Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:28 2009

## Asterisk developer's documentation

# chan_iax2.c File Reference

Implementation of Inter-Asterisk eXchange Version 2. More...

`#include <stdlib.h>`
`#include <stdio.h>`
`#include <sys/types.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 <string.h>`
`#include <strings.h>`
`#include <errno.h>`
`#include <unistd.h>`
`#include <netdb.h>`
`#include <fcntl.h>`
`#include <sys/stat.h>`
`#include <regex.h>`
`#include "asterisk.h"`
`#include "asterisk/lock.h"`
`#include "asterisk/frame.h"`
`#include "asterisk/channel.h"`
`#include "asterisk/logger.h"`
`#include "asterisk/module.h"`
`#include "asterisk/pbx.h"`
`#include "asterisk/sched.h"`
`#include "asterisk/io.h"`
`#include "asterisk/config.h"`
`#include "asterisk/options.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/aes.h"`
`#include "asterisk/dnsmgr.h"`
`#include "asterisk/devicestate.h"`
`#include "asterisk/netsock.h"`
`#include "asterisk/astobj2.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 | addr_range
struct | ast_firmware_list
struct | ast_iax2_queue
struct | ast_peer_list
| The peer list: Peers and Friends ---. More...
struct | ast_user_list
| The user list: Users and friends ---. More...
struct | callno_entry
struct | chan_iax2_pvt
struct | create_addr_info
struct | dpreq_data
struct | iax2_context
struct | iax2_dpcache
struct | iax2_peer
struct | iax2_registry
struct | iax2_trunk_peer
struct | iax2_user
struct | iax_dual
struct | iax_firmware
struct | iax_rr
struct | parsed_dial_string
struct | peercnt

## Defines

#define | CACHE_FLAG_CANEXIST (1 << 2)
#define | CACHE_FLAG_EXISTS (1 << 0)
#define | CACHE_FLAG_MATCHMORE (1 << 7)
#define | CACHE_FLAG_NONEXISTENT (1 << 1)
#define | CACHE_FLAG_PENDING (1 << 3)
#define | CACHE_FLAG_TIMEOUT (1 << 4)
#define | CACHE_FLAG_TRANSMITTED (1 << 5)
#define | CACHE_FLAG_UNKNOWN (1 << 6)
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
#define | CALLTOKEN_HASH_FORMAT "%s%d%u%d"
#define | CALLTOKEN_IE_FORMAT "%u?%s"
#define | DEBUG_SUPPORT
#define | DEFAULT_DROP 3
#define | DEFAULT_FREQ_NOTOK 10 * 1000
#define | DEFAULT_FREQ_OK 60 * 1000
#define | DEFAULT_MAXMS 2000
#define | DEFAULT_RETRY_TIME 1000
#define | DEFAULT_TRUNKDATA 640 * 10
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
#define | FORMAT "%-20.20s %-10.10s %-20.20s %8d %s\n"
#define | FORMAT "%-15.15s %-15d %-15d\n"
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
#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\n"
#define | FORMAT2 "%-20.20s %-10.10s %-20.20s %8.8s %s\n"
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
#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 | FREE free
#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_CAPABILITY_FULLBANDWIDTH 0xFFFF
#define | IAX_CAPABILITY_LOWBANDWIDTH
#define | IAX_CAPABILITY_LOWFREE
#define | IAX_CAPABILITY_MEDBANDWIDTH
#define | IPTOS_MINCOST 0x02
#define | MAX_JITTER_BUFFER 50
#define | MAX_PEER_BUCKETS 563
#define | MAX_RETRY_TIME 10000
#define | MAX_TIMESTAMP_SKEW 160
#define | MAX_TRUNKDATA 640 * 200
#define | MEMORY_SIZE 100
#define | MIN_JITTER_BUFFER 10
#define | MIN_RETRY_TIME 100
#define | MIN_REUSE_TIME 60
#define | NEWJB
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
#define | TRUNK_CALL_START 0x4000
#define | TS_GAP_FOR_JB_RESYNC 5000

## Enumerations

enum | { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 }
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) }

enum

{
IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3),
IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7),
IAX_MESSAGEDETAIL = (1 << 8), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11),
IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15),
IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19),
IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_MAXAUTHREQ = (1 << 23),
IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26)
}

enum | calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 }
| Call token validation settings. More...
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 }

## Functions

static int | __do_deliver (void *data)
static int | __iax2_show_peers (int manager, int fd, int argc, char *argv[])
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 int | __unload_module (void)
static int | add_calltoken_ignore (const char *addr)
static void | add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int | addr_range_cmp_cb (void *obj, void *arg, int flags)
static int | addr_range_delme_cb (void *obj, void *arg, int flags)
static int | addr_range_hash_cb (const void *obj, const int flags)
static int | addr_range_match_address_cb (void *obj, void *arg, int flags)
static int | apply_context (struct iax2_context *con, char *context)
static int | ast_cli_netstats (int fd, int limit_fmt)
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability)
| AST_MUTEX_DEFINE_STATIC (dpcache_lock)
| AST_MUTEX_DEFINE_STATIC (reg_lock)
| AST_MUTEX_DEFINE_STATIC (tpeerlock)
| AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static int | attempt_transmit (void *data)
static int | auth_fail (int callno, int failcode)
static int | auth_reject (void *nothing)
static int | authenticate (char *challenge, char *secret, char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey)
static int | authenticate_request (struct chan_iax2_pvt *p)
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int | auto_congest (void *nothing)
static int | auto_hangup (void *nothing)
static void | build_callno_limits (struct ast_variable *v)
static struct iax2_context * | build_context (char *context)
static void | build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, int temponly)
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, int temponly)
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 *tv)
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)
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static char * | complete_iax2_show_peer (char *line, char *word, int pos, int state)
static int | complete_transfer (int callno, struct iax_ies *ies)
static unsigned char | compress_subclass (int subclass)
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int | create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
static int | create_callno_pools (void)
static int | decode_frame (aes_decrypt_ctx *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 | delete_users (void)
char * | description (void)
| Provides a description of the module.
static void | destroy_firmware (struct iax_firmware *cur)
static void | destroy_peer (struct iax2_peer *peer)
static void | destroy_user (struct iax2_user *user)
static void | dp_lookup (int callno, char *context, char *callednum, char *callerid, int skiplock)
static void * | dp_lookup_thread (void *data)
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int | expire_registry (void *data)
static struct iax2_dpcache * | find_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 lockpeer, int sockfd, int check_dcallno)
static struct iax2_peer * | find_peer (const char *name, int realtime)
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd)
static struct iax2_user * | find_user (const char *name, int realtime)
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts)
static void | free_context (struct iax2_context *con)
static char * | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
static int | get_auth_methods (char *value)
static int | get_encrypt_methods (const char *s)
static int | get_from_jb (void *p)
static struct callno_entry * | get_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 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 | iax2_allow_new (int frametype, int subclass, int inbound)
static int | iax2_answer (struct ast_channel *c)
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)
static unsigned int | iax2_datetime (char *tz)
static void | iax2_destroy (int callno)
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static void | iax2_destroy_nolock (int callno)
static int | iax2_devicestate (void *data)
static int | iax2_digit (struct ast_channel *c, char digit)
static int | iax2_do_debug (int fd, int argc, char *argv[])
static int | iax2_do_jb_debug (int fd, int argc, char *argv[])
static int | iax2_do_register (struct iax2_registry *reg)
static int | iax2_do_register_s (void *data)
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[])
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno)
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void | iax2_frame_free (struct iax_frame *fr)
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len, int lockpeer)
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)
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int | iax2_no_debug (int fd, int argc, char *argv[])
static int | iax2_no_jb_debug (int fd, int argc, char *argv[])
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[])
static int | iax2_poke_noanswer (void *data)
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int | iax2_poke_peer_s (void *data)
static int | iax2_predestroy (int callno)
static int | iax2_predestroy_nolock (int callno)
static int | iax2_prov_app (struct ast_channel *chan, void *data)
static int | iax2_prov_cmd (int fd, int argc, char *argv[])
static char * | iax2_prov_complete_template_3rd (char *line, char *word, int pos, int state)
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
static int | iax2_prune_realtime (int fd, int argc, char *argv[])
static int | iax2_queue_frame (int callno, struct ast_frame *f)
static struct ast_frame * | iax2_read (struct ast_channel *c)
static int | iax2_register (char *value, int lineno)
static int | iax2_reload (int fd, int argc, char *argv[])
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause)
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_set_jitter (int fd, int argc, char *argv[])
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int | iax2_show_cache (int fd, int argc, char *argv[])
static int | iax2_show_callnumber_usage (int fd, int argc, char *argv[])
static int | iax2_show_channels (int fd, int argc, char *argv[])
static int | iax2_show_firmware (int fd, int argc, char *argv[])
static int | iax2_show_netstats (int fd, int argc, char *argv[])
static int | iax2_show_peer (int fd, int argc, char *argv[])
static int | iax2_show_peers (int fd, int argc, char *argv[])
static int | iax2_show_registry (int fd, int argc, char *argv[])
static int | iax2_show_stats (int fd, int argc, char *argv[])
static int | iax2_show_users (int fd, int argc, char *argv[])
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1)
static int | iax2_test_losspct (int fd, int argc, char *argv[])
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 int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2)
static void * | iax_park_thread (void *stuff)
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr)
static void | jb_debug_output (const char *fmt,...)
static void | jb_error_output (const char *fmt,...)
static void | jb_warning_output (const char *fmt,...)
char * | key (void)
| Returns the ASTERISK_GPL_KEY.
int | load_module (void)
| Initialize the module.
static int | load_objects (void)
static void | lock_both (unsigned short callno0, unsigned short callno1)
static int | make_trunk (unsigned short callno, int locked)
static int | manager_iax2_show_netstats (struct mansession *s, struct message *m)
static int | manager_iax2_show_peers (struct mansession *s, struct message *m)
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc)
static void * | network_thread (void *ignore)
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, int lockpeer, 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_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen)
| peer_status: Report Peer status in character string
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 sockaddr_in *sin)
static void | peercnt_remove (struct peercnt *peercnt)
static int | peercnt_remove_by_addr (struct sockaddr_in *sin)
static int | peercnt_remove_cb (void *obj)
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 | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin)
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime)
static struct iax2_user * | realtime_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 (char *name, int callno)
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * | regstate2str (int regstate)
int | reload (void)
| Reload stuff.
static int | reload_config (void)
static void | reload_firmware (void)
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt)
static int | replace_callno (void *obj)
static void | requirecalltoken_mark_auto (const char *name, int subclass)
static void | resend_with_token (int callno, struct iax_frame *f, char *newtoken)
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 | 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 (void *data)
static int | send_packet (struct iax_frame *f)
static int | send_ping (void *data)
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int | set_config (const char *config_file, int reload)
static void | set_peercnt_limit (struct peercnt *peercnt)
static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags)
static void | set_timing (void)
static int | socket_read (int *id, int fd, short events, void *cbdata)
static void | spawn_dp_lookup (int callno, char *context, char *callednum, char *callerid)
static int | start_network_thread (void)
static int | stop_stuff (int callno)
static void | store_by_peercallno (struct chan_iax2_pvt *pvt)
static int | timing_read (int *id, int fd, short events, void *cbdata)
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 int | uncompress_subclass (unsigned char csub)
int | unload_module (void)
| Cleanup all module structures, sockets, etc.
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 (char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
int | usecount (void)
| Provides a usecount.
static void | vnak_retransmit (int callno, int last)

## Variables

static char | accountcode [AST_MAX_ACCOUNT_CODE]
static int | amaflags = 0
static int | authdebug = 1
static int | autokill = 0
static struct ao2_container * | callno_limits
static struct ao2_container * | callno_pool
static const unsigned int | CALLNO_POOL_BUCKETS = 2699
static struct ao2_container * | callno_pool_trunk
static struct ao2_container * | calltoken_ignores
static const char | channeltype [] = "IAX2"
static char | context [80] = "default"
static char | debug_jb_usage []
static char | debug_trunk_usage []
static char | debug_usage []
static uint16_t | DEFAULT_MAXCALLNO_LIMIT = 2048
static uint16_t | DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192
static int | defaultsockfd = -1
static int | delayreject = 0
static const char | desc [] = "Inter Asterisk eXchange (Ver 2)"
static struct iax2_dpcache * | dpcache
static uint16_t | global_maxcallno
static uint16_t | global_maxcallno_nonval
static int | global_rtautoclear = 120
static struct ast_flags | globalflags = { 0 }
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static struct ast_cli_entry | iax2_cli []
static int | iax2_dropcount = DEFAULT_DROP
static int | iax2_encryption = 0
enum { ... } | iax2_flags
int(* | iax2_regfunk )(char *username, int onoff) = NULL
static char | iax2_reload_usage []
enum { ... } | iax2_state
static struct ast_switch | iax2_switch
static struct ast_channel_tech | iax2_tech
static char | iax2_test_losspct_usage []
static struct ao2_container * | iax_peercallno_pvts
| Another container of iax2_pvt structures.
static int | iaxcompat = 0
static int | iaxdebug = 0
static int | iaxdefaultdpcache = 10 * 60
static int | iaxdefaulttimeout = 5
struct ast_custom_function | iaxpeer_function
static struct ast_iax2_queue | iaxq
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS]
static ast_mutex_t | iaxsl [IAX_MAX_CALLS]
static int | iaxtrunkdebug = 0
static struct io_context * | io
static char | jitter_usage []
static int | jittershrinkrate = 2
static int | lagrq_time = 10
static char | language [MAX_LANGUAGE] = ""
static int | lastauthmethod = 0
static const time_t | MAX_CALLTOKEN_DELAY = 10
static int | max_jitter_buffer = MAX_JITTER_BUFFER
static int | max_reg_expire
static int | max_retries = 4
static int | maxauthreq = 0
static int | maxjitterbuffer = 1000
static int | maxjitterinterps = 10
static int | maxnontrunkcall = 1
static int | maxtrunkcall = TRUNK_CALL_START
static int | min_jitter_buffer = MIN_JITTER_BUFFER
static int | min_reg_expire
static struct ast_netsock_list * | netsock
static pthread_t | netthreadid = AST_PTHREADT_NULL
static char | no_debug_jb_usage []
static char | no_debug_trunk_usage []
static char | no_debug_usage []
static struct ast_netsock_list * | outsock
static char * | papp = "IAX2Provision"
static char * | pdescrip
static struct ao2_container * | peercnts
static struct ast_peer_list | peerl
static int | ping_time = 20
static struct ast_codec_pref | prefs
static char | prune_realtime_usage []
static char * | psyn = "Provision a calling IAXy with a given template"
static int | randomcalltokendata
static char | regcontext [AST_MAX_CONTEXT] = ""
static struct iax2_registry * | registrations
static int | resyncthreshold = 1000
static struct sched_context * | sched
static char | show_cache_usage []
static char | show_callnumber_usage []
static char | show_channels_usage []
static char | show_firmware_usage []
static char | show_netstats_usage []
static char | show_peer_usage []
static char | show_peers_usage []
static char | show_prov_usage []
static char | show_reg_usage []
static char | show_stats_usage []
static char | show_users_usage []
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)"
static int | test_losspct = 0
static int | timingfd = -1
static int | tos = 0
static uint16_t | total_nonval_callno_used = 0
static struct iax2_trunk_peer * | tpeers
static int | trunkfreq = 20
static int | usecnt
static struct ast_user_list | userl
static struct ast_firmware_list | waresl

## Detailed Description

Implementation of Inter-Asterisk eXchange Version 2.

See also
  - IAX2 configuration

Definition in file chan_iax2.c.

## Define Documentation

#define CACHE_FLAG_CANEXIST (1 << 2)

Extension can exist

Definition at line 734 of file chan_iax2.c.

Referenced by complete_dpreply(), iax2_canmatch(), and iax2_show_cache().

#define CACHE_FLAG_EXISTS (1 << 0)

Extension exists

Definition at line 730 of file chan_iax2.c.

Referenced by complete_dpreply(), iax2_exec(), iax2_exists(), and iax2_show_cache().

#define CACHE_FLAG_MATCHMORE (1 << 7)

Matchmore

Definition at line 744 of file chan_iax2.c.

Referenced by complete_dpreply(), iax2_matchmore(), and iax2_show_cache().

#define CACHE_FLAG_NONEXISTENT (1 << 1)

Extension is nonexistent

Definition at line 732 of file chan_iax2.c.

Referenced by complete_dpreply(), and iax2_show_cache().

#define CACHE_FLAG_PENDING (1 << 3)

Waiting to hear back response

Definition at line 736 of file chan_iax2.c.

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

#define CACHE_FLAG_TIMEOUT (1 << 4)

Timed out

Definition at line 738 of file chan_iax2.c.

Referenced by find_cache(), and iax2_show_cache().

#define CACHE_FLAG_TRANSMITTED (1 << 5)

Request transmitted

Definition at line 740 of file chan_iax2.c.

Referenced by iax2_dprequest(), iax2_show_cache(), and socket_read().

#define CACHE_FLAG_UNKNOWN (1 << 6)

Timeout

Definition at line 742 of file chan_iax2.c.

Referenced by complete_dpreply(), and iax2_show_cache().

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

Definition at line 124 of file chan_iax2.c.

Referenced by ast_iax2_new(), and iax2_call().

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

Definition at line 133 of file chan_iax2.c.

#define DEFAULT_DROP 3

Definition at line 128 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK 10 * 1000

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

Referenced by build_peer(), and handle_response_peerpoke().

#define DEFAULT_MAXMS 2000

Definition at line 205 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME 1000

Definition at line 126 of file chan_iax2.c.

Referenced by complete_transfer(), and find_callno().

#define DEFAULT_TRUNKDATA 640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 446 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

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

#define FORMAT "%-15.15s %-15d %-15d\n"

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

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

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

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

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

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

Referenced by iax2_show_channels().

#define FREE free

Definition at line 773 of file chan_iax2.c.

Referenced by __build_step(), ast_park_call(), do_parking_thread(), fillin_process(), handle_macro(), load_config(), pbx_load_module(), and register_peer_exten().

#define GAMMA (0.01)

Definition at line 138 of file chan_iax2.c.

Referenced by schedule_delivery().

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

Definition at line 373 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF

Definition at line 190 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

    (IAX_CAPABILITY_MEDBANDWIDTH &   \
                         ~AST_FORMAT_G726 &   \
                         ~AST_FORMAT_ADPCM)

Definition at line 197 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

    (IAX_CAPABILITY_LOWBANDWIDTH &      \
                          ~AST_FORMAT_G723_1)

Definition at line 201 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Value:

    (IAX_CAPABILITY_FULLBANDWIDTH &  \
                         ~AST_FORMAT_SLINEAR &   \
                         ~AST_FORMAT_ULAW &   \
                         ~AST_FORMAT_ALAW)

Definition at line 192 of file chan_iax2.c.

Referenced by set_config().

#define IPTOS_MINCOST 0x02

Definition at line 107 of file chan_iax2.c.

#define MAX_JITTER_BUFFER 50

Definition at line 443 of file chan_iax2.c.

#define MAX_PEER_BUCKETS 563

Definition at line 661 of file chan_iax2.c.

Referenced by load_objects().

#define MAX_RETRY_TIME 10000

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

#define MAX_TRUNKDATA 640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 447 of file chan_iax2.c.

Referenced by iax2_trunk_queue(), and timing_read().

#define MEMORY_SIZE 100

Definition at line 127 of file chan_iax2.c.

Referenced by schedule_delivery().

#define MIN_JITTER_BUFFER 10

Definition at line 444 of file chan_iax2.c.

#define MIN_RETRY_TIME 100

Definition at line 440 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME 60

Definition at line 135 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

#define NEWJB

Definition at line 100 of file chan_iax2.c.

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

Definition at line 123 of file chan_iax2.c.

Referenced by auto_congest(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), and iax2_write().

#define TRUNK_CALL_START 0x4000

Definition at line 131 of file chan_iax2.c.

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

#define TS_GAP_FOR_JB_RESYNC 5000

Definition at line 452 of file chan_iax2.c.

Referenced by schedule_delivery().

## Enumeration Type Documentation

anonymous enum

Enumerator:

  NEW_PREVENT |
  NEW_ALLOW |
  NEW_FORCE |
  NEW_ALLOW_CALLTOKEN_VALIDATED |

Definition at line 1284 of file chan_iax2.c.

    01284      {
    01285    /* do not allow a new call number, only search ones in use for match */
    01286    NEW_PREVENT = 0,
    01287    /* search for match first, then allow a new one to be allocated */
    01288    NEW_ALLOW = 1,
    01289    /* do not search for match, force a new call number */
    01290    NEW_FORCE = 2,
    01291    /* do not search for match, force a new call number.  Signifies call number
    01292     * has been calltoken validated */
    01293    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
    01294 };

anonymous enum

Enumerator:

  IAX_STATE_STARTED |
  IAX_STATE_AUTHENTICATED |
  IAX_STATE_TBD |

Definition at line 237 of file chan_iax2.c.

    00237      {
    00238    IAX_STATE_STARTED =     (1 << 0),
    00239    IAX_STATE_AUTHENTICATED =  (1 << 1),
    00240    IAX_STATE_TBD =      (1 << 2)
    00241 } iax2_state;

anonymous enum

Enumerator:

  IAX_HASCALLERID | CallerID has been specified
  IAX_DELME | Needs to be deleted
  IAX_TEMPONLY | Temporary (realtime)
  IAX_TRUNK | Treat as a trunk
  IAX_NOTRANSFER | Don't native bridge
  IAX_USEJITTERBUF | Use jitter buffer
  IAX_DYNAMIC | dynamic peer
  IAX_SENDANI | Send ANI along with CallerID
  IAX_MESSAGEDETAIL | Show exact numbers
  IAX_ALREADYGONE | Already disconnected
  IAX_PROVISION | This is a provisioning request
  IAX_QUELCH | Whether or not we quelch audio
  IAX_ENCRYPTED | Whether we should assume encrypted tx/rx
  IAX_KEYPOPULATED | Whether we have a key populated
  IAX_CODEC_USER_FIRST | are we willing to let the other guy choose the codec?
  IAX_CODEC_NOPREFS | Force old behaviour by turning off prefs
  IAX_CODEC_NOCAP | only consider requested format and ignore capabilities
  IAX_RTCACHEFRIENDS | let realtime stay till your reload
  IAX_RTUPDATE | Send a realtime update
  IAX_RTAUTOCLEAR | erase me on expire
  IAX_FORCEJITTERBUF | Force jitterbuffer, even when bridged to a channel that can take jitter
  IAX_RTIGNOREREGEXPIRE | When using realtime, ignore registration expiration
  IAX_TRUNKTIMESTAMPS | Send trunk timestamps
  IAX_MAXAUTHREQ | Maximum outstanding AUTHREQ restriction is in place
  IAX_DELAYPBXSTART | 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
  IAX_ALLOWFWDOWNLOAD | Allow the FWDOWNL command?

Definition at line 248 of file chan_iax2.c.

    00248      {
    00249    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
    00250    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
    00251    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
    00252    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
    00253    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
    00254    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
    00255    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
    00256    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
    00257    IAX_MESSAGEDETAIL =  (1 << 8),   /*!< Show exact numbers */
    00258    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
    00259    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
    00260    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
    00261    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
    00262    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
    00263    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
    00264    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
    00265    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
    00266    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
    00267    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
    00268    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */
    00269    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
    00270    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
    00271    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
    00272    IAX_MAXAUTHREQ =        (1 << 23),      /*!< Maximum outstanding AUTHREQ restriction is in place */
    00273    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
    00274                        response, so that we've achieved a three-way handshake with
    00275                        them before sending voice or anything else*/
    00276    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
    00277 } iax2_flags;

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

    00287                          {
    00288    /*! \brief Default calltoken required unless the ip is in the ignorelist */
    00289    CALLTOKEN_DEFAULT = 0,
    00290    /*! \brief Require call token validation. */
    00291    CALLTOKEN_YES = 1,
    00292    /*! \brief Require call token validation after a successful registration
    00293     *         using call token validation occurs. */
    00294    CALLTOKEN_AUTO = 2,
    00295    /*! \brief Do not require call token validation. */
    00296    CALLTOKEN_NO = 3,
    00297 };

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

    00404                    {
    00405    REG_STATE_UNREGISTERED = 0,
    00406    REG_STATE_REGSENT,
    00407    REG_STATE_AUTHSENT,
    00408    REG_STATE_REGISTERED,
    00409    REG_STATE_REJECTED,
    00410    REG_STATE_TIMEOUT,
    00411    REG_STATE_NOAUTH
    00412 };

enum iax_transfer_state

Enumerator:

  TRANSFER_NONE |
  TRANSFER_BEGIN |
  TRANSFER_READY |
  TRANSFER_RELEASED |
  TRANSFER_PASSTHROUGH |

Definition at line 414 of file chan_iax2.c.

    00414                         {
    00415    TRANSFER_NONE = 0,
    00416    TRANSFER_BEGIN,
    00417    TRANSFER_READY,
    00418    TRANSFER_RELEASED,
    00419    TRANSFER_PASSTHROUGH
    00420 };

## Function Documentation

static int __do_deliver | ( | void * | data | ) | `[static]`

Definition at line 2371 of file chan_iax2.c.

References iax_frame::af, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, and iax_frame::retrans.

Referenced by get_from_jb(), and schedule_delivery().

    02372 {
    02373    /* Just deliver the packet by using queueing.  This is called by
    02374      the IAX thread with the iaxsl lock held. */
    02375    struct iax_frame *fr = data;
    02376    fr->retrans = -1;
    02377    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
    02378       iax2_queue_frame(fr->callno, &fr->af);
    02379    /* Free our iax frame */
    02380    iax2_frame_free(fr);
    02381    /* And don't run again */
    02382    return 0;
    02383 }

static int __iax2_show_peers | ( | int | manager,
|  | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5407 of file chan_iax2.c.

References iax2_peer::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, ast_peer_list::lock, iax2_peer::mask, iax2_peer::name, name, iax2_peer::next, peer_status(), peerl, ast_peer_list::peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax2_peer::username.

Referenced by iax2_show_peers(), and manager_iax2_show_peers().

    05408 {
    05409    regex_t regexbuf;
    05410    int havepattern = 0;
    05411    int total_peers = 0;
    05412    int online_peers = 0;
    05413    int offline_peers = 0;
    05414    int unmonitored_peers = 0;
    05415
    05416 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
    05417 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
    05418
    05419    struct iax2_peer *peer;
    05420    char name[256];
    05421    char iabuf[INET_ADDRSTRLEN];
    05422    int registeredonly=0;
    05423    char *term = manager ? "\r\n" : "\n";
    05424
    05425    switch (argc) {
    05426    case 6:
    05427       if (!strcasecmp(argv[3], "registered"))
    05428          registeredonly = 1;
    05429       else
    05430          return RESULT_SHOWUSAGE;
    05431       if (!strcasecmp(argv[4], "like")) {
    05432          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
    05433             return RESULT_SHOWUSAGE;
    05434          havepattern = 1;
    05435       } else
    05436          return RESULT_SHOWUSAGE;
    05437       break;
    05438    case 5:
    05439       if (!strcasecmp(argv[3], "like")) {
    05440          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
    05441             return RESULT_SHOWUSAGE;
    05442          havepattern = 1;
    05443       } else
    05444          return RESULT_SHOWUSAGE;
    05445       break;
    05446    case 4:
    05447       if (!strcasecmp(argv[3], "registered"))
    05448          registeredonly = 1;
    05449       else
    05450          return RESULT_SHOWUSAGE;
    05451       break;
    05452    case 3:
    05453       break;
    05454    default:
    05455       return RESULT_SHOWUSAGE;
    05456    }
    05457
    05458    ast_mutex_lock(&peerl.lock);
    05459    ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
    05460    for (peer = peerl.peers;peer;peer = peer->next) {
    05461       char nm[20];
    05462       char status[20];
    05463       char srch[2000];
    05464       int retstatus;
    05465
    05466       if (registeredonly && !peer->addr.sin_addr.s_addr)
    05467          continue;
    05468       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
    05469          continue;
    05470
    05471       if (!ast_strlen_zero(peer->username))
    05472          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
    05473       else
    05474          ast_copy_string(name, peer->name, sizeof(name));
    05475
    05476       retstatus = peer_status(peer, status, sizeof(status));
    05477       if (retstatus > 0)
    05478          online_peers++;
    05479       else if (!retstatus)
    05480          offline_peers++;
    05481       else
    05482          unmonitored_peers++;
    05483
    05484       ast_copy_string(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm));
    05485
    05486       snprintf(srch, sizeof(srch), FORMAT, name,
    05487                peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
    05488                ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
    05489                nm,
    05490                ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
    05491                peer->encmethods ? "(E)" : "   ", status, term);
    05492
    05493       ast_cli(fd, FORMAT, name,
    05494                peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
    05495                ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
    05496                nm,
    05497                ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
    05498                peer->encmethods ? "(E)" : "   ", status, term);
    05499       total_peers++;
    05500    }
    05501    ast_mutex_unlock(&peerl.lock);
    05502
    05503    ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
    05504
    05505    if (havepattern)
    05506       regfree(&regexbuf);
    05507
    05508    return RESULT_SUCCESS;
    05509 #undef FORMAT
    05510 #undef FORMAT2
    05511 }

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

References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::mallocd, ast_frame::offset, ast_frame::samples, ast_frame::src, and ast_frame::subclass.

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

    05875 {
    05876    struct ast_frame f;
    05877    f.frametype = type;
    05878    f.subclass = command;
    05879    f.datalen = datalen;
    05880    f.samples = 0;
    05881    f.mallocd = 0;
    05882    f.offset = 0;
    05883    f.src = (char *)__FUNCTION__;
    05884    f.data = (char *)data;
    05885    return iax2_send(i, &f, ts, seqno, now, transfer, final);
    05886 }

static int __unload_module | ( | void |  | ) | `[static]`

Definition at line 11154 of file chan_iax2.c.

References ao2_ref(), ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_mutex_destroy(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_destroy(), IAX_MAX_CALLS, iax_provision_unload(), iaxq, ast_firmware_list::lock, ast_peer_list::lock, ast_user_list::lock, ast_iax2_queue::lock, peerl, sched_context_destroy(), userl, and waresl.

Referenced by load_module(), and unload_module().

    11155 {
    11156    int x;
    11157    /* Cancel the network thread, close the net socket */
    11158    if (netthreadid != AST_PTHREADT_NULL) {
    11159       pthread_cancel(netthreadid);
    11160       pthread_join(netthreadid, NULL);
    11161    }
    11162    ast_netsock_release(netsock);
    11163    ast_netsock_release(outsock);
    11164    for (x=0;x<IAX_MAX_CALLS;x++)
    11165       if (iaxs[x])
    11166          iax2_destroy(x);
    11167    ast_manager_unregister( "IAXpeers" );
    11168    ast_manager_unregister( "IAXnetstats" );
    11169    ast_unregister_application(papp);
    11170    ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
    11171    ast_unregister_switch(&iax2_switch);
    11172    ast_channel_unregister(&iax2_tech);
    11173    delete_users();
    11174    iax_provision_unload();
    11175    sched_context_destroy(sched);
    11176
    11177    ast_mutex_destroy(&iaxq.lock);
    11178    ast_mutex_destroy(&userl.lock);
    11179    ast_mutex_destroy(&peerl.lock);
    11180    ast_mutex_destroy(&waresl.lock);
    11181
    11182    for (x = 0; x < IAX_MAX_CALLS; x++)
    11183       ast_mutex_destroy(&iaxsl[x]);
    11184
    11185    ao2_ref(iax_peercallno_pvts, -1);
    11186    ao2_ref(peercnts, -1);
    11187    ao2_ref(callno_limits, -1);
    11188    ao2_ref(calltoken_ignores, -1);
    11189    ao2_ref(callno_pool, -1);
    11190    ao2_ref(callno_pool_trunk, -1);
    11191
    11192    return 0;
    11193 }

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

Definition at line 1740 of file chan_iax2.c.

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

Referenced by set_config().

    01741 {
    01742    struct addr_range tmp;
    01743    struct addr_range *addr_range = NULL;
    01744    struct ast_ha *ha = NULL;
    01745
    01746    if (ast_strlen_zero(addr)) {
    01747       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
    01748       return -1;
    01749    }
    01750
    01751    ha = ast_append_ha("permit", addr, NULL);
    01752
    01753    /* check for valid config information */
    01754    if (!ha) {
    01755       ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr);
    01756       return -1;
    01757    }
    01758
    01759    ast_copy_ha(ha, &tmp.ha);
    01760    /* find or create the addr_range */
    01761    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
    01762       ao2_lock(addr_range);
    01763       addr_range->delme = 0;
    01764       ao2_unlock(addr_range);
    01765    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
    01766       /* copy over config data into addr_range object */
    01767       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
    01768       ao2_link(calltoken_ignores, addr_range);
    01769    } else {
    01770       ast_free_ha(ha);
    01771       return -1;
    01772    }
    01773
    01774    ast_free_ha(ha);
    01775    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
    01776
    01777    return 0;
    01778 }

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

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

    03838 {
    03839    /* first make sure their are two empty bytes left in ied->buf */
    03840    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
    03841       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
    03842       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
    03843       pvt->calltoken_ie_len = 2;
    03844    }
    03845 }

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

Definition at line 1399 of file chan_iax2.c.

References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.

Referenced by load_objects().

    01400 {
    01401    struct addr_range *lim1 = obj, *lim2 = arg;
    01402    return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
    01403       (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
    01404       CMP_MATCH | CMP_STOP : 0;
    01405 }

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

Definition at line 1386 of file chan_iax2.c.

References addr_range::delme.

    01387 {
    01388    struct addr_range *lim = obj;
    01389    lim->delme = 1;
    01390    return 0;
    01391 }

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

Definition at line 1393 of file chan_iax2.c.

References addr_range::ha, and ast_ha::netaddr.

Referenced by load_objects().

    01394 {
    01395    const struct addr_range *lim = obj;
    01396    return abs((int) lim->ha.netaddr.s_addr);
    01397 }

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

Definition at line 1419 of file chan_iax2.c.

References addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.

Referenced by calltoken_required(), and set_peercnt_limit().

    01420 {
    01421    struct addr_range *addr_range = obj;
    01422    struct sockaddr_in *sin = arg;
    01423
    01424    if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
    01425       return CMP_MATCH | CMP_STOP;
    01426    }
    01427    return 0;
    01428 }

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

Definition at line 5926 of file chan_iax2.c.

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

Referenced by check_access().

    05927 {
    05928    while(con) {
    05929       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
    05930          return -1;
    05931       con = con->next;
    05932    }
    05933    return 0;
    05934 }

static int ast_cli_netstats | ( | int | fd,
|  | int | limit_fmt |
| ) |  |  | `[static]`

Definition at line 5693 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, jb_info::current, iax_rr::delay, iax_rr::dropped, fmt, chan_iax2_pvt::frames_dropped, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, IAX_MAX_CALLS, IAX_USEJITTERBUF, jb_getinfo(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.

Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().

    05694 {
    05695    int x;
    05696    int numchans = 0;
    05697    for (x=0;x<IAX_MAX_CALLS;x++) {
    05698       ast_mutex_lock(&iaxsl[x]);
    05699       if (iaxs[x]) {
    05700 #ifdef BRIDGE_OPTIMIZATION
    05701          if (iaxs[x]->bridgecallno) {
    05702             if (limit_fmt)
    05703                ast_cli(fd, "%-25.25s <NATIVE BRIDGED>",
    05704                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)");
    05705             else
    05706                ast_cli(fd, "%s <NATIVE BRIDGED>",
    05707                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)");
    05708                         } else
    05709 #endif
    05710          {
    05711             int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
    05712             char *fmt;
    05713 #ifdef NEWJB
    05714             jb_info jbinfo;
    05715
    05716             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
    05717                jb_getinfo(iaxs[x]->jb, &jbinfo);
    05718                localjitter = jbinfo.jitter;
    05719                localdelay = jbinfo.current - jbinfo.min;
    05720                locallost = jbinfo.frames_lost;
    05721                locallosspct = jbinfo.losspct/1000;
    05722                localdropped = jbinfo.frames_dropped;
    05723                localooo = jbinfo.frames_ooo;
    05724             } else {
    05725                localjitter = -1;
    05726                localdelay = 0;
    05727                locallost = -1;
    05728                locallosspct = -1;
    05729                localdropped = 0;
    05730                localooo = -1;
    05731             }
    05732 #else
    05733             localjitter = iaxs[x]->jitter;
    05734             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF))
    05735             {
    05736                localdelay = jitterbufsize(iaxs[x]);
    05737                localdropped = iaxs[x]->frames_dropped;
    05738             } else {
    05739                localdelay = localdropped = 0;
    05740             }
    05741             locallost = locallosspct = localooo = -1;
    05742 #endif
    05743             if (limit_fmt)
    05744                fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
    05745             else
    05746                fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
    05747             ast_cli(fd, fmt,
    05748                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
    05749                   iaxs[x]->pingtime,
    05750                   localjitter,
    05751                   localdelay,
    05752                   locallost,
    05753                   locallosspct,
    05754                   localdropped,
    05755                   localooo,
    05756                   iaxs[x]->frames_received/1000,
    05757                   iaxs[x]->remote_rr.jitter,
    05758                   iaxs[x]->remote_rr.delay,
    05759                   iaxs[x]->remote_rr.losscnt,
    05760                   iaxs[x]->remote_rr.losspct,
    05761                   iaxs[x]->remote_rr.dropped,
    05762                   iaxs[x]->remote_rr.ooo,
    05763                   iaxs[x]->remote_rr.packets/1000
    05764             );
    05765          }
    05766          numchans++;
    05767       }
    05768       ast_mutex_unlock(&iaxsl[x]);
    05769    }
    05770    return numchans;
    05771 }

static struct ast_channel* ast_iax2_new | ( | int | callno,
|  | int | state,
|  | int | capability |
| ) |  |  | `[static, read]`

Definition at line 4616 of file chan_iax2.c.

References ast_channel::accountcode, chan_iax2_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), 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, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, chan_iax2_pvt::cid_name, ast_callerid::cid_num, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, chan_iax2_pvt::context, ast_channel::context, chan_iax2_pvt::dnid, chan_iax2_pvt::exten, ast_channel::exten, chan_iax2_pvt::host, ast_channel::language, chan_iax2_pvt::language, LOG_WARNING, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::readformat, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt_lock, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_read().

    04617 {
    04618    struct ast_channel *tmp;
    04619    struct chan_iax2_pvt *i;
    04620    struct ast_variable *v = NULL;
    04621
    04622    /* Don't hold call lock */
    04623    ast_mutex_unlock(&iaxsl[callno]);
    04624    tmp = ast_channel_alloc(1);
    04625    ast_mutex_lock(&iaxsl[callno]);
    04626    i = iaxs[callno];
    04627    if (i && tmp) {
    04628       tmp->tech = &iax2_tech;
    04629       snprintf(tmp->name, sizeof(tmp->name), "IAX2/%s-%d", i->host, i->callno);
    04630       tmp->type = channeltype;
    04631       /* We can support any format by default, until we get restricted */
    04632       tmp->nativeformats = capability;
    04633       tmp->readformat = ast_best_codec(capability);
    04634       tmp->writeformat = ast_best_codec(capability);
    04635       tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
    04636
    04637       if (!ast_strlen_zero(i->cid_num))
    04638          tmp->cid.cid_num = strdup(i->cid_num);
    04639       if (!ast_strlen_zero(i->cid_name))
    04640          tmp->cid.cid_name = strdup(i->cid_name);
    04641       if (!ast_strlen_zero(i->ani))
    04642          tmp->cid.cid_ani = strdup(i->ani);
    04643       tmp->cid.cid_pres = i->calling_pres;
    04644       tmp->cid.cid_ton = i->calling_ton;
    04645       tmp->cid.cid_tns = i->calling_tns;
    04646
    04647       if (!ast_strlen_zero(i->language))
    04648          ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
    04649       if (!ast_strlen_zero(i->dnid))
    04650          tmp->cid.cid_dnid = strdup(i->dnid);
    04651       if (!ast_strlen_zero(i->accountcode))
    04652          ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
    04653       if (i->amaflags)
    04654          tmp->amaflags = i->amaflags;
    04655       ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
    04656       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
    04657       tmp->adsicpe = i->peeradsicpe;
    04658       i->owner = tmp;
    04659       i->capability = capability;
    04660       ast_setstate(tmp, state);
    04661
    04662       for (v = i->vars ; v ; v = v->next)
    04663          pbx_builtin_setvar_helper(tmp, v->name, v->value);
    04664
    04665       if (state != AST_STATE_DOWN) {
    04666          if (ast_pbx_start(tmp)) {
    04667             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
    04668             ast_hangup(tmp);
    04669             tmp = NULL;
    04670          }
    04671       }
    04672
    04673       ast_mutex_lock(&usecnt_lock);
    04674       usecnt++;
    04675       ast_mutex_unlock(&usecnt_lock);
    04676       ast_update_use_count();
    04677    }
    04678    return tmp;
    04679 }

AST_MUTEX_DEFINE_STATIC | ( | dpcache_lock |  | ) |

AST_MUTEX_DEFINE_STATIC | ( | reg_lock |  | ) |

AST_MUTEX_DEFINE_STATIC | ( | tpeerlock |  | ) |

AST_MUTEX_DEFINE_STATIC | ( | usecnt_lock |  | ) |

static int attempt_transmit | ( | void * | data | ) | `[static]`

Definition at line 2578 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax_frame::callno, ast_iax2_queue::count, chan_iax2_pvt::error, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, ast_iax2_queue::head, iax2_destroy_nolock(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, ast_iax2_queue::lock, LOG_WARNING, MAX_RETRY_TIME, ast_channel::name, iax_frame::next, iax_frame::oseqno, chan_iax2_pvt::owner, iax_frame::prev, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, ast_iax2_queue::tail, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.

Referenced by network_thread().

    02579 {
    02580    /* Attempt to transmit the frame to the remote peer...
    02581       Called without iaxsl held. */
    02582    struct iax_frame *f = data;
    02583    int freeme=0;
    02584    int callno = f->callno;
    02585    char iabuf[INET_ADDRSTRLEN];
    02586    /* Make sure this call is still active */
    02587    if (callno)
    02588       ast_mutex_lock(&iaxsl[callno]);
    02589    if ((f->callno) && iaxs[f->callno]) {
    02590       if ((f->retries < 0) /* Already ACK'd */ ||
    02591           (f->retries >= max_retries) /* Too many attempts */) {
    02592             /* Record an error if we've transmitted too many times */
    02593             if (f->retries >= max_retries) {
    02594                if (f->transfer) {
    02595                   /* Transfer timeout */
    02596                   send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
    02597                } else if (f->final) {
    02598                   if (f->final)
    02599                      iax2_destroy_nolock(f->callno);
    02600                } else {
    02601                   if (iaxs[f->callno]->owner)
    02602                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
    02603                   iaxs[f->callno]->error = ETIMEDOUT;
    02604                   if (iaxs[f->callno]->owner) {
    02605                      struct ast_frame fr = { 0, };
    02606                      /* Hangup the fd */
    02607                      fr.frametype = AST_FRAME_CONTROL;
    02608                      fr.subclass = AST_CONTROL_HANGUP;
    02609                      iax2_queue_frame(f->callno, &fr);
    02610                      /* Remember, owner could disappear */
    02611                      if (iaxs[f->callno]->owner)
    02612                         iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
    02613                   } else {
    02614                      if (iaxs[f->callno]->reg) {
    02615                         memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us));
    02616                         iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT;
    02617                         iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
    02618                      }
    02619                      iax2_destroy_nolock(f->callno);
    02620                   }
    02621                }
    02622
    02623             }
    02624             freeme++;
    02625       } else {
    02626          /* Update it if it needs it */
    02627          update_packet(f);
    02628          /* Attempt transmission */
    02629          send_packet(f);
    02630          f->retries++;
    02631          /* Try again later after 10 times as long */
    02632          f->retrytime *= 10;
    02633          if (f->retrytime > MAX_RETRY_TIME)
    02634             f->retrytime = MAX_RETRY_TIME;
    02635          /* Transfer messages max out at one second */
    02636          if (f->transfer && (f->retrytime > 1000))
    02637             f->retrytime = 1000;
    02638          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
    02639       }
    02640    } else {
    02641       /* Make sure it gets freed */
    02642       f->retries = -1;
    02643       freeme++;
    02644    }
    02645    if (callno)
    02646       ast_mutex_unlock(&iaxsl[callno]);
    02647    /* Do not try again */
    02648    if (freeme) {
    02649       /* Don't attempt delivery, just remove it from the queue */
    02650       ast_mutex_lock(&iaxq.lock);
    02651       if (f->prev)
    02652          f->prev->next = f->next;
    02653       else
    02654          iaxq.head = f->next;
    02655       if (f->next)
    02656          f->next->prev = f->prev;
    02657       else
    02658          iaxq.tail = f->prev;
    02659       iaxq.count--;
    02660       ast_mutex_unlock(&iaxq.lock);
    02661       f->retrans = -1;
    02662       /* Free the IAX frame */
    02663       iax2_frame_free(f);
    02664    }
    02665    return 0;
    02666 }

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

Definition at line 7206 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), auth_reject(), chan_iax2_pvt::authfail, and chan_iax2_pvt::authid.

Referenced by socket_read().

    07207 {
    07208    /* Schedule sending the authentication failure in one second, to prevent
    07209       guessing */
    07210    ast_mutex_lock(&iaxsl[callno]);
    07211    iaxs[callno]->authfail = failcode;
    07212    if (delayreject) {
    07213       if (iaxs[callno]->authid > -1)
    07214          ast_sched_del(sched, iaxs[callno]->authid);
    07215       iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
    07216    } else
    07217       auth_reject((void *)(long)callno);
    07218    ast_mutex_unlock(&iaxsl[callno]);
    07219    return 0;
    07220 }

static int auth_reject | ( | void * | nothing | ) | `[static]`

Definition at line 7184 of file chan_iax2.c.

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

Referenced by auth_fail().

    07185 {
    07186    /* Called from IAX thread only, without iaxs lock */
    07187    int callno = (int)(long)(nothing);
    07188    struct iax_ie_data ied;
    07189    ast_mutex_lock(&iaxsl[callno]);
    07190    if (iaxs[callno]) {
    07191       iaxs[callno]->authid = -1;
    07192       memset(&ied, 0, sizeof(ied));
    07193       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
    07194          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
    07195          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
    07196       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
    07197          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
    07198          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
    07199       }
    07200       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
    07201    }
    07202    ast_mutex_unlock(&iaxsl[callno]);
    07203    return 0;
    07204 }

static int authenticate | ( | char * | challenge,
|  | char * | secret,
|  | char * | keyn,
|  | int | authmethods,
|  | struct iax_ie_data * | ied,
|  | struct sockaddr_in * | sin,
|  | aes_encrypt_ctx * | ecx,
|  | aes_decrypt_ctx * | dcx |
| ) |  |  | `[static]`

Definition at line 6465 of file chan_iax2.c.

References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_enc_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, key(), LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().

    06466 {
    06467    int res = -1;
    06468    int x;
    06469    char iabuf[INET_ADDRSTRLEN];
    06470    if (!ast_strlen_zero(keyn)) {
    06471       if (!(authmethods & IAX_AUTH_RSA)) {
    06472          if (ast_strlen_zero(secret))
    06473             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06474       } else if (ast_strlen_zero(challenge)) {
    06475          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06476       } else {
    06477          char sig[256];
    06478          struct ast_key *key;
    06479          key = ast_key_get(keyn, AST_KEY_PRIVATE);
    06480          if (!key) {
    06481             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
    06482          } else {
    06483             if (ast_sign(key, challenge, sig)) {
    06484                ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n");
    06485                res = -1;
    06486             } else {
    06487                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
    06488                res = 0;
    06489             }
    06490          }
    06491       }
    06492    }
    06493    /* Fall back */
    06494    if (res && !ast_strlen_zero(secret)) {
    06495       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
    06496          struct MD5Context md5;
    06497          unsigned char digest[16];
    06498          char digres[128];
    06499          MD5Init(&md5);
    06500          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
    06501          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
    06502          MD5Final(digest, &md5);
    06503          /* If they support md5, authenticate with it.  */
    06504          for (x=0;x<16;x++)
    06505             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
    06506          if (ecx && dcx)
    06507             build_enc_keys(digest, ecx, dcx);
    06508          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
    06509          res = 0;
    06510       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
    06511          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
    06512          res = 0;
    06513       } else
    06514          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), authmethods);
    06515    }
    06516    return res;
    06517 }

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

Definition at line 6519 of file chan_iax2.c.

References iax2_peer::addr, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strlen_zero(), ast_test_flag, authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::challenge, iax_ies::challenge, chan_iax2_pvt::dcx, destroy_peer(), chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::next, iax2_peer::outkey, chan_iax2_pvt::peer, peerl, ast_peer_list::peers, iax_ie_data::pos, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, chan_iax2_pvt::username, and iax_ies::username.

Referenced by socket_read().

    06520 {
    06521    struct iax2_peer *peer;
    06522    /* Start pessimistic */
    06523    int res = -1;
    06524    int authmethods = 0;
    06525    struct iax_ie_data ied;
    06526
    06527    memset(&ied, 0, sizeof(ied));
    06528
    06529    if (ies->username)
    06530       ast_copy_string(p->username, ies->username, sizeof(p->username));
    06531    if (ies->challenge)
    06532       ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge));
    06533    if (ies->authmethods)
    06534       authmethods = ies->authmethods;
    06535    if (authmethods & IAX_AUTH_MD5)
    06536       merge_encryption(p, ies->encmethods);
    06537    else
    06538       p->encmethods = 0;
    06539
    06540    /* Check for override RSA authentication first */
    06541    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
    06542       /* Normal password authentication */
    06543       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
    06544    } else {
    06545       ast_mutex_lock(&peerl.lock);
    06546       peer = peerl.peers;
    06547       while(peer) {
    06548          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
    06549                         /* No peer specified at our end, or this is the peer */
    06550           && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
    06551                         /* No username specified in peer rule, or this is the right username */
    06552           && (!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)))
    06553                         /* No specified host, or this is our host */
    06554          ) {
    06555             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
    06556             if (!res)
    06557                break;
    06558          }
    06559          peer = peer->next;
    06560       }
    06561       ast_mutex_unlock(&peerl.lock);
    06562       if (!peer) {
    06563          /* We checked our list and didn't find one.  It's unlikely, but possible,
    06564             that we're trying to authenticate *to* a realtime peer */
    06565          if ((peer = realtime_peer(p->peer, NULL))) {
    06566             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
    06567             if (ast_test_flag(peer, IAX_TEMPONLY))
    06568                destroy_peer(peer);
    06569          }
    06570       }
    06571    }
    06572    if (ies->encmethods)
    06573       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
    06574    if (!res)
    06575       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
    06576    return res;
    06577 }

static int authenticate_request | ( | struct chan_iax2_pvt * | p | ) | `[static]`

Definition at line 6177 of file chan_iax2.c.

References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, chan_iax2_pvt::authmethods, iax_ie_data::buf, chan_iax2_pvt::challenge, iax2_user::curauthreq, 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, ast_user_list::lock, iax2_user::maxauthreq, iax2_user::name, iax2_user::next, iax_ie_data::pos, send_command(), send_command_final(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by socket_read().

    06178 {
    06179    struct iax2_user *user = NULL;
    06180    struct iax_ie_data ied;
    06181    int res = -1, authreq_restrict = 0;
    06182
    06183    memset(&ied, 0, sizeof(ied));
    06184
    06185    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
    06186    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
    06187       ast_mutex_lock(&userl.lock);
    06188       user = userl.users;
    06189       while (user) {
    06190          if (!strcmp(user->name, p->username)) {
    06191             if (user->curauthreq == user->maxauthreq)
    06192                authreq_restrict = 1;
    06193             else
    06194                user->curauthreq++;
    06195             break;
    06196          }
    06197          user = user->next;
    06198       }
    06199       ast_mutex_unlock(&userl.lock);
    06200    }
    06201
    06202    /* If the AUTHREQ limit test failed, send back an error */
    06203    if (authreq_restrict) {
    06204       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
    06205       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
    06206       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
    06207       return 0;
    06208    }
    06209
    06210    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
    06211    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
    06212       snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
    06213       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
    06214    }
    06215    if (p->encmethods)
    06216       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
    06217
    06218    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
    06219
    06220    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
    06221
    06222    if (p->encmethods)
    06223       ast_set_flag(p, IAX_ENCRYPTED);
    06224
    06225    return res;
    06226 }

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

Definition at line 6228 of file chan_iax2.c.

References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::host, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, key(), ast_user_list::lock, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, iax2_user::next, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by socket_read().

    06229 {
    06230    char requeststr[256];
    06231    char md5secret[256] = "";
    06232    char secret[256] = "";
    06233    char rsasecret[256] = "";
    06234    int res = -1;
    06235    int x;
    06236    struct iax2_user *user = NULL;
    06237
    06238    if (p->authrej) {
    06239       return res;
    06240    }
    06241    ast_mutex_lock(&userl.lock);
    06242    user = userl.users;
    06243    while (user) {
    06244       if (!strcmp(user->name, p->username))
    06245          break;
    06246       user = user->next;
    06247    }
    06248    if (user) {
    06249       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
    06250          user->curauthreq--;
    06251          ast_clear_flag(p, IAX_MAXAUTHREQ);
    06252       }
    06253       ast_copy_string(p->host, user->name, sizeof(p->host));
    06254    }
    06255    ast_mutex_unlock(&userl.lock);
    06256
    06257    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
    06258       return res;
    06259    if (ies->password)
    06260       ast_copy_string(secret, ies->password, sizeof(secret));
    06261    if (ies->md5_result)
    06262       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
    06263    if (ies->rsa_result)
    06264       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
    06265    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
    06266       struct ast_key *key;
    06267       char *keyn;
    06268       char tmpkey[256];
    06269       char *stringp=NULL;
    06270       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
    06271       stringp=tmpkey;
    06272       keyn = strsep(&stringp, ":");
    06273       while(keyn) {
    06274          key = ast_key_get(keyn, AST_KEY_PUBLIC);
    06275          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
    06276             res = 0;
    06277             break;
    06278          } else if (!key)
    06279             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
    06280          keyn = strsep(&stringp, ":");
    06281       }
    06282    } else if (p->authmethods & IAX_AUTH_MD5) {
    06283       struct MD5Context md5;
    06284       unsigned char digest[16];
    06285       char *tmppw, *stringp;
    06286
    06287       tmppw = ast_strdupa(p->secret);
    06288       stringp = tmppw;
    06289       while((tmppw = strsep(&stringp, ";"))) {
    06290          MD5Init(&md5);
    06291          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
    06292          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
    06293          MD5Final(digest, &md5);
    06294          /* If they support md5, authenticate with it.  */
    06295          for (x=0;x<16;x++)
    06296             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
    06297          if (!strcasecmp(requeststr, md5secret)) {
    06298             res = 0;
    06299             break;
    06300          }
    06301       }
    06302    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
    06303       if (!strcmp(secret, p->secret))
    06304          res = 0;
    06305    }
    06306    return res;
    06307 }

static int auto_congest | ( | void * | nothing | ) | `[static]`

Definition at line 3768 of file chan_iax2.c.

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

Referenced by iax2_call(), and sip_call().

    03769 {
    03770    int callno = PTR_TO_CALLNO(nothing);
    03771    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
    03772    ast_mutex_lock(&iaxsl[callno]);
    03773    if (iaxs[callno]) {
    03774       iaxs[callno]->initid = -1;
    03775       iax2_queue_frame(callno, &f);
    03776       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
    03777    }
    03778    ast_mutex_unlock(&iaxsl[callno]);
    03779    return 0;
    03780 }

static int auto_hangup | ( | void * | nothing | ) | `[static]`

Definition at line 7222 of file chan_iax2.c.

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

Referenced by iax2_dprequest(), and iax2_provision().

    07223 {
    07224    /* Called from IAX thread only, without iaxs lock */
    07225    int callno = (int)(long)(nothing);
    07226    struct iax_ie_data ied;
    07227    ast_mutex_lock(&iaxsl[callno]);
    07228    if (iaxs[callno]) {
    07229       iaxs[callno]->autoid = -1;
    07230       memset(&ied, 0, sizeof(ied));
    07231       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
    07232       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
    07233       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
    07234    }
    07235    ast_mutex_unlock(&iaxsl[callno]);
    07236    return 0;
    07237 }

static void build_callno_limits | ( | struct ast_variable * | v | ) | `[static]`

Definition at line 1687 of file chan_iax2.c.

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

Referenced by set_config().

    01688 {
    01689    struct addr_range *addr_range = NULL;
    01690    struct addr_range tmp;
    01691    struct ast_ha *ha;
    01692    int limit;
    01693    int found;
    01694
    01695    for (; v; v = v->next) {
    01696       limit = -1;
    01697       found = 0;
    01698       ha = ast_append_ha("permit", v->name, NULL);
    01699
    01700       /* check for valid config information */
    01701       if (!ha) {
    01702          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
    01703          continue;
    01704       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
    01705          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
    01706          ast_free_ha(ha);
    01707          continue;
    01708       }
    01709
    01710       ast_copy_ha(ha, &tmp.ha);
    01711       /* find or create the addr_range */
    01712       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
    01713          ao2_lock(addr_range);
    01714          found = 1;
    01715       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
    01716          ast_free_ha(ha);
    01717          return; /* out of memory */
    01718       }
    01719
    01720       /* copy over config data into addr_range object */
    01721       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
    01722       ast_free_ha(ha); /* cleanup the tmp ha */
    01723       addr_range->limit = limit;
    01724       addr_range->delme = 0;
    01725
    01726       /* cleanup */
    01727       if (found) {
    01728          ao2_unlock(addr_range);
    01729       } else {
    01730          ao2_link(callno_limits, addr_range);
    01731       }
    01732       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
    01733    }
    01734 }

static struct iax2_context* build_context | ( | char * | context | ) | `[static, read]`

Definition at line 9523 of file chan_iax2.c.

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

Referenced by build_user().

    09524 {
    09525    struct iax2_context *con = malloc(sizeof(struct iax2_context));
    09526    if (con) {
    09527       ast_copy_string(con->context, context, sizeof(con->context));
    09528       con->next = NULL;
    09529    }
    09530    return con;
    09531 }

static void build_enc_keys | ( | const unsigned char * | digest,
|  | aes_encrypt_ctx * | ecx,
|  | aes_decrypt_ctx * | dcx |
| ) |  |  | `[static]`

Definition at line 5006 of file chan_iax2.c.

References aes_decrypt_key128(), and aes_encrypt_key128().

Referenced by authenticate(), and decrypt_frame().

    05007 {
    05008    aes_encrypt_key128(digest, ecx);
    05009    aes_decrypt_key128(digest, dcx);
    05010 }

static struct iax2_peer * build_peer | ( | const char * | name,
|  | struct ast_variable * | v,
|  | int | temponly |
| ) |  |  | `[static, read]`

Definition at line 9654 of file chan_iax2.c.

References iax2_peer::addr, ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_true(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::dbsecret, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, free, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, ast_peer_list::lock, LOG_WARNING, iax2_peer::mailbox, malloc, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::next, iax2_peer::outkey, peer_set_srcaddr(), peercnt_modify(), iax2_peer::peercontext, peerl, ast_peer_list::peers, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, iax2_peer::regexten, iax2_peer::secret, iax2_peer::smoothing, iax2_peer::sockfd, iax2_peer::username, ast_variable::value, and iax2_peer::zonetag.

    09655 {
    09656    struct iax2_peer *peer;
    09657    struct iax2_peer *prev;
    09658    struct ast_ha *oldha = NULL;
    09659    int maskfound=0;
    09660    int found=0;
    09661    prev = NULL;
    09662    ast_mutex_lock(&peerl.lock);
    09663    if (!temponly) {
    09664       peer = peerl.peers;
    09665       while(peer) {
    09666          if (!strcmp(peer->name, name)) {
    09667             break;
    09668          }
    09669          prev = peer;
    09670          peer = peer->next;
    09671       }
    09672    } else
    09673       peer = NULL;
    09674    if (peer) {
    09675       found++;
    09676       oldha = peer->ha;
    09677       peer->ha = NULL;
    09678       /* Already in the list, remove it and it will be added back (or FREE'd) */
    09679       if (prev) {
    09680          prev->next = peer->next;
    09681       } else {
    09682          peerl.peers = peer->next;
    09683       }
    09684       ast_mutex_unlock(&peerl.lock);
    09685    } else {
    09686       ast_mutex_unlock(&peerl.lock);
    09687       peer = malloc(sizeof(struct iax2_peer));
    09688       if (peer) {
    09689          memset(peer, 0, sizeof(struct iax2_peer));
    09690          peer->expire = -1;
    09691          peer->pokeexpire = -1;
    09692          peer->sockfd = defaultsockfd;
    09693       }
    09694    }
    09695    if (peer) {
    09696       ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
    09697       peer->encmethods = iax2_encryption;
    09698       peer->secret[0] = '\0';
    09699       if (!found) {
    09700          ast_copy_string(peer->name, name, sizeof(peer->name));
    09701          peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
    09702          peer->expiry = min_reg_expire;
    09703       }
    09704       peer->prefs = prefs;
    09705       peer->capability = iax2_capability;
    09706       peer->smoothing = 0;
    09707       peer->pokefreqok = DEFAULT_FREQ_OK;
    09708       peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
    09709       peer->maxcallno = 0;
    09710       peercnt_modify(0, 0, &peer->addr);
    09711       peer->calltoken_required = CALLTOKEN_DEFAULT;
    09712       peer->context[0] = '\0';
    09713       peer->peercontext[0] = '\0';
    09714       ast_clear_flag(peer, IAX_HASCALLERID);
    09715       peer->cid_name[0] = '\0';
    09716       peer->cid_num[0] = '\0';
    09717       while(v) {
    09718          if (!strcasecmp(v->name, "secret")) {
    09719             ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
    09720          } else if (!strcasecmp(v->name, "mailbox")) {
    09721             ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
    09722          } else if (!strcasecmp(v->name, "dbsecret")) {
    09723             ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret));
    09724          } else if (!strcasecmp(v->name, "mailboxdetail")) {
    09725             ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL);
    09726          } else if (!strcasecmp(v->name, "trunk")) {
    09727             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
    09728             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
    09729                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
    09730                ast_clear_flag(peer, IAX_TRUNK);
    09731             }
    09732          } else if (!strcasecmp(v->name, "auth")) {
    09733             peer->authmethods = get_auth_methods(v->value);
    09734          } else if (!strcasecmp(v->name, "encryption")) {
    09735             peer->encmethods = get_encrypt_methods(v->value);
    09736          } else if (!strcasecmp(v->name, "notransfer")) {
    09737             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
    09738          } else if (!strcasecmp(v->name, "jitterbuffer")) {
    09739             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
    09740          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
    09741             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
    09742          } else if (!strcasecmp(v->name, "host")) {
    09743             if (!strcasecmp(v->value, "dynamic")) {
    09744                /* They'll register with us */
    09745                ast_set_flag(peer, IAX_DYNAMIC);
    09746                if (!found) {
    09747                   /* Initialize stuff iff we're not found, otherwise
    09748                      we keep going with what we had */
    09749                   memset(&peer->addr.sin_addr, 0, 4);
    09750                   if (peer->addr.sin_port) {
    09751                      /* If we've already got a port, make it the default rather than absolute */
    09752                      peer->defaddr.sin_port = peer->addr.sin_port;
    09753                      peer->addr.sin_port = 0;
    09754                   }
    09755                }
    09756             } else {
    09757                /* Non-dynamic.  Make sure we become that way if we're not */
    09758                if (peer->expire > -1)
    09759                   ast_sched_del(sched, peer->expire);
    09760                peer->expire = -1;
    09761                ast_clear_flag(peer, IAX_DYNAMIC);
    09762                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
    09763                   free(peer);
    09764                   return NULL;
    09765                }
    09766                if (!peer->addr.sin_port)
    09767                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
    09768             }
    09769             if (!maskfound)
    09770                inet_aton("255.255.255.255", &peer->mask);
    09771          } else if (!strcasecmp(v->name, "defaultip")) {
    09772             if (ast_get_ip(&peer->defaddr, v->value)) {
    09773                free(peer);
    09774                return NULL;
    09775             }
    09776          } else if (!strcasecmp(v->name, "sourceaddress")) {
    09777             peer_set_srcaddr(peer, v->value);
    09778          } else if (!strcasecmp(v->name, "permit") ||
    09779                   !strcasecmp(v->name, "deny")) {
    09780             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
    09781          } else if (!strcasecmp(v->name, "mask")) {
    09782             maskfound++;
    09783             inet_aton(v->value, &peer->mask);
    09784          } else if (!strcasecmp(v->name, "context")) {
    09785             ast_copy_string(peer->context, v->value, sizeof(peer->context));
    09786          } else if (!strcasecmp(v->name, "regexten")) {
    09787             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
    09788          } else if (!strcasecmp(v->name, "peercontext")) {
    09789             ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext));
    09790          } else if (!strcasecmp(v->name, "port")) {
    09791             if (ast_test_flag(peer, IAX_DYNAMIC))
    09792                peer->defaddr.sin_port = htons(atoi(v->value));
    09793             else
    09794                peer->addr.sin_port = htons(atoi(v->value));
    09795          } else if (!strcasecmp(v->name, "username")) {
    09796             ast_copy_string(peer->username, v->value, sizeof(peer->username));
    09797          } else if (!strcasecmp(v->name, "allow")) {
    09798             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
    09799          } else if (!strcasecmp(v->name, "disallow")) {
    09800             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
    09801          } else if (!strcasecmp(v->name, "callerid")) {
    09802             if (!ast_strlen_zero(v->value)) {
    09803                ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name),
    09804                            peer->cid_num, sizeof(peer->cid_num));
    09805                ast_set_flag(peer, IAX_HASCALLERID);
    09806             } else {
    09807                ast_clear_flag(peer, IAX_HASCALLERID);
    09808                peer->cid_name[0] = '\0';
    09809                peer->cid_num[0] = '\0';
    09810             }
    09811          } else if (!strcasecmp(v->name, "sendani")) {
    09812             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
    09813          } else if (!strcasecmp(v->name, "inkeys")) {
    09814             ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys));
    09815          } else if (!strcasecmp(v->name, "outkey")) {
    09816             ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
    09817          } else if (!strcasecmp(v->name, "qualify")) {
    09818             if (!strcasecmp(v->value, "no")) {
    09819                peer->maxms = 0;
    09820             } else if (!strcasecmp(v->value, "yes")) {
    09821                peer->maxms = DEFAULT_MAXMS;
    09822             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
    09823                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);
    09824                peer->maxms = 0;
    09825             }
    09826          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
    09827             peer->smoothing = ast_true(v->value);
    09828          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
    09829             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
    09830                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);
    09831             }
    09832          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
    09833             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
    09834                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);
    09835             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
    09836          } else if (!strcasecmp(v->name, "timezone")) {
    09837             ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag));
    09838          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
    09839             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
    09840                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
    09841             } else {
    09842                peercnt_modify(1, peer->maxcallno, &peer->addr);
    09843             }
    09844          } else if (!strcasecmp(v->name, "requirecalltoken")) {
    09845             /* default is required unless in optional ip list */
    09846             if (ast_false(v->value)) {
    09847                peer->calltoken_required = CALLTOKEN_NO;
    09848             } else if (!strcasecmp(v->value, "auto")) {
    09849                peer->calltoken_required = CALLTOKEN_AUTO;
    09850             } else if (ast_true(v->value)) {
    09851                peer->calltoken_required = CALLTOKEN_YES;
    09852             } else {
    09853                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
    09854             }
    09855          } /* else if (strcasecmp(v->name,"type")) */
    09856          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
    09857          v=v->next;
    09858       }
    09859       if (!peer->authmethods)
    09860          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
    09861       ast_clear_flag(peer, IAX_DELME);
    09862       /* Make sure these are IPv4 addresses */
    09863       peer->addr.sin_family = AF_INET;
    09864    }
    09865    if (oldha)
    09866       ast_free_ha(oldha);
    09867    return peer;
    09868 }

static struct iax2_user * build_user | ( | const char * | name,
|  | struct ast_variable * | v,
|  | int | temponly |
| ) |  |  | `[static, read]`

Definition at line 9871 of file chan_iax2.c.

References iax2_user::accountcode, iax2_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_false(), ast_free_ha(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, iax2_user::cid_name, iax2_user::cid_num, iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, iax2_user::language, ast_variable::lineno, ast_user_list::lock, LOG_WARNING, malloc, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_context::next, iax2_user::next, prefs, iax2_user::prefs, iax2_user::secret, user, userl, ast_user_list::users, ast_variable::value, and iax2_user::vars.

    09872 {
    09873    struct iax2_user *prev, *user;
    09874    struct iax2_context *con, *conl = NULL;
    09875    struct ast_ha *oldha = NULL;
    09876    struct iax2_context *oldcon = NULL;
    09877    int format;
    09878    int oldcurauthreq = 0;
    09879    char *varname = NULL, *varval = NULL;
    09880    struct ast_variable *tmpvar = NULL;
    09881
    09882    prev = NULL;
    09883    ast_mutex_lock(&userl.lock);
    09884    if (!temponly) {
    09885       user = userl.users;
    09886       while(user) {
    09887          if (!strcmp(user->name, name)) {
    09888             break;
    09889          }
    09890          prev = user;
    09891          user = user->next;
    09892       }
    09893    } else
    09894       user = NULL;
    09895
    09896    if (user) {
    09897       oldcurauthreq = user->curauthreq;
    09898       oldha = user->ha;
    09899       oldcon = user->contexts;
    09900       user->ha = NULL;
    09901       user->contexts = NULL;
    09902       /* Already in the list, remove it and it will be added back (or FREE'd) */
    09903       if (prev) {
    09904          prev->next = user->next;
    09905       } else {
    09906          userl.users = user->next;
    09907       }
    09908       ast_mutex_unlock(&userl.lock);
    09909    } else {
    09910       ast_mutex_unlock(&userl.lock);
    09911       user = malloc(sizeof(struct iax2_user));
    09912       if (user)
    09913          memset(user, 0, sizeof(struct iax2_user));
    09914    }
    09915
    09916    if (user) {
    09917       memset(user, 0, sizeof(struct iax2_user));
    09918       user->maxauthreq = maxauthreq;
    09919       user->curauthreq = oldcurauthreq;
    09920       user->prefs = prefs;
    09921       user->capability = iax2_capability;
    09922       user->encmethods = iax2_encryption;
    09923       user->calltoken_required = CALLTOKEN_DEFAULT;
    09924       ast_copy_string(user->name, name, sizeof(user->name));
    09925       ast_copy_string(user->language, language, sizeof(user->language));
    09926       ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
    09927       ast_clear_flag(user, IAX_HASCALLERID);
    09928       user->cid_num[0] = '\0';
    09929       user->cid_name[0] = '\0';
    09930       while(v) {
    09931          if (!strcasecmp(v->name, "context")) {
    09932             con = build_context(v->value);
    09933             if (con) {
    09934                if (conl)
    09935                   conl->next = con;
    09936                else
    09937                   user->contexts = con;
    09938                conl = con;
    09939             }
    09940          } else if (!strcasecmp(v->name, "permit") ||
    09941                   !strcasecmp(v->name, "deny")) {
    09942             user->ha = ast_append_ha(v->name, v->value, user->ha);
    09943          } else if (!strcasecmp(v->name, "setvar")) {
    09944             varname = ast_strdupa(v->value);
    09945             if (varname && (varval = strchr(varname,'='))) {
    09946                *varval = '\0';
    09947                varval++;
    09948                if((tmpvar = ast_variable_new(varname, varval))) {
    09949                   tmpvar->next = user->vars;
    09950                   user->vars = tmpvar;
    09951                }
    09952             }
    09953          } else if (!strcasecmp(v->name, "allow")) {
    09954             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
    09955          } else if (!strcasecmp(v->name, "disallow")) {
    09956             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
    09957          } else if (!strcasecmp(v->name, "trunk")) {
    09958             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
    09959             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
    09960                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
    09961                ast_clear_flag(user, IAX_TRUNK);
    09962             }
    09963          } else if (!strcasecmp(v->name, "auth")) {
    09964             user->authmethods = get_auth_methods(v->value);
    09965          } else if (!strcasecmp(v->name, "encryption")) {
    09966             user->encmethods = get_encrypt_methods(v->value);
    09967          } else if (!strcasecmp(v->name, "notransfer")) {
    09968             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
    09969          } else if (!strcasecmp(v->name, "codecpriority")) {
    09970             if(!strcasecmp(v->value, "caller"))
    09971                ast_set_flag(user, IAX_CODEC_USER_FIRST);
    09972             else if(!strcasecmp(v->value, "disabled"))
    09973                ast_set_flag(user, IAX_CODEC_NOPREFS);
    09974             else if(!strcasecmp(v->value, "reqonly")) {
    09975                ast_set_flag(user, IAX_CODEC_NOCAP);
    09976                ast_set_flag(user, IAX_CODEC_NOPREFS);
    09977             }
    09978          } else if (!strcasecmp(v->name, "jitterbuffer")) {
    09979             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
    09980          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
    09981             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
    09982          } else if (!strcasecmp(v->name, "dbsecret")) {
    09983             ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret));
    09984          } else if (!strcasecmp(v->name, "secret")) {
    09985             if (!ast_strlen_zero(user->secret)) {
    09986                strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
    09987                strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1);
    09988             } else
    09989                ast_copy_string(user->secret, v->value, sizeof(user->secret));
    09990          } else if (!strcasecmp(v->name, "callerid")) {
    09991             if (!ast_strlen_zero(v->value)) {
    09992                ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
    09993                ast_set_flag(user, IAX_HASCALLERID);
    09994             } else {
    09995                ast_clear_flag(user, IAX_HASCALLERID);
    09996                user->cid_name[0] = '\0';
    09997                user->cid_num[0] = '\0';
    09998             }
    09999          } else if (!strcasecmp(v->name, "accountcode")) {
    10000             ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
    10001          } else if (!strcasecmp(v->name, "language")) {
    10002             ast_copy_string(user->language, v->value, sizeof(user->language));
    10003          } else if (!strcasecmp(v->name, "amaflags")) {
    10004             format = ast_cdr_amaflags2int(v->value);
    10005             if (format < 0) {
    10006                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
    10007             } else {
    10008                user->amaflags = format;
    10009             }
    10010          } else if (!strcasecmp(v->name, "inkeys")) {
    10011             ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
    10012          } else if (!strcasecmp(v->name, "maxauthreq")) {
    10013             user->maxauthreq = atoi(v->value);
    10014             if (user->maxauthreq < 0)
    10015                user->maxauthreq = 0;
    10016          } else if (!strcasecmp(v->name, "requirecalltoken")) {
    10017             /* default is required unless in optional ip list */
    10018             if (ast_false(v->value)) {
    10019                user->calltoken_required = CALLTOKEN_NO;
    10020             } else if (!strcasecmp(v->value, "auto")) {
    10021                user->calltoken_required = CALLTOKEN_AUTO;
    10022             } else if (ast_true(v->value)) {
    10023                user->calltoken_required = CALLTOKEN_YES;
    10024             } else {
    10025                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
    10026             }
    10027          } /* else if (strcasecmp(v->name,"type")) */
    10028          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
    10029          v = v->next;
    10030       }
    10031       if (!user->authmethods) {
    10032          if (!ast_strlen_zero(user->secret)) {
    10033             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
    10034             if (!ast_strlen_zero(user->inkeys))
    10035                user->authmethods |= IAX_AUTH_RSA;
    10036          } else if (!ast_strlen_zero(user->inkeys)) {
    10037             user->authmethods = IAX_AUTH_RSA;
    10038          } else {
    10039             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
    10040          }
    10041       }
    10042       ast_clear_flag(user, IAX_DELME);
    10043    }
    10044    if (oldha)
    10045       ast_free_ha(oldha);
    10046    if (oldcon)
    10047       free_context(oldcon);
    10048    return user;
    10049 }

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

Definition at line 10517 of file chan_iax2.c.

References add_empty_calltoken_ie(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, iax_ie_data::buf, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, find_callno(), 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_MAX_CALLS, IAX_PROTO_VERSION, parsed_dial_string::key, LOG_DEBUG, LOG_WARNING, NEW_FORCE, chan_iax2_pvt::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, chan_iax2_pvt::secret, secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.

Referenced by find_cache().

    10518 {
    10519    struct sockaddr_in sin;
    10520    int x;
    10521    int callno;
    10522    struct iax_ie_data ied;
    10523    struct create_addr_info cai;
    10524    struct parsed_dial_string pds;
    10525    char *tmpstr;
    10526
    10527    for (x=0; x<IAX_MAX_CALLS; x++) {
    10528       /* Look for an *exact match* call.  Once a call is negotiated, it can only
    10529          look up entries for a single context */
    10530       if (!ast_mutex_trylock(&iaxsl[x])) {
    10531          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
    10532             return x;
    10533          ast_mutex_unlock(&iaxsl[x]);
    10534       }
    10535    }
    10536
    10537    /* No match found, we need to create a new one */
    10538
    10539    memset(&cai, 0, sizeof(cai));
    10540    memset(&ied, 0, sizeof(ied));
    10541    memset(&pds, 0, sizeof(pds));
    10542
    10543    tmpstr = ast_strdupa(data);
    10544    parse_dial_string(tmpstr, &pds);
    10545
    10546    /* Populate our address from the given */
    10547    if (create_addr(pds.peer, &sin, &cai))
    10548       return -1;
    10549
    10550    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
    10551       pds.peer, pds.username, pds.password, pds.context);
    10552
    10553    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd, 0);
    10554    if (callno < 1) {
    10555       ast_log(LOG_WARNING, "Unable to create call\n");
    10556       return -1;
    10557    }
    10558
    10559    ast_mutex_lock(&iaxsl[callno]);
    10560    ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot));
    10561    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
    10562
    10563    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
    10564    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
    10565    /* the string format is slightly different from a standard dial string,
    10566       because the context appears in the 'exten' position
    10567    */
    10568    if (pds.exten)
    10569       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
    10570    if (pds.username)
    10571       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
    10572    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
    10573    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
    10574    /* Keep password handy */
    10575    if (pds.password)
    10576       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
    10577    if (pds.key)
    10578       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
    10579    /* Start the call going */
    10580    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
    10581    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
    10582
    10583    return callno;
    10584 }

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

Definition at line 4869 of file chan_iax2.c.

References ast_log(), ast_tvsub(), chan_iax2_pvt::callno, LOG_DEBUG, option_debug, and chan_iax2_pvt::rxcore.

    04870 {
    04871    /* Returns where in "receive time" we are.  That is, how many ms
    04872       since we received (or would have received) the frame with timestamp 0 */
    04873    int ms;
    04874 #ifdef IAXTESTS
    04875    int jit;
    04876 #endif /* IAXTESTS */
    04877    /* Setup rxcore if necessary */
    04878    if (ast_tvzero(p->rxcore)) {
    04879       p->rxcore = ast_tvnow();
    04880       if (option_debug && iaxdebug)
    04881          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
    04882                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
    04883       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
    04884 #if 1
    04885       if (option_debug && iaxdebug)
    04886          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
    04887                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
    04888 #endif
    04889    }
    04890
    04891    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
    04892 #ifdef IAXTESTS
    04893    if (test_jit) {
    04894       if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) {
    04895          jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0));
    04896          if ((int)(2.0 * rand() / (RAND_MAX + 1.0)))
    04897             jit = -jit;
    04898          ms += jit;
    04899       }
    04900    }
    04901    if (test_late) {
    04902       ms += test_late;
    04903       test_late = 0;
    04904    }
    04905 #endif /* IAXTESTS */
    04906    return ms;
    04907 }

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

Definition at line 4725 of file chan_iax2.c.

References AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VOICE, ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame::frametype, chan_iax2_pvt::lastsent, LOG_DEBUG, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, chan_iax2_pvt::peercallno, and ast_frame::samples.

Referenced by iax2_send(), and socket_read().

    04726 {
    04727    int ms;
    04728    int voice = 0;
    04729    int genuine = 0;
    04730    int adjust;
    04731    struct timeval *delivery = NULL;
    04732
    04733
    04734    /* What sort of frame do we have?: voice is self-explanatory
    04735       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
    04736       non-genuine frames are CONTROL frames [ringing etc], DTMF
    04737       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
    04738       the others need a timestamp slaved to the voice frames so that they go in sequence
    04739    */
    04740    if (f) {
    04741       if (f->frametype == AST_FRAME_VOICE) {
    04742          voice = 1;
    04743          delivery = &f->delivery;
    04744       } else if (f->frametype == AST_FRAME_IAX) {
    04745          genuine = 1;
    04746       } else if (f->frametype == AST_FRAME_CNG) {
    04747          p->notsilenttx = 0;
    04748       }
    04749    }
    04750    if (ast_tvzero(p->offset)) {
    04751       gettimeofday(&p->offset, NULL);
    04752       /* Round to nearest 20ms for nice looking traces */
    04753       p->offset.tv_usec -= p->offset.tv_usec % 20000;
    04754    }
    04755    /* If the timestamp is specified, just send it as is */
    04756    if (ts)
    04757       return ts;
    04758    /* If we have a time that the frame arrived, always use it to make our timestamp */
    04759    if (delivery && !ast_tvzero(*delivery)) {
    04760       ms = ast_tvdiff_ms(*delivery, p->offset);
    04761       if (option_debug > 2 && iaxdebug)
    04762          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
    04763    } else {
    04764       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
    04765       if (ms < 0)
    04766          ms = 0;
    04767       if (voice) {
    04768          /* On a voice frame, use predicted values if appropriate */
    04769          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
    04770             /* Adjust our txcore, keeping voice and non-voice synchronized */
    04771             /* AN EXPLANATION:
    04772                When we send voice, we usually send "calculated" timestamps worked out
    04773                on the basis of the number of samples sent. When we send other frames,
    04774                we usually send timestamps worked out from the real clock.
    04775                The problem is that they can tend to drift out of step because the
    04776                   source channel's clock and our clock may not be exactly at the same rate.
    04777                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
    04778                for this call.  Moving it adjusts timestamps for non-voice frames.
    04779                We make the adjustment in the style of a moving average.  Each time we
    04780                adjust p->offset by 10% of the difference between our clock-derived
    04781                timestamp and the predicted timestamp.  That's why you see "10000"
    04782                below even though IAX2 timestamps are in milliseconds.
    04783                The use of a moving average avoids offset moving too radically.
    04784                Generally, "adjust" roams back and forth around 0, with offset hardly
    04785                changing at all.  But if a consistent different starts to develop it
    04786                will be eliminated over the course of 10 frames (200-300msecs)
    04787             */
    04788             adjust = (ms - p->nextpred);
    04789             if (adjust < 0)
    04790                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
    04791             else if (adjust > 0)
    04792                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
    04793
    04794             if (!p->nextpred) {
    04795                p->nextpred = ms; /*f->samples / 8;*/
    04796                if (p->nextpred <= p->lastsent)
    04797                   p->nextpred = p->lastsent + 3;
    04798             }
    04799             ms = p->nextpred;
    04800          } else {
    04801                 /* in this case, just use the actual
    04802             * time, since we're either way off
    04803             * (shouldn't happen), or we're  ending a
    04804             * silent period -- and seed the next
    04805             * predicted time.  Also, round ms to the
    04806             * next multiple of frame size (so our
    04807             * silent periods are multiples of
    04808             * frame size too) */
    04809
    04810             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
    04811                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
    04812                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
    04813
    04814             if (f->samples >= 8) /* check to make sure we dont core dump */
    04815             {
    04816                int diff = ms % (f->samples / 8);
    04817                if (diff)
    04818                    ms += f->samples/8 - diff;
    04819             }
    04820
    04821             p->nextpred = ms;
    04822             p->notsilenttx = 1;
    04823          }
    04824       } else {
    04825          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
    04826             it's a genuine frame */
    04827          if (genuine) {
    04828             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
    04829             if (ms <= p->lastsent)
    04830                ms = p->lastsent + 3;
    04831          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
    04832             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
    04833             ms = p->lastsent + 3;
    04834          }
    04835       }
    04836    }
    04837    p->lastsent = ms;
    04838    if (voice)
    04839       p->nextpred = p->nextpred + f->samples / 8;
    04840    return ms;
    04841 }

static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer,
|  | int | sampms,
|  | struct timeval * | tv |
| ) |  |  | `[static]`

Definition at line 4681 of file chan_iax2.c.

References iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.

Referenced by send_trunk().

    04682 {
    04683    unsigned long int mssincetx; /* unsigned to handle overflows */
    04684    long int ms, pred;
    04685
    04686    tpeer->trunkact = *tv;
    04687    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
    04688    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
    04689       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
    04690       tpeer->txtrunktime = *tv;
    04691       tpeer->lastsent = 999999;
    04692    }
    04693    /* Update last transmit time now */
    04694    tpeer->lasttxtime = *tv;
    04695
    04696    /* Calculate ms offset */
    04697    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
    04698    /* Predict from last value */
    04699    pred = tpeer->lastsent + sampms;
    04700    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
    04701       ms = pred;
    04702
    04703    /* We never send the same timestamp twice, so fudge a little if we must */
    04704    if (ms == tpeer->lastsent)
    04705       ms = tpeer->lastsent + 1;
    04706    tpeer->lastsent = ms;
    04707    return ms;
    04708 }

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

Definition at line 1874 of file chan_iax2.c.

Referenced by create_callno_pools().

    01875 {
    01876    return abs(rand());
    01877 }

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

Definition at line 1435 of file chan_iax2.c.

References addr_range_match_address_cb(), ao2_callback(), ao2_ref(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, LOG_DEBUG, option_debug, and user.

Referenced by handle_call_token().

    01436 {
    01437    struct addr_range *addr_range;
    01438    struct iax2_peer *peer = NULL;
    01439    struct iax2_user *user = NULL;
    01440    /* if no username is given, check for guest accounts */
    01441    const char *find = ast_strlen_zero(name) ?  "guest" : name;
    01442    int res = 1;  /* required by default */
    01443    int optional = 0;
    01444    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
    01445    char iabuf[INET_ADDRSTRLEN];
    01446    /* There are only two cases in which calltoken validation is not required.
    01447     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
    01448     *         the peer definition has not set the requirecalltoken option.
    01449     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
    01450     */
    01451
    01452    /* ----- Case 1 ----- */
    01453    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
    01454       ao2_ref(addr_range, -1);
    01455       optional = 1;
    01456    }
    01457
    01458    /* ----- Case 2 ----- */
    01459    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find, 1))) {
    01460       calltoken_required = user->calltoken_required;
    01461    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 1))) {
    01462       calltoken_required = peer->calltoken_required;
    01463    }
    01464
    01465    if (option_debug) {
    01466       ast_log(LOG_DEBUG, "Determining if address %s with username %s requires calltoken validation.  Optional = %d  calltoken_required = %d \n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), name, optional, calltoken_required);
    01467    }
    01468    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
    01469       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
    01470       res = 0;
    01471    }
    01472
    01473    return res;
    01474 }

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

Definition at line 5937 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, iax2_user::accountcode, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, chan_iax2_pvt::ani, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, 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, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, iax2_user::cid_name, chan_iax2_pvt::cid_name, cid_name, iax2_user::cid_num, chan_iax2_pvt::cid_num, cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, iax2_user::contexts, iax2_user::dbsecret, destroy_user(), chan_iax2_pvt::dnid, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, chan_iax2_pvt::exten, exten, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, chan_iax2_pvt::inkeys, iax2_user::inkeys, key(), iax2_user::language, chan_iax2_pvt::language, iax_ies::language, ast_user_list::lock, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), chan_iax2_pvt::secret, secret, iax2_user::secret, user, userl, chan_iax2_pvt::username, iax_ies::username, ast_user_list::users, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, and iax_ies::version.

Referenced by socket_read().

    05938 {
    05939    /* Start pessimistic */
    05940    int res = -1;
    05941    int version = 2;
    05942    struct iax2_user *user, *best = NULL;
    05943    int bestscore = 0;
    05944    int gotcapability = 0;
    05945    char iabuf[INET_ADDRSTRLEN];
    05946    struct ast_variable *v = NULL, *tmpvar = NULL;
    05947
    05948    if (!iaxs[callno])
    05949       return res;
    05950    if (ies->called_number)
    05951       ast_copy_string(iaxs[callno]->exten, ies->called_number, sizeof(iaxs[callno]->exten));
    05952    if (ies->calling_number) {
    05953       ast_shrink_phone_number(ies->calling_number);
    05954       ast_copy_string(iaxs[callno]->cid_num, ies->calling_number, sizeof(iaxs[callno]->cid_num));
    05955    }
    05956    if (ies->calling_name)
    05957       ast_copy_string(iaxs[callno]->cid_name, ies->calling_name, sizeof(iaxs[callno]->cid_name));
    05958    if (ies->calling_ani)
    05959       ast_copy_string(iaxs[callno]->ani, ies->calling_ani, sizeof(iaxs[callno]->ani));
    05960    if (ies->dnid)
    05961       ast_copy_string(iaxs[callno]->dnid, ies->dnid, sizeof(iaxs[callno]->dnid));
    05962    if (ies->called_context)
    05963       ast_copy_string(iaxs[callno]->context, ies->called_context, sizeof(iaxs[callno]->context));
    05964    if (ies->language)
    05965       ast_copy_string(iaxs[callno]->language, ies->language, sizeof(iaxs[callno]->language));
    05966    if (ies->username)
    05967       ast_copy_string(iaxs[callno]->username, ies->username, sizeof(iaxs[callno]->username));
    05968    if (ies->calling_ton > -1)
    05969       iaxs[callno]->calling_ton = ies->calling_ton;
    05970    if (ies->calling_tns > -1)
    05971       iaxs[callno]->calling_tns = ies->calling_tns;
    05972    if (ies->calling_pres > -1)
    05973       iaxs[callno]->calling_pres = ies->calling_pres;
    05974    if (ies->format)
    05975       iaxs[callno]->peerformat = ies->format;
    05976    if (ies->adsicpe)
    05977       iaxs[callno]->peeradsicpe = ies->adsicpe;
    05978    if (ies->capability) {
    05979       gotcapability = 1;
    05980       iaxs[callno]->peercapability = ies->capability;
    05981    }
    05982    if (ies->version)
    05983       version = ies->version;
    05984
    05985    /* Use provided preferences until told otherwise for actual preferences */
    05986    if(ies->codec_prefs) {
    05987       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
    05988       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
    05989    }
    05990
    05991    if (!gotcapability)
    05992       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
    05993    if (version > IAX_PROTO_VERSION) {
    05994       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
    05995          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version);
    05996       return res;
    05997    }
    05998    ast_mutex_lock(&userl.lock);
    05999    /* Search the userlist for a compatible entry, and fill in the rest */
    06000    user = userl.users;
    06001    while(user) {
    06002       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
    06003          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
    06004          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
    06005          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
    06006               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
    06007          if (!ast_strlen_zero(iaxs[callno]->username)) {
    06008             /* Exact match, stop right now. */
    06009             best = user;
    06010             break;
    06011          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
    06012             /* No required authentication */
    06013             if (user->ha) {
    06014                /* There was host authentication and we passed, bonus! */
    06015                if (bestscore < 4) {
    06016                   bestscore = 4;
    06017                   best = user;
    06018                }
    06019             } else {
    06020                /* No host access, but no secret, either, not bad */
    06021                if (bestscore < 3) {
    06022                   bestscore = 3;
    06023                   best = user;
    06024                }
    06025             }
    06026          } else {
    06027             if (user->ha) {
    06028                /* Authentication, but host access too, eh, it's something.. */
    06029                if (bestscore < 2) {
    06030                   bestscore = 2;
    06031                   best = user;
    06032                }
    06033             } else {
    06034                /* Authentication and no host access...  This is our baseline */
    06035                if (bestscore < 1) {
    06036                   bestscore = 1;
    06037                   best = user;
    06038                }
    06039             }
    06040          }
    06041       }
    06042       user = user->next;
    06043    }
    06044    ast_mutex_unlock(&userl.lock);
    06045    user = best;
    06046    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
    06047       user = realtime_user(iaxs[callno]->username, sin);
    06048       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
    06049           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
    06050          destroy_user(user);
    06051          user = NULL;
    06052       }
    06053    }
    06054    if (user) {
    06055       /* We found our match (use the first) */
    06056       /* copy vars */
    06057       for (v = user->vars ; v ; v = v->next) {
    06058          if((tmpvar = ast_variable_new(v->name, v->value))) {
    06059             tmpvar->next = iaxs[callno]->vars;
    06060             iaxs[callno]->vars = tmpvar;
    06061          }
    06062       }
    06063       /* If a max AUTHREQ restriction is in place, activate it */
    06064       if (user->maxauthreq > 0)
    06065          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
    06066       iaxs[callno]->prefs = user->prefs;
    06067       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
    06068       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
    06069       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
    06070       iaxs[callno]->encmethods = user->encmethods;
    06071       /* Store the requested username if not specified */
    06072       if (ast_strlen_zero(iaxs[callno]->username))
    06073          ast_copy_string(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username));
    06074       /* Store whether this is a trunked call, too, of course, and move if appropriate */
    06075       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
    06076       iaxs[callno]->capability = user->capability;
    06077       /* And use the default context */
    06078       if (ast_strlen_zero(iaxs[callno]->context)) {
    06079          if (user->contexts)
    06080             ast_copy_string(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context));
    06081          else
    06082             ast_copy_string(iaxs[callno]->context, context, sizeof(iaxs[callno]->context));
    06083       }
    06084       /* And any input keys */
    06085       ast_copy_string(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys));
    06086       /* And the permitted authentication methods */
    06087       iaxs[callno]->authmethods = user->authmethods;
    06088       /* If they have callerid, override the given caller id.  Always store the ANI */
    06089       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
    06090          if (ast_test_flag(user, IAX_HASCALLERID)) {
    06091             iaxs[callno]->calling_tns = 0;
    06092             iaxs[callno]->calling_ton = 0;
    06093             ast_copy_string(iaxs[callno]->cid_num, user->cid_num, sizeof(iaxs[callno]->cid_num));
    06094             ast_copy_string(iaxs[callno]->cid_name, user->cid_name, sizeof(iaxs[callno]->cid_name));
    06095             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
    06096          }
    06097          if (ast_strlen_zero(iaxs[callno]->ani))
    06098             ast_copy_string(iaxs[callno]->ani, user->cid_num, sizeof(iaxs[callno]->ani));
    06099       } else {
    06100          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
    06101       }
    06102       if (!ast_strlen_zero(user->accountcode))
    06103          ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode));
    06104       if (user->amaflags)
    06105          iaxs[callno]->amaflags = user->amaflags;
    06106       if (!ast_strlen_zero(user->language))
    06107          ast_copy_string(iaxs[callno]->language, user->language, sizeof(iaxs[callno]->language));
    06108       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
    06109       /* Keep this check last */
    06110       if (!ast_strlen_zero(user->dbsecret)) {
    06111          char *family, *key=NULL;
    06112          family = ast_strdupa(user->dbsecret);
    06113          if (family) {
    06114             key = strchr(family, '/');
    06115             if (key) {
    06116                *key = '\0';
    06117                key++;
    06118             }
    06119          }
    06120          if (!family || !key || ast_db_get(family, key, iaxs[callno]->secret, sizeof(iaxs[callno]->secret)))
    06121             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
    06122       } else
    06123          ast_copy_string(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret));
    06124       if (ast_test_flag(user, IAX_TEMPONLY))
    06125          destroy_user(user);
    06126       res = 0;
    06127    } else {
    06128        /* user was not found, but we should still fake an AUTHREQ.
    06129         * Set authmethods to the last known authmethods used by the system.
    06130         * Set a fake secret, it's not looked at, just required to attempt authentication.
    06131         * Set authrej so the AUTHREP is rejected without even looking at its contents */
    06132       iaxs[callno]->authmethods = lastauthmethod ? lastauthmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
    06133       ast_copy_string(iaxs[callno]->secret, "badsecret", sizeof(iaxs[callno]->secret));
    06134       iaxs[callno]->authrej = 1;
    06135       if (!ast_strlen_zero(iaxs[callno]->username)) {
    06136          /* only send the AUTHREQ if a username was specified. */
    06137          res = 0;
    06138       }
    06139    }
    06140    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
    06141    return res;
    06142 }

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

Definition at line 7573 of file chan_iax2.c.

References ast_log(), iax2_provision(), iax_provision_version(), LOG_DEBUG, and option_debug.

Referenced by socket_read().

    07574 {
    07575    unsigned int ourver;
    07576    char rsi[80];
    07577    snprintf(rsi, sizeof(rsi), "si-%s", si);
    07578    if (iax_provision_version(&ourver, rsi, 1))
    07579       return 0;
    07580    if (option_debug)
    07581       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
    07582    if (ourver != ver)
    07583       iax2_provision(sin, sockfd, NULL, rsi, 1);
    07584    return 0;
    07585 }

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

Definition at line 9552 of file chan_iax2.c.

References ast_log(), LOG_DEBUG, and LOG_ERROR.

Referenced by peer_set_srcaddr().

    09553 {
    09554    int sd;
    09555    int res;
    09556
    09557    sd = socket(AF_INET, SOCK_DGRAM, 0);
    09558    if (sd < 0) {
    09559       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
    09560       return -1;
    09561    }
    09562
    09563    res = bind(sd, sa, salen);
    09564    if (res < 0) {
    09565       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
    09566       close(sd);
    09567       return 1;
    09568    }
    09569
    09570    close(sd);
    09571    return 0;
    09572 }

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

Definition at line 6618 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_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, chan_iax2_pvt::dpentries, iax_ies::dpstatus, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters.

Referenced by socket_read().

    06619 {
    06620    char exten[256] = "";
    06621    int status = CACHE_FLAG_UNKNOWN;
    06622    int expiry = iaxdefaultdpcache;
    06623    int x;
    06624    int matchmore = 0;
    06625    struct iax2_dpcache *dp, *prev;
    06626
    06627    if (ies->called_number)
    06628       ast_copy_string(exten, ies->called_number, sizeof(exten));
    06629
    06630    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
    06631       status = CACHE_FLAG_EXISTS;
    06632    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
    06633       status = CACHE_FLAG_CANEXIST;
    06634    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
    06635       status = CACHE_FLAG_NONEXISTENT;
    06636
    06637    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
    06638       /* Don't really do anything with this */
    06639    }
    06640    if (ies->refresh)
    06641       expiry = ies->refresh;
    06642    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
    06643       matchmore = CACHE_FLAG_MATCHMORE;
    06644    ast_mutex_lock(&dpcache_lock);
    06645    prev = NULL;
    06646    dp = pvt->dpentries;
    06647    while(dp) {
    06648       if (!strcmp(dp->exten, exten)) {
    06649          /* Let them go */
    06650          if (prev)
    06651             prev->peer = dp->peer;
    06652          else
    06653             pvt->dpentries = dp->peer;
    06654          dp->peer = NULL;
    06655          dp->callno = 0;
    06656          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
    06657          if (dp->flags & CACHE_FLAG_PENDING) {
    06658             dp->flags &= ~CACHE_FLAG_PENDING;
    06659             dp->flags |= status;
    06660             dp->flags |= matchmore;
    06661          }
    06662          /* Wake up waiters */
    06663          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
    06664             if (dp->waiters[x] > -1) {
    06665                if (write(dp->waiters[x], "asdf", 4) == -1) {
    06666                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
    06667                }
    06668             }
    06669       }
    06670       prev = dp;
    06671       dp = dp->peer;
    06672    }
    06673    ast_mutex_unlock(&dpcache_lock);
    06674    return 0;
    06675 }

static char* complete_iax2_show_peer | ( | char * | line,
|  | char * | word,
|  | int | pos,
|  | int | state |
| ) |  |  | `[static]`

Definition at line 2860 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and strdup.

    02861 {
    02862    int which = 0;
    02863    struct iax2_peer *p;
    02864    char *res = NULL;
    02865
    02866    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
    02867    if(pos == 3) {
    02868       ast_mutex_lock(&peerl.lock);
    02869       for(p = peerl.peers ; p ; p = p->next) {
    02870          if(!strncasecmp(p->name, word, strlen(word))) {
    02871             if(++which > state) {
    02872                res = strdup(p->name);
    02873                break;
    02874             }
    02875          }
    02876       }
    02877       ast_mutex_unlock(&peerl.lock);
    02878    }
    02879
    02880    return res;
    02881 }

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

Definition at line 6677 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, ast_iax2_queue::head, iax2_frame_free(), iaxq, 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, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, 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(), 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_read().

    06678 {
    06679    int peercallno = 0;
    06680    struct chan_iax2_pvt *pvt = iaxs[callno];
    06681    struct iax_frame *cur;
    06682
    06683    if (ies->callno)
    06684       peercallno = ies->callno;
    06685
    06686    if (peercallno < 1) {
    06687       ast_log(LOG_WARNING, "Invalid transfer request\n");
    06688       return -1;
    06689    }
    06690
    06691    /* since a transfer has taken place, the address will change.
    06692     * This must be accounted for in the peercnts table.  Remove
    06693     * the old address and add the new one */
    06694    peercnt_remove_by_addr(&pvt->addr);
    06695    peercnt_add(&pvt->transfer);
    06696    /* now copy over the new address */
    06697    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
    06698    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
    06699    /* Reset sequence numbers */
    06700    pvt->oseqno = 0;
    06701    pvt->rseqno = 0;
    06702    pvt->iseqno = 0;
    06703    pvt->aseqno = 0;
    06704
    06705    if (pvt->peercallno) {
    06706       remove_by_peercallno(pvt);
    06707    }
    06708    pvt->peercallno = peercallno;
    06709    store_by_peercallno(pvt);
    06710
    06711    pvt->transferring = TRANSFER_NONE;
    06712    pvt->svoiceformat = -1;
    06713    pvt->voiceformat = 0;
    06714    pvt->svideoformat = -1;
    06715    pvt->videoformat = 0;
    06716    pvt->transfercallno = -1;
    06717    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
    06718    memset(&pvt->offset, 0, sizeof(pvt->offset));
    06719 #ifdef NEWJB
    06720    {  /* reset jitterbuffer */
    06721          jb_frame frame;
    06722                while(jb_getall(pvt->jb,&frame) == JB_OK)
    06723                   iax2_frame_free(frame.data);
    06724
    06725       jb_reset(pvt->jb);
    06726    }
    06727 #else
    06728    memset(&pvt->history, 0, sizeof(pvt->history));
    06729    pvt->jitterbuffer = 0;
    06730    pvt->jitter = 0;
    06731    pvt->historicjitter = 0;
    06732 #endif
    06733    pvt->lag = 0;
    06734    pvt->last = 0;
    06735    pvt->lastsent = 0;
    06736    pvt->nextpred = 0;
    06737    pvt->pingtime = DEFAULT_RETRY_TIME;
    06738    ast_mutex_lock(&iaxq.lock);
    06739    for (cur = iaxq.head; cur ; cur = cur->next) {
    06740       /* We must cancel any packets that would have been transmitted
    06741          because now we're talking to someone new.  It's okay, they
    06742          were transmitted to someone that didn't care anyway. */
    06743       if (callno == cur->callno)
    06744          cur->retries = -1;
    06745    }
    06746    ast_mutex_unlock(&iaxq.lock);
    06747    return 0;
    06748 }

static unsigned char compress_subclass | ( | int | subclass | ) | `[static]`

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

    00964 {
    00965    int x;
    00966    int power=-1;
    00967    /* If it's 128 or smaller, just return it */
    00968    if (subclass < IAX_FLAG_SC_LOG)
    00969       return subclass;
    00970    /* Otherwise find its power */
    00971    for (x = 0; x < IAX_MAX_SHIFT; x++) {
    00972       if (subclass & (1 << x)) {
    00973          if (power > -1) {
    00974             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
    00975             return 0;
    00976          } else
    00977             power = x;
    00978       }
    00979    }
    00980    return power | IAX_FLAG_SC_LOG;
    00981 }

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

Definition at line 7587 of file chan_iax2.c.

References ast_test_flag, jb_info::current, chan_iax2_pvt::frames_dropped, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, 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, IAX_USEJITTERBUF, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, chan_iax2_pvt::min, and jb_info::min.

Referenced by socket_read().

    07588 {
    07589 #ifdef NEWJB
    07590    jb_info stats;
    07591    jb_getinfo(pvt->jb, &stats);
    07592
    07593    memset(iep, 0, sizeof(*iep));
    07594
    07595    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
    07596    if(stats.frames_in == 0) stats.frames_in = 1;
    07597    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
    07598    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
    07599    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
    07600    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
    07601    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
    07602 #else
    07603    memset(iep, 0, sizeof(*iep));
    07604    iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter);
    07605    iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received);
    07606    if(!ast_test_flag(pvt, IAX_USEJITTERBUF))
    07607       iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0);
    07608    else
    07609       iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min);
    07610    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped);
    07611    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */
    07612    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */
    07613 #endif
    07614 }

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

Definition at line 3680 of file chan_iax2.c.

References iax2_peer::addr, ast_clear_flag, ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, destroy_peer(), iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::outkey, create_addr_info::outkey, 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, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

    03681 {
    03682    struct ast_hostent ahp;
    03683    struct hostent *hp;
    03684    struct iax2_peer *peer;
    03685
    03686    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
    03687    cai->sockfd = defaultsockfd;
    03688    cai->maxtime = 0;
    03689    sin->sin_family = AF_INET;
    03690
    03691    if (!(peer = find_peer(peername, 1))) {
    03692       cai->found = 0;
    03693
    03694       hp = ast_gethostbyname(peername, &ahp);
    03695       if (hp) {
    03696          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
    03697          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
    03698          /* use global iax prefs for unknown peer/user */
    03699          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
    03700          return 0;
    03701       } else {
    03702          ast_log(LOG_WARNING, "No such host: %s\n", peername);
    03703          return -1;
    03704       }
    03705    }
    03706
    03707    cai->found = 1;
    03708
    03709    /* if the peer has no address (current or default), return failure */
    03710    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
    03711       if (ast_test_flag(peer, IAX_TEMPONLY))
    03712          destroy_peer(peer);
    03713       return -1;
    03714    }
    03715
    03716    /* if the peer is being monitored and is currently unreachable, return failure */
    03717    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
    03718       if (ast_test_flag(peer, IAX_TEMPONLY))
    03719          destroy_peer(peer);
    03720       return -1;
    03721    }
    03722
    03723    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
    03724    cai->maxtime = peer->maxms;
    03725    cai->capability = peer->capability;
    03726    cai->encmethods = peer->encmethods;
    03727    cai->sockfd = peer->sockfd;
    03728    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
    03729    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
    03730    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
    03731    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
    03732    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
    03733    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
    03734    if (ast_strlen_zero(peer->dbsecret)) {
    03735       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
    03736    } else {
    03737       char *family;
    03738       char *key = NULL;
    03739
    03740       family = ast_strdupa(peer->dbsecret);
    03741       if (family) {
    03742          key = strchr(family, '/');
    03743          if (key)
    03744             *key++ = '\0';
    03745       }
    03746       if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
    03747          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
    03748          if (ast_test_flag(peer, IAX_TEMPONLY))
    03749             destroy_peer(peer);
    03750          return -1;
    03751       }
    03752    }
    03753
    03754    if (peer->addr.sin_addr.s_addr) {
    03755       sin->sin_addr = peer->addr.sin_addr;
    03756       sin->sin_port = peer->addr.sin_port;
    03757    } else {
    03758       sin->sin_addr = peer->defaddr.sin_addr;
    03759       sin->sin_port = peer->defaddr.sin_port;
    03760    }
    03761
    03762    if (ast_test_flag(peer, IAX_TEMPONLY))
    03763       destroy_peer(peer);
    03764
    03765    return 0;
    03766 }

static int create_callno_pools | ( | void |  | ) | `[static]`

Definition at line 1879 of file chan_iax2.c.

References ao2_alloc(), ao2_container_alloc(), ao2_ref(), callno_entry::callno, callno_hash(), IAX_MAX_CALLS, and TRUNK_CALL_START.

Referenced by load_objects().

    01880 {
    01881    uint16_t i;
    01882
    01883    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
    01884       return -1;
    01885    }
    01886
    01887    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
    01888       return -1;
    01889    }
    01890
    01891    /* start at 2, 0 and 1 are reserved */
    01892    for (i = 2; i <= IAX_MAX_CALLS; i++) {
    01893       struct callno_entry *callno_entry;
    01894
    01895       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
    01896          return -1;
    01897       }
    01898
    01899       callno_entry->callno = i;
    01900
    01901       if (i < TRUNK_CALL_START) {
    01902          ao2_link(callno_pool, callno_entry);
    01903       } else {
    01904          ao2_link(callno_pool_trunk, callno_entry);
    01905       }
    01906
    01907       ao2_ref(callno_entry, -1);
    01908    }
    01909
    01910    return 0;
    01911 }

static int decode_frame | ( | aes_decrypt_ctx * | dcx,
|  | struct ast_iax2_full_hdr * | fh,
|  | struct ast_frame * | f,
|  | int * | datalen |
| ) |  |  | `[static]`

Definition at line 5060 of file chan_iax2.c.

References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, LOG_DEBUG, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame().

    05061 {
    05062    int padding;
    05063    unsigned char *workspace;
    05064    workspace = alloca(*datalen);
    05065    if (!workspace)
    05066       return -1;
    05067    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
    05068       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
    05069       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
    05070          return -1;
    05071       /* Decrypt */
    05072       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
    05073
    05074       padding = 16 + (workspace[15] & 0xf);
    05075       if (option_debug && iaxdebug)
    05076          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
    05077       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
    05078          return -1;
    05079
    05080       *datalen -= padding;
    05081       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
    05082       f->frametype = fh->type;
    05083       if (f->frametype == AST_FRAME_VIDEO) {
    05084          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
    05085       } else {
    05086          f->subclass = uncompress_subclass(fh->csub);
    05087       }
    05088    } else {
    05089       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
    05090       if (option_debug && iaxdebug)
    05091          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
    05092       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
    05093          return -1;
    05094       /* Decrypt */
    05095       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
    05096       padding = 16 + (workspace[15] & 0x0f);
    05097       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
    05098          return -1;
    05099       *datalen -= padding;
    05100       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
    05101    }
    05102    return 0;
    05103 }

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

Definition at line 5146 of file chan_iax2.c.

References ast_set_flag, ast_strdupa, ast_test_flag, build_enc_keys(), decode_frame(), IAX_KEYPOPULATED, MD5Final(), MD5Init(), MD5Update(), secret, and strsep().

Referenced by socket_read().

    05147 {
    05148    int res=-1;
    05149    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
    05150       /* Search for possible keys, given secrets */
    05151       struct MD5Context md5;
    05152       unsigned char digest[16];
    05153       char *tmppw, *stringp;
    05154
    05155       tmppw = ast_strdupa(iaxs[callno]->secret);
    05156       stringp = tmppw;
    05157       while((tmppw = strsep(&stringp, ";"))) {
    05158          MD5Init(&md5);
    05159          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
    05160          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
    05161          MD5Final(digest, &md5);
    05162          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
    05163          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
    05164          if (!res) {
    05165             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
    05166             break;
    05167          }
    05168       }
    05169    } else
    05170       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
    05171    return res;
    05172 }

static void delete_users | ( | void |  | ) | `[static]`

Definition at line 10051 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, iax2_registry::callno, iax2_registry::expire, free, iax2_destroy_nolock(), IAX_DELME, ast_peer_list::lock, ast_user_list::lock, iax2_peer::next, iax2_registry::next, iax2_user::next, peerl, ast_peer_list::peers, chan_iax2_pvt::reg, regl, user, userl, and ast_user_list::users.

    10052 {
    10053    struct iax2_user *user;
    10054    struct iax2_peer *peer;
    10055    struct iax2_registry *reg, *regl;
    10056
    10057    ast_mutex_lock(&userl.lock);
    10058    for (user=userl.users;user;) {
    10059       ast_set_flag(user, IAX_DELME);
    10060       user = user->next;
    10061    }
    10062    ast_mutex_unlock(&userl.lock);
    10063    ast_mutex_lock(&reg_lock);
    10064    for (reg = registrations;reg;) {
    10065       regl = reg;
    10066       reg = reg->next;
    10067       if (regl->expire > -1) {
    10068          ast_sched_del(sched, regl->expire);
    10069       }
    10070       if (regl->callno) {
    10071          /* XXX Is this a potential lock?  I don't think so, but you never know */
    10072          ast_mutex_lock(&iaxsl[regl->callno]);
    10073          if (iaxs[regl->callno]) {
    10074             iaxs[regl->callno]->reg = NULL;
    10075             iax2_destroy_nolock(regl->callno);
    10076          }
    10077          ast_mutex_unlock(&iaxsl[regl->callno]);
    10078       }
    10079       free(regl);
    10080    }
    10081    registrations = NULL;
    10082    ast_mutex_unlock(&reg_lock);
    10083    ast_mutex_lock(&peerl.lock);
    10084    for (peer=peerl.peers;peer;) {
    10085       /* Assume all will be deleted, and we'll find out for sure later */
    10086       ast_set_flag(peer, IAX_DELME);
    10087       peer = peer->next;
    10088    }
    10089    ast_mutex_unlock(&peerl.lock);
    10090 }

char* description | ( | void |  | ) |

Provides a description of the module.

Returns:
  a short description of your module

Definition at line 11367 of file chan_iax2.c.

    11368 {
    11369    return (char *) desc;
    11370 }

static void destroy_firmware | ( | struct iax_firmware * | cur | ) | `[static]`

Definition at line 2105 of file chan_iax2.c.

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

Referenced by reload_firmware().

    02106 {
    02107    /* Close firmware */
    02108    if (cur->fwh) {
    02109       munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
    02110    }
    02111    close(cur->fd);
    02112    free(cur);
    02113 }

static void destroy_peer | ( | struct iax2_peer * | peer | ) | `[static]`

Definition at line 10122 of file chan_iax2.c.

References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::expire, free, iax2_peer::ha, iax2_destroy(), IAX_MAX_CALLS, iax2_peer::pokeexpire, and register_peer_exten().

Referenced by authenticate_reply(), create_addr(), iax2_devicestate(), iax2_getpeername(), iax2_show_peer(), prune_peers(), realtime_peer(), register_verify(), registry_authrequest(), and update_registry().

    10123 {
    10124    int x;
    10125    ast_free_ha(peer->ha);
    10126    for (x=0;x<IAX_MAX_CALLS;x++) {
    10127       ast_mutex_lock(&iaxsl[x]);
    10128       if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
    10129          iax2_destroy(x);
    10130       }
    10131       ast_mutex_unlock(&iaxsl[x]);
    10132    }
    10133    /* Delete it, it needs to disappear */
    10134    if (peer->expire > -1)
    10135       ast_sched_del(sched, peer->expire);
    10136    if (peer->pokeexpire > -1)
    10137       ast_sched_del(sched, peer->pokeexpire);
    10138    if (peer->callno > 0)
    10139       iax2_destroy(peer->callno);
    10140    register_peer_exten(peer, 0);
    10141    if (peer->dnsmgr)
    10142       ast_dnsmgr_release(peer->dnsmgr);
    10143    free(peer);
    10144 }

static void destroy_user | ( | struct iax2_user * | user | ) | `[static]`

Definition at line 10092 of file chan_iax2.c.

References ast_free_ha(), ast_variables_destroy(), iax2_user::contexts, free, free_context(), iax2_user::ha, and iax2_user::vars.

Referenced by check_access(), and prune_users().

    10093 {
    10094    ast_free_ha(user->ha);
    10095    free_context(user->contexts);
    10096    if(user->vars) {
    10097       ast_variables_destroy(user->vars);
    10098       user->vars = NULL;
    10099    }
    10100    free(user);
    10101 }

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

Definition at line 7416 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(), iax_ie_data::buf, IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iax_ie_data::pos, and send_command().

Referenced by dp_lookup_thread(), and socket_read().

    07417 {
    07418    unsigned short dpstatus = 0;
    07419    struct iax_ie_data ied1;
    07420    int mm;
    07421
    07422    memset(&ied1, 0, sizeof(ied1));
    07423    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
    07424    /* Must be started */
    07425    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
    07426       dpstatus = IAX_DPSTATUS_EXISTS;
    07427    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
    07428       dpstatus = IAX_DPSTATUS_CANEXIST;
    07429    } else {
    07430       dpstatus = IAX_DPSTATUS_NONEXISTENT;
    07431    }
    07432    if (ast_ignore_pattern(context, callednum))
    07433       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
    07434    if (mm)
    07435       dpstatus |= IAX_DPSTATUS_MATCHMORE;
    07436    if (!skiplock)
    07437       ast_mutex_lock(&iaxsl[callno]);
    07438    if (iaxs[callno]) {
    07439       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
    07440       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
    07441       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
    07442       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
    07443    }
    07444    if (!skiplock)
    07445       ast_mutex_unlock(&iaxsl[callno]);
    07446 }

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

Definition at line 7448 of file chan_iax2.c.

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

Referenced by spawn_dp_lookup().

    07449 {
    07450    /* Look up for dpreq */
    07451    struct dpreq_data *dpr = data;
    07452    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
    07453    if (dpr->callerid)
    07454       free(dpr->callerid);
    07455    free(dpr);
    07456    return NULL;
    07457 }

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

Definition at line 5105 of file chan_iax2.c.

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

Referenced by iax2_send().

    05106 {
    05107    int padding;
    05108    unsigned char *workspace;
    05109    workspace = alloca(*datalen + 32);
    05110    if (!workspace)
    05111       return -1;
    05112    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
    05113       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
    05114       if (option_debug && iaxdebug)
    05115          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
    05116       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
    05117       padding = 16 + (padding & 0xf);
    05118       memcpy(workspace, poo, padding);
    05119       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
    05120       workspace[15] &= 0xf0;
    05121       workspace[15] |= (padding & 0xf);
    05122       if (option_debug && iaxdebug)
    05123          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
    05124       *datalen += padding;
    05125       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
    05126       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
    05127          memcpy(poo, workspace + *datalen - 32, 32);
    05128    } else {
    05129       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
    05130       if (option_debug && iaxdebug)
    05131          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
    05132       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
    05133       padding = 16 + (padding & 0xf);
    05134       memcpy(workspace, poo, padding);
    05135       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
    05136       workspace[15] &= 0xf0;
    05137       workspace[15] |= (padding & 0x0f);
    05138       *datalen += padding;
    05139       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
    05140       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
    05141          memcpy(poo, workspace + *datalen - 32, 32);
    05142    }
    05143    return 0;
    05144 }

static int expire_registry | ( | void * | data | ) | `[static]`

Definition at line 6887 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_set_flag, ast_test_flag, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, LOG_DEBUG, iax2_peer::name, peercnt_modify(), prune_peers(), realtime_update_peer(), and register_peer_exten().

Referenced by iax2_prune_realtime(), realtime_peer(), reg_source_db(), and update_registry().

    06888 {
    06889    struct iax2_peer *p = data;
    06890
    06891    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
    06892    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
    06893       realtime_update_peer(p->name, &p->addr, 0);
    06894    /* modify entry in peercnts table as _not_ registered */
    06895    peercnt_modify(0, 0, &p->addr);
    06896    /* Reset the address */
    06897    memset(&p->addr, 0, sizeof(p->addr));
    06898    /* Reset expire notice */
    06899    p->expire = -1;
    06900    /* Reset expiry value */
    06901    p->expiry = min_reg_expire;
    06902    if (!ast_test_flag(p, IAX_TEMPONLY))
    06903       ast_db_del("IAX/Registry", p->name);
    06904    register_peer_exten(p, 0);
    06905    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
    06906    if (iax2_regfunk)
    06907       iax2_regfunk(p->name, 0);
    06908
    06909    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
    06910       ast_set_flag(p, IAX_DELME);
    06911       prune_peers();
    06912    }
    06913
    06914    return 0;
    06915 }

static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan,
|  | const char * | data,
|  | const char * | context,
|  | const char * | exten,
|  | int | priority |
| ) |  |  | `[static, read]`

Definition at line 10586 of file chan_iax2.c.

References ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_frfree(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, LOG_WARNING, malloc, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters.

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

    10587 {
    10588    struct iax2_dpcache *dp, *prev = NULL, *next;
    10589    struct timeval tv;
    10590    int x;
    10591    int com[2];
    10592    int timeout;
    10593    int old=0;
    10594    int outfd;
    10595    int abort;
    10596    int callno;
    10597    struct ast_channel *c;
    10598    struct ast_frame *f;
    10599    gettimeofday(&tv, NULL);
    10600    dp = dpcache;
    10601    while(dp) {
    10602       next = dp->next;
    10603       /* Expire old caches */
    10604       if (ast_tvcmp(tv, dp->expiry) > 0) {
    10605             /* It's expired, let it disappear */
    10606             if (prev)
    10607                prev->next = dp->next;
    10608             else
    10609                dpcache = dp->next;
    10610             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
    10611                /* Free memory and go again */
    10612                free(dp);
    10613             } else {
    10614                ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
    10615             }
    10616             dp = next;
    10617             continue;
    10618       }
    10619       /* We found an entry that matches us! */
    10620       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
    10621          break;
    10622       prev = dp;
    10623       dp = next;
    10624    }
    10625    if (!dp) {
    10626       /* No matching entry.  Create a new one. */
    10627       /* First, can we make a callno? */
    10628       callno = cache_get_callno_locked(data);
    10629       if (callno < 0) {
    10630          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
    10631          return NULL;
    10632       }
    10633       dp = malloc(sizeof(struct iax2_dpcache));
    10634       if (!dp) {
    10635          ast_mutex_unlock(&iaxsl[callno]);
    10636          return NULL;
    10637       }
    10638       memset(dp, 0, sizeof(struct iax2_dpcache));
    10639       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
    10640       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
    10641       gettimeofday(&dp->expiry, NULL);
    10642       dp->orig = dp->expiry;
    10643       /* Expires in 30 mins by default */
    10644       dp->expiry.tv_sec += iaxdefaultdpcache;
    10645       dp->next = dpcache;
    10646       dp->flags = CACHE_FLAG_PENDING;
    10647       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
    10648          dp->waiters[x] = -1;
    10649       dpcache = dp;
    10650       dp->peer = iaxs[callno]->dpentries;
    10651       iaxs[callno]->dpentries = dp;
    10652       /* Send the request if we're already up */
    10653       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
    10654          iax2_dprequest(dp, callno);
    10655       ast_mutex_unlock(&iaxsl[callno]);
    10656    }
    10657    /* By here we must have a dp */
    10658    if (dp->flags & CACHE_FLAG_PENDING) {
    10659       /* Okay, here it starts to get nasty.  We need a pipe now to wait
    10660          for a reply to come back so long as it's pending */
    10661       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
    10662          /* Find an empty slot */
    10663          if (dp->waiters[x] < 0)
    10664             break;
    10665       }
    10666       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
    10667          ast_log(LOG_WARNING, "No more waiter positions available\n");
    10668          return NULL;
    10669       }
    10670       if (pipe(com)) {
    10671          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
    10672          return NULL;
    10673       }
    10674       dp->waiters[x] = com[1];
    10675       /* Okay, now we wait */
    10676       timeout = iaxdefaulttimeout * 1000;
    10677       /* Temporarily unlock */
    10678       ast_mutex_unlock(&dpcache_lock);
    10679       /* Defer any dtmf */
    10680       if (chan)
    10681          old = ast_channel_defer_dtmf(chan);
    10682       abort = 0;
    10683       while(timeout) {
    10684          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
    10685          if (outfd > -1) {
    10686             break;
    10687          }
    10688          if (c) {
    10689             f = ast_read(c);
    10690             if (f)
    10691                ast_frfree(f);
    10692             else {
    10693                /* Got hung up on, abort! */
    10694                break;
    10695                abort = 1;
    10696             }
    10697          }
    10698       }
    10699       if (!timeout) {
    10700          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
    10701       }
    10702       ast_mutex_lock(&dpcache_lock);
    10703       dp->waiters[x] = -1;
    10704       close(com[1]);
    10705       close(com[0]);
    10706       if (abort) {
    10707          /* Don't interpret anything, just abort.  Not sure what th epoint
    10708            of undeferring dtmf on a hung up channel is but hey whatever */
    10709          if (!old && chan)
    10710             ast_channel_undefer_dtmf(chan);
    10711          return NULL;
    10712       }
    10713       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
    10714          /* Now to do non-independent analysis the results of our wait */
    10715          if (dp->flags & CACHE_FLAG_PENDING) {
    10716             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
    10717                pending.  Don't let it take as long to timeout. */
    10718             dp->flags &= ~CACHE_FLAG_PENDING;
    10719             dp->flags |= CACHE_FLAG_TIMEOUT;
    10720             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
    10721                systems without leaving it unavailable once the server comes back online */
    10722             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
    10723             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
    10724                if (dp->waiters[x] > -1)
    10725                   write(dp->waiters[x], "asdf", 4);
    10726          }
    10727       }
    10728       /* Our caller will obtain the rest */
    10729       if (!old && chan)
    10730          ast_channel_undefer_dtmf(chan);
    10731    }
    10732    return dp;
    10733 }

static int find_callno | ( | unsigned short | callno,
|  | unsigned short | dcallno,
|  | struct sockaddr_in * | sin,
|  | int | new,
|  | int | lockpeer,
|  | int | sockfd,
|  | int | check_dcallno |
| ) |  |  | `[static]`

Definition at line 1971 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), host, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_USEJITTERBUF, chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, match(), NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), TRUNK_CALL_START, and update_max_nontrunk().

Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_poke_peer(), iax2_provision(), iax2_request(), and socket_read().

    01972 {
    01973    int res = 0;
    01974    int x;
    01975    char iabuf[INET_ADDRSTRLEN];
    01976    /* this call is calltoken validated as long as it is either NEW_FORCE
    01977     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
    01978    int validated = (new > NEW_ALLOW) ? 1 : 0;
    01979    char host[80];
    01980    if (new <= NEW_ALLOW) {
    01981       if (callno) {
    01982          struct chan_iax2_pvt *pvt;
    01983          struct chan_iax2_pvt tmp_pvt = {
    01984             .callno = dcallno,
    01985             .peercallno = callno,
    01986             /* hack!! */
    01987             .frames_received = check_dcallno,
    01988          };
    01989
    01990          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
    01991
    01992          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
    01993             res = pvt->callno;
    01994             ao2_ref(pvt, -1);
    01995             pvt = NULL;
    01996             return res;
    01997          }
    01998       }
    01999
    02000       /* Look for an existing connection first */
    02001       for (x=2;(res < 1) && (x<maxnontrunkcall);x++) {
    02002          ast_mutex_lock(&iaxsl[x]);
    02003          if (iaxs[x]) {
    02004             /* Look for an exact match */
    02005             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
    02006                res = x;
    02007             }
    02008          }
    02009          ast_mutex_unlock(&iaxsl[x]);
    02010       }
    02011       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
    02012          ast_mutex_lock(&iaxsl[x]);
    02013          if (iaxs[x]) {
    02014             /* Look for an exact match */
    02015             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
    02016                res = x;
    02017             }
    02018          }
    02019          ast_mutex_unlock(&iaxsl[x]);
    02020       }
    02021    }
    02022    if ((res < 1) && (new >= NEW_ALLOW)) {
    02023       struct callno_entry *callno_entry;
    02024       /* It may seem odd that we look through the peer list for a name for
    02025        * this *incoming* call.  Well, it is weird.  However, users don't
    02026        * have an IP address/port number that we can match against.  So,
    02027        * this is just checking for a peer that has that IP/port and
    02028        * assuming that we have a user of the same name.  This isn't always
    02029        * correct, but it will be changed if needed after authentication. */
    02030       if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer))
    02031          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
    02032
    02033
    02034       if (peercnt_add(sin)) {
    02035          /* This address has hit its callnumber limit.  When the limit
    02036           * is reached, the connection is not added to the peercnts table.*/
    02037          return 0;
    02038       }
    02039
    02040       if (!(callno_entry = get_unused_callno(0, validated))) {
    02041          /* since we ran out of space, remove the peercnt
    02042           * entry we added earlier */
    02043          peercnt_remove_by_addr(sin);
    02044          ast_log(LOG_WARNING, "No more space\n");
    02045          return 0;
    02046       }
    02047       x = callno_entry->callno;
    02048       ast_mutex_lock(&iaxsl[x]);
    02049
    02050       iaxs[x] = new_iax(sin, lockpeer, host);
    02051       update_max_nontrunk();
    02052       if (iaxs[x]) {
    02053          if (option_debug && iaxdebug)
    02054             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
    02055          iaxs[x]->callno_entry = callno_entry;
    02056          iaxs[x]->sockfd = sockfd;
    02057          iaxs[x]->addr.sin_port = sin->sin_port;
    02058          iaxs[x]->addr.sin_family = sin->sin_family;
    02059          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
    02060          iaxs[x]->peercallno = callno;
    02061          iaxs[x]->callno = x;
    02062          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
    02063          iaxs[x]->expiry = min_reg_expire;
    02064          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
    02065          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
    02066          iaxs[x]->amaflags = amaflags;
    02067          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
    02068          ast_copy_string(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode));
    02069          if (iaxs[x]->peercallno) {
    02070             store_by_peercallno(iaxs[x]);
    02071          }
    02072       } else {
    02073          ast_log(LOG_WARNING, "Out of resources\n");
    02074          ast_mutex_unlock(&iaxsl[x]);
    02075          replace_callno(callno_entry);
    02076          return 0;
    02077       }
    02078       ast_mutex_unlock(&iaxsl[x]);
    02079       res = x;
    02080    }
    02081    return res;
    02082 }

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

Definition at line 1012 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer().

    01013 {
    01014    struct iax2_peer *peer;
    01015    ast_mutex_lock(&peerl.lock);
    01016    for(peer = peerl.peers; peer; peer = peer->next) {
    01017       if (!strcasecmp(peer->name, name)) {
    01018          break;
    01019       }
    01020    }
    01021    ast_mutex_unlock(&peerl.lock);
    01022    if(!peer && realtime)
    01023       peer = realtime_peer(name, NULL);
    01024    return peer;
    01025 }

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

Definition at line 4909 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_inet_ntoa(), ast_log(), ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, LOG_DEBUG, malloc, iax2_trunk_peer::next, iax2_trunk_peer::sockfd, tpeers, and iax2_trunk_peer::trunkact.

Referenced by iax2_trunk_queue(), and socket_read().

    04910 {
    04911    struct iax2_trunk_peer *tpeer;
    04912    char iabuf[INET_ADDRSTRLEN];
    04913    /* Finds and locks trunk peer */
    04914    ast_mutex_lock(&tpeerlock);
    04915    tpeer = tpeers;
    04916    while(tpeer) {
    04917       /* We don't lock here because tpeer->addr *never* changes */
    04918       if (!inaddrcmp(&tpeer->addr, sin)) {
    04919          ast_mutex_lock(&tpeer->lock);
    04920          break;
    04921       }
    04922       tpeer = tpeer->next;
    04923    }
    04924    if (!tpeer) {
    04925       tpeer = malloc(sizeof(struct iax2_trunk_peer));
    04926       if (tpeer) {
    04927          memset(tpeer, 0, sizeof(struct iax2_trunk_peer));
    04928          ast_mutex_init(&tpeer->lock);
    04929          tpeer->lastsent = 9999;
    04930          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
    04931          tpeer->trunkact = ast_tvnow();
    04932          ast_mutex_lock(&tpeer->lock);
    04933          tpeer->next = tpeers;
    04934          tpeer->sockfd = fd;
    04935          tpeers = tpeer;
    04936 #ifdef SO_NO_CHECK
    04937          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
    04938 #endif
    04939          ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
    04940       }
    04941    }
    04942    ast_mutex_unlock(&tpeerlock);
    04943    return tpeer;
    04944 }

static struct iax2_user* find_user | ( | const char * | name,
|  | int | realtime |
| ) |  |  | `[static, read]`

Definition at line 997 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_user_list::lock, iax2_user::name, iax2_user::next, realtime_user(), user, userl, and ast_user_list::users.

    00998 {
    00999    struct iax2_user *user;
    01000    ast_mutex_lock(&userl.lock);
    01001    for(user = userl.users; user; user = user->next) {
    01002       if (!strcasecmp(user->name, name)) {
    01003          break;
    01004       }
    01005    }
    01006    ast_mutex_unlock(&userl.lock);
    01007    if(!user && realtime)
    01008       user = realtime_user(name, NULL);
    01009    return user;
    01010 }

static unsigned int fix_peerts | ( | struct timeval * | tv,
|  | int | callno,
|  | unsigned int | ts |
| ) |  |  | `[static]`

Definition at line 4710 of file chan_iax2.c.

References chan_iax2_pvt::rxcore.

Referenced by socket_read().

    04711 {
    04712    long ms; /* NOT unsigned */
    04713    if (ast_tvzero(iaxs[callno]->rxcore)) {
    04714       /* Initialize rxcore time if appropriate */
    04715       gettimeofday(&iaxs[callno]->rxcore, NULL);
    04716       /* Round to nearest 20ms so traces look pretty */
    04717       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
    04718    }
    04719    /* Calculate difference between trunk and channel */
    04720    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
    04721    /* Return as the sum of trunk time and the difference between trunk and real time */
    04722    return ms + ts;
    04723 }

static void free_context | ( | struct iax2_context * | con | ) | `[static]`

Definition at line 9360 of file chan_iax2.c.

References free, and iax2_context::next.

Referenced by build_user(), and destroy_user().

    09361 {
    09362    struct iax2_context *conl;
    09363    while(con) {
    09364       conl = con;
    09365       con = con->next;
    09366       free(conl);
    09367    }
    09368 }

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

Definition at line 10858 of file chan_iax2.c.

References iax2_peer::addr, ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), IAX_DYNAMIC, LOG_ERROR, iax2_peer::mailbox, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.

    10859 {
    10860    char *ret = NULL;
    10861    struct iax2_peer *peer;
    10862    char *peername, *colname;
    10863    char iabuf[INET_ADDRSTRLEN];
    10864
    10865    buf[0] = '\0';
    10866
    10867    if (!(peername = ast_strdupa(data))) {
    10868       ast_log(LOG_ERROR, "Memory Error!\n");
    10869       return ret;
    10870    }
    10871
    10872    /* if our channel, return the IP address of the endpoint of current channel */
    10873    if (!strcmp(peername,"CURRENTCHANNEL")) {
    10874            unsigned short callno;
    10875       if (chan->tech != &iax2_tech)
    10876          return buf;
    10877       callno = PTR_TO_CALLNO(chan->tech_pvt);
    10878       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
    10879       return buf;
    10880    }
    10881
    10882    if ((colname = strchr(peername, ':'))) {
    10883       *colname = '\0';
    10884       colname++;
    10885    } else {
    10886       colname = "ip";
    10887    }
    10888    if (!(peer = find_peer(peername, 1)))
    10889       return ret;
    10890
    10891    if (!strcasecmp(colname, "ip")) {
    10892       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
    10893    } else  if (!strcasecmp(colname, "status")) {
    10894       peer_status(peer, buf, len);
    10895    } else  if (!strcasecmp(colname, "mailbox")) {
    10896       ast_copy_string(buf, peer->mailbox, len);
    10897    } else  if (!strcasecmp(colname, "context")) {
    10898       ast_copy_string(buf, peer->context, len);
    10899    } else  if (!strcasecmp(colname, "expire")) {
    10900       snprintf(buf, len, "%d", peer->expire);
    10901    } else  if (!strcasecmp(colname, "dynamic")) {
    10902       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
    10903    } else  if (!strcasecmp(colname, "callerid_name")) {
    10904       ast_copy_string(buf, peer->cid_name, len);
    10905    } else  if (!strcasecmp(colname, "callerid_num")) {
    10906       ast_copy_string(buf, peer->cid_num, len);
    10907    } else  if (!strcasecmp(colname, "codecs")) {
    10908       ast_getformatname_multiple(buf, len -1, peer->capability);
    10909    } else  if (!strncasecmp(colname, "codec[", 6)) {
    10910       char *codecnum, *ptr;
    10911       int index = 0, codec = 0;
    10912
    10913       codecnum = strchr(colname, '[');
    10914       *codecnum = '\0';
    10915       codecnum++;
    10916       if ((ptr = strchr(codecnum, ']'))) {
    10917          *ptr = '\0';
    10918       }
    10919       index = atoi(codecnum);
    10920       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
    10921          ast_copy_string(buf, ast_getformatname(codec), len);
    10922       }
    10923    }
    10924    ret = buf;
    10925
    10926    return ret;
    10927 }

static int get_auth_methods | ( | char * | value | ) | `[static]`

Definition at line 9533 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

    09534 {
    09535    int methods = 0;
    09536    if (strstr(value, "rsa"))
    09537       methods |= IAX_AUTH_RSA;
    09538    if (strstr(value, "md5"))
    09539       methods |= IAX_AUTH_MD5;
    09540    if (strstr(value, "plaintext"))
    09541       methods |= IAX_AUTH_PLAINTEXT;
    09542    return methods;
    09543 }

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

Definition at line 925 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

    00926 {
    00927    int e;
    00928    if (!strcasecmp(s, "aes128"))
    00929       e = IAX_ENCRYPT_AES128;
    00930    else if (ast_true(s))
    00931       e = IAX_ENCRYPT_AES128;
    00932    else
    00933       e = 0;
    00934    return e;
    00935 }

static int get_from_jb | ( | void * | p | ) | `[static]`

Definition at line 3051 of file chan_iax2.c.

References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), chan_iax2_pvt::callno, ast_frame::data, jb_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, ast_frame::mallocd, jb_frame::ms, iax_frame::next, ast_frame::offset, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by update_jbsched().

    03052 {
    03053    /* make sure pvt is valid! */
    03054     struct chan_iax2_pvt *pvt = p;
    03055     struct iax_frame *fr;
    03056     jb_frame frame;
    03057     int ret;
    03058     long now;
    03059     long next;
    03060     struct timeval tv;
    03061
    03062     ast_mutex_lock(&iaxsl[pvt->callno]);
    03063     pvt->jbid = -1;
    03064
    03065     gettimeofday(&tv,NULL);
    03066     /* round up a millisecond since ast_sched_runq does; */
    03067     /* prevents us from spinning while waiting for our now */
    03068     /* to catch up with runq's now */
    03069     tv.tv_usec += 1000;
    03070
    03071     now = ast_tvdiff_ms(tv, pvt->rxcore);
    03072
    03073     if(now >= (next = jb_next(pvt->jb))) {
    03074       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
    03075       switch(ret) {
    03076       case JB_OK:
    03077          fr = frame.data;
    03078          __do_deliver(fr);
    03079           break;
    03080       case JB_INTERP:
    03081           {
    03082          struct ast_frame af;
    03083
    03084          /* create an interpolation frame */
    03085          af.frametype = AST_FRAME_VOICE;
    03086          af.subclass = pvt->voiceformat;
    03087          af.datalen  = 0;
    03088          af.samples  = frame.ms * 8;
    03089          af.mallocd  = 0;
    03090          af.src  = "IAX2 JB interpolation";
    03091          af.data  = NULL;
    03092          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
    03093          af.offset=AST_FRIENDLY_OFFSET;
    03094
    03095          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
    03096           * which we'd need to malloc, and then it would free it.  That seems like a drag */
    03097          if (iaxs[pvt->callno] && !ast_test_flag(iaxs[pvt->callno], IAX_ALREADYGONE))
    03098             iax2_queue_frame(pvt->callno, &af);
    03099           }
    03100           break;
    03101       case JB_DROP:
    03102          iax2_frame_free(frame.data);
    03103           break;
    03104       case JB_NOFRAME:
    03105       case JB_EMPTY:
    03106          /* do nothing */
    03107           break;
    03108       default:
    03109          /* shouldn't happen */
    03110           break;
    03111       }
    03112     }
    03113     update_jbsched(pvt);
    03114     ast_mutex_unlock(&iaxsl[pvt->callno]);
    03115     return 0;
    03116 }

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

Definition at line 1812 of file chan_iax2.c.

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

Referenced by find_callno(), and make_trunk().

    01813 {
    01814    struct callno_entry *callno_entry = NULL;
    01815    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
    01816       ast_log(LOG_WARNING, "Out of CallNumbers\n");
    01817       /* Minor optimization for the extreme case. */
    01818       return NULL;
    01819    }
    01820
    01821    /* the callno_pool container is locked here primarily to ensure thread
    01822     * safety of the total_nonval_callno_used check and increment */
    01823    ao2_lock(callno_pool);
    01824
    01825    /* only a certain number of nonvalidated call numbers should be allocated.
    01826     * If there ever is an attack, this separates the calltoken validating
    01827     * users from the non calltoken validating users. */
    01828    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
    01829       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
    01830       ao2_unlock(callno_pool);
    01831       return NULL;
    01832    }
    01833
    01834    /* unlink the object from the container, taking over ownership
    01835     * of the reference the container had to the object */
    01836    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
    01837
    01838    if (callno_entry) {
    01839       callno_entry->validated = validated;
    01840       if (!validated) {
    01841          total_nonval_callno_used++;
    01842       }
    01843    }
    01844
    01845    ao2_unlock(callno_pool);
    01846    return callno_entry;
    01847 }

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

References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), 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(), ast_iax2_full_hdr::scallno, send_apathetic_reply(), t, ast_iax2_full_hdr::ts, uncompress_subclass(), and iax_ies::username.

Referenced by socket_read().

    03973 {
    03974 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
    03975 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
    03976    char buf[256] = { 0 };
    03977    time_t t = time(NULL);
    03978    char hash[41]; /* 40 char sha1 hash */
    03979    int subclass = uncompress_subclass(fh->csub);
    03980    char iabuf[INET_ADDRSTRLEN];
    03981
    03982    /* ----- Case 1 ----- */
    03983    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
    03984       struct iax_ie_data ied = {
    03985          .buf = { 0 },
    03986          .pos = 0,
    03987       };
    03988
    03989       /* create the hash with their address data and our timestamp */
    03990       snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
    03991       ast_sha1_hash(hash, buf);
    03992
    03993       snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
    03994       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf);
    03995       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
    03996
    03997       return 1;
    03998
    03999    /* ----- Case 2 ----- */
    04000    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
    04001       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
    04002       char *rec_ts = NULL;      /* received timestamp */
    04003       unsigned int rec_time;  /* received time_t */
    04004
    04005       /* split the timestamp from the hash data */
    04006       rec_hash = strchr((char *) ies->calltokendata, '?');
    04007       if (rec_hash) {
    04008          *rec_hash++ = '\0';
    04009          rec_ts = (char *) ies->calltokendata;
    04010       }
    04011
    04012       /* check that we have valid data before we do any comparisons */
    04013       if (!rec_hash || !rec_ts) {
    04014          goto reject;
    04015       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
    04016          goto reject;
    04017       }
    04018
    04019       /* create a hash with their address and the _TOKEN'S_ timestamp */
    04020       snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
    04021       ast_sha1_hash(hash, buf);
    04022
    04023       /* compare hashes and then check timestamp delay */
    04024       if (strcmp(hash, rec_hash)) {
    04025          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    04026          goto reject; /* received hash does not match ours, reject */
    04027       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
    04028          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    04029          goto reject; /* too much delay, reject */
    04030       }
    04031
    04032       /* at this point the call token is valid, returning 0
    04033        * will allow socket_process to continue as usual */
    04034       requirecalltoken_mark_auto(ies->username, subclass);
    04035       return 0;
    04036
    04037    /* ----- Case 3 ----- */
    04038    } else { /* calltokens are not supported for this client, how do we respond? */
    04039       if (calltoken_required(sin, ies->username, subclass)) {
    04040          ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenignore list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ies->username);
    04041          goto reject;
    04042       }
    04043       return 0; /* calltoken is not required for this addr, so permit it. */
    04044    }
    04045
    04046 reject:
    04047    /* received frame has failed calltoken inspection, send apathetic reject messages */
    04048    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
    04049       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
    04050    } else {
    04051       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
    04052    }
    04053
    04054    return 1;
    04055 }

static int handle_error | ( | void |  | ) | `[static]`

Definition at line 2399 of file chan_iax2.c.

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

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

    02400 {
    02401    /* XXX Ideally we should figure out why an error occured and then abort those
    02402       rather than continuing to try.  Unfortunately, the published interface does
    02403       not seem to work XXX */
    02404 #if 0
    02405    struct sockaddr_in *sin;
    02406    int res;
    02407    struct msghdr m;
    02408    struct sock_extended_err e;
    02409    m.msg_name = NULL;
    02410    m.msg_namelen = 0;
    02411    m.msg_iov = NULL;
    02412    m.msg_control = &e;
    02413    m.msg_controllen = sizeof(e);
    02414    m.msg_flags = 0;
    02415    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
    02416    if (res < 0)
    02417       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
    02418    else {
    02419       if (m.msg_controllen) {
    02420          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
    02421          if (sin)
    02422             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    02423          else
    02424             ast_log(LOG_WARNING, "No address detected??\n");
    02425       } else {
    02426          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
    02427       }
    02428    }
    02429 #endif
    02430    return 0;
    02431 }

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

Acknowledgment received for OUR registration.

Definition at line 6751 of file chan_iax2.c.

References iax2_registry::addr, iax_ies::apparent_addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax_ies::refresh, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3.

Referenced by socket_read().

    06752 {
    06753    struct iax2_registry *reg;
    06754    /* Start pessimistic */
    06755    char peer[256] = "";
    06756    char msgstatus[40];
    06757    int refresh = 60;
    06758    char ourip[256] = "<Unspecified>";
    06759    struct sockaddr_in oldus;
    06760    struct sockaddr_in us;
    06761    char iabuf[INET_ADDRSTRLEN];
    06762    int oldmsgs;
    06763
    06764    memset(&us, 0, sizeof(us));
    06765    if (ies->apparent_addr)
    06766       bcopy(ies->apparent_addr, &us, sizeof(us));
    06767    if (ies->username)
    06768       ast_copy_string(peer, ies->username, sizeof(peer));
    06769    if (ies->refresh)
    06770       refresh = ies->refresh;
    06771    if (ies->calling_number) {
    06772       /* We don't do anything with it really, but maybe we should */
    06773    }
    06774    reg = iaxs[callno]->reg;
    06775    if (!reg) {
    06776       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
    06777       return -1;
    06778    }
    06779    memcpy(&oldus, &reg->us, sizeof(oldus));
    06780    oldmsgs = reg->messages;
    06781    if (inaddrcmp(&reg->addr, sin)) {
    06782       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06783       return -1;
    06784    }
    06785    memcpy(&reg->us, &us, sizeof(reg->us));
    06786    reg->messages = ies->msgcount;
    06787    /* always refresh the registration at the interval requested by the server
    06788       we are registering to
    06789    */
    06790    reg->refresh = refresh;
    06791    if (reg->expire > -1)
    06792       ast_sched_del(sched, reg->expire);
    06793    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
    06794    if ((inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) {
    06795       if (reg->messages > 65534)
    06796          snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
    06797       else if (reg->messages > 1)
    06798          snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
    06799       else if (reg->messages > 0)
    06800          snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
    06801       else
    06802          snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
    06803       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
    06804       ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ourip, msgstatus);
    06805       manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06806    }
    06807    reg->regstate = REG_STATE_REGISTERED;
    06808    return 0;
    06809 }

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

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

    01952 {
    01953    if (frametype != AST_FRAME_IAX) {
    01954       return 0;
    01955    }
    01956    switch (subclass) {
    01957    case IAX_COMMAND_NEW:
    01958    case IAX_COMMAND_REGREQ:
    01959    case IAX_COMMAND_FWDOWNL:
    01960    case IAX_COMMAND_REGREL:
    01961       return 1;
    01962    case IAX_COMMAND_POKE:
    01963       if (!inbound) {
    01964          return 1;
    01965       }
    01966       break;
    01967    }
    01968    return 0;
    01969 }

static int iax2_answer | ( | struct ast_channel * | c | ) | `[static]`

Definition at line 4526 of file chan_iax2.c.

References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), LOG_DEBUG, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

    04527 {
    04528    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
    04529    if (option_debug)
    04530       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
    04531    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
    04532 }

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

References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, ast_frame::frametype, iax2_start_transfer(), IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, last, lock_both(), LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_debug, option_verbose, PTR_TO_CALLNO, ast_channel::tech_pvt, TRANSFER_RELEASED, tv, ast_channel::type, unlock_both(), and VERBOSE_PREFIX_3.

    04361 {
    04362    struct ast_channel *cs[3];
    04363    struct ast_channel *who;
    04364    int to = -1;
    04365    int res = -1;
    04366    int transferstarted=0;
    04367    struct ast_frame *f;
    04368    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
    04369    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
    04370    struct timeval waittimer = {0, 0}, tv;
    04371
    04372    lock_both(callno0, callno1);
    04373    /* Put them in native bridge mode */
    04374    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
    04375       iaxs[callno0]->bridgecallno = callno1;
    04376       iaxs[callno1]->bridgecallno = callno0;
    04377    }
    04378    unlock_both(callno0, callno1);
    04379
    04380    /* If not, try to bridge until we can execute a transfer, if we can */
    04381    cs[0] = c0;
    04382    cs[1] = c1;
    04383    for (/* ever */;;) {
    04384       /* Check in case we got masqueraded into */
    04385       if ((c0->type != channeltype) || (c1->type != channeltype)) {
    04386          if (option_verbose > 2)
    04387             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
    04388          /* Remove from native mode */
    04389          if (c0->type == channeltype) {
    04390             ast_mutex_lock(&iaxsl[callno0]);
    04391             iaxs[callno0]->bridgecallno = 0;
    04392             ast_mutex_unlock(&iaxsl[callno0]);
    04393          }
    04394          if (c1->type == channeltype) {
    04395             ast_mutex_lock(&iaxsl[callno1]);
    04396             iaxs[callno1]->bridgecallno = 0;
    04397             ast_mutex_unlock(&iaxsl[callno1]);
    04398          }
    04399          return AST_BRIDGE_FAILED_NOWARN;
    04400       }
    04401       if (c0->nativeformats != c1->nativeformats) {
    04402          if (option_verbose > 2) {
    04403             char buf0[255];
    04404             char buf1[255];
    04405             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
    04406             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
    04407             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
    04408          }
    04409          /* Remove from native mode */
    04410          lock_both(callno0, callno1);
    04411          iaxs[callno0]->bridgecallno = 0;
    04412          iaxs[callno1]->bridgecallno = 0;
    04413          unlock_both(callno0, callno1);
    04414          return AST_BRIDGE_FAILED_NOWARN;
    04415       }
    04416       /* check if transfered and if we really want native bridging */
    04417       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER) &&
    04418       !(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
    04419          /* Try the transfer */
    04420          if (iax2_start_transfer(callno0, callno1))
    04421             ast_log(LOG_WARNING, "Unable to start the transfer\n");
    04422          transferstarted = 1;
    04423       }
    04424       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
    04425          /* Call has been transferred.  We're no longer involved */
    04426          gettimeofday(&tv, NULL);
    04427          if (ast_tvzero(waittimer)) {
    04428             waittimer = tv;
    04429          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
    04430             c0->_softhangup |= AST_SOFTHANGUP_DEV;
    04431             c1->_softhangup |= AST_SOFTHANGUP_DEV;
    04432             *fo = NULL;
    04433             *rc = c0;
    04434             res = AST_BRIDGE_COMPLETE;
    04435             break;
    04436          }
    04437       }
    04438       to = 1000;
    04439       who = ast_waitfor_n(cs, 2, &to);
    04440       if (timeoutms > -1) {
    04441          timeoutms -= (1000 - to);
    04442          if (timeoutms < 0)
    04443             timeoutms = 0;
    04444       }
    04445       if (!who) {
    04446          if (!timeoutms) {
    04447             res = AST_BRIDGE_RETRY;
    04448             break;
    04449          }
    04450          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
    04451             res = AST_BRIDGE_FAILED;
    04452             break;
    04453          }
    04454          continue;
    04455       }
    04456       f = ast_read(who);
    04457       if (!f) {
    04458          *fo = NULL;
    04459          *rc = who;
    04460          res = AST_BRIDGE_COMPLETE;
    04461          break;
    04462       }
    04463       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
    04464          *fo = f;
    04465          *rc = who;
    04466          res =  AST_BRIDGE_COMPLETE;
    04467          break;
    04468       }
    04469       if ((f->frametype == AST_FRAME_VOICE) ||
    04470           (f->frametype == AST_FRAME_TEXT) ||
    04471           (f->frametype == AST_FRAME_VIDEO) ||
    04472           (f->frametype == AST_FRAME_IMAGE) ||
    04473           (f->frametype == AST_FRAME_DTMF)) {
    04474          if ((f->frametype == AST_FRAME_DTMF) &&
    04475              (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
    04476             if ((who == c0)) {
    04477                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
    04478                   *rc = c0;
    04479                   *fo = f;
    04480                   res = AST_BRIDGE_COMPLETE;
    04481                   /* Remove from native mode */
    04482                   break;
    04483                } else
    04484                   goto tackygoto;
    04485             } else
    04486             if ((who == c1)) {
    04487                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
    04488                   *rc = c1;
    04489                   *fo = f;
    04490                   res =  AST_BRIDGE_COMPLETE;
    04491                   break;
    04492                } else
    04493                   goto tackygoto;
    04494             }
    04495          } else {
    04496 #if 0
    04497             if (iaxdebug && option_debug)
    04498                ast_log(LOG_DEBUG, "Read from %s\n", who->name);
    04499             if (who == last)
    04500                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
    04501             last = who;
    04502 #endif
    04503 tackygoto:
    04504             if (who == c0)
    04505                ast_write(c1, f);
    04506             else
    04507                ast_write(c0, f);
    04508          }
    04509          ast_frfree(f);
    04510       } else
    04511          ast_frfree(f);
    04512       /* Swap who gets priority */
    04513       cs[2] = cs[0];
    04514       cs[0] = cs[1];
    04515       cs[1] = cs[2];
    04516    }
    04517    lock_both(callno0, callno1);
    04518    if(iaxs[callno0])
    04519       iaxs[callno0]->bridgecallno = 0;
    04520    if(iaxs[callno1])
    04521       iaxs[callno1]->bridgecallno = 0;
    04522    unlock_both(callno0, callno1);
    04523    return res;
    04524 }

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

Definition at line 4115 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_sched_add(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_strlen_zero(), ast_test_flag, auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, chan_iax2_pvt::context, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_datetime(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), 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_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, chan_iax2_pvt::initid, parsed_dial_string::key, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, n, ast_channel::name, ast_channel::nativeformats, parsed_dial_string::options, chan_iax2_pvt::outkey, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, chan_iax2_pvt::secret, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, chan_iax2_pvt::username, create_addr_info::username, and parsed_dial_string::username.

    04116 {
    04117    struct sockaddr_in sin;
    04118    char *l=NULL, *n=NULL, *tmpstr;
    04119    struct iax_ie_data ied;
    04120    char *defaultrdest = "s";
    04121    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
    04122    struct parsed_dial_string pds;
    04123    struct create_addr_info cai;
    04124
    04125    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
    04126       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
    04127       return -1;
    04128    }
    04129
    04130    memset(&cai, 0, sizeof(cai));
    04131    cai.encmethods = iax2_encryption;
    04132
    04133    memset(&pds, 0, sizeof(pds));
    04134    tmpstr = ast_strdupa(dest);
    04135    parse_dial_string(tmpstr, &pds);
    04136
    04137    if (!pds.exten)
    04138       pds.exten = defaultrdest;
    04139
    04140    if (create_addr(pds.peer, &sin, &cai)) {
    04141       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
    04142       return -1;
    04143    }
    04144
    04145    if (!pds.username && !ast_strlen_zero(cai.username))
    04146       pds.username = cai.username;
    04147    if (!pds.password && !ast_strlen_zero(cai.secret))
    04148       pds.password = cai.secret;
    04149    if (!pds.key && !ast_strlen_zero(cai.outkey))
    04150       pds.key = cai.outkey;
    04151    if (!pds.context && !ast_strlen_zero(cai.peercontext))
    04152       pds.context = cai.peercontext;
    04153
    04154    /* Keep track of the context for outgoing calls too */
    04155    ast_copy_string(c->context, cai.context, sizeof(c->context));
    04156
    04157    if (pds.port)
    04158       sin.sin_port = htons(atoi(pds.port));
    04159
    04160    l = c->cid.cid_num;
    04161    n = c->cid.cid_name;
    04162
    04163    /* Now build request */
    04164    memset(&ied, 0, sizeof(ied));
    04165
    04166    /* On new call, first IE MUST be IAX version of caller */
    04167    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
    04168    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
    04169    if (pds.options && strchr(pds.options, 'a')) {
    04170       /* Request auto answer */
    04171       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
    04172    }
    04173
    04174    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
    04175
    04176    if (l) {
    04177       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
    04178       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
    04179    } else {
    04180       if (n)
    04181          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
    04182       else
    04183          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
    04184    }
    04185
    04186    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
    04187    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
    04188
    04189    if (n)
    04190       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
    04191    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
    04192       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
    04193
    04194    if (!ast_strlen_zero(c->language))
    04195       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
    04196    if (!ast_strlen_zero(c->cid.cid_dnid))
    04197       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
    04198
    04199    if (pds.context)
    04200       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
    04201
    04202    if (pds.username)
    04203       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
    04204
    04205    if (cai.encmethods)
    04206       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
    04207
    04208    ast_mutex_lock(&iaxsl[callno]);
    04209
    04210    if (!ast_strlen_zero(c->context))
    04211       ast_copy_string(iaxs[callno]->context, c->context, sizeof(iaxs[callno]->context));
    04212
    04213    if (pds.username)
    04214       ast_copy_string(iaxs[callno]->username, pds.username, sizeof(iaxs[callno]->username));
    04215
    04216    iaxs[callno]->encmethods = cai.encmethods;
    04217
    04218    if (pds.key)
    04219       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
    04220    if (pds.password)
    04221       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
    04222
    04223    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
    04224    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
    04225    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
    04226    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
    04227
    04228    if (iaxs[callno]->maxtime) {
    04229       /* Initialize pingtime and auto-congest time */
    04230       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
    04231       iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
    04232    } else if (autokill) {
    04233       iaxs[callno]->pingtime = autokill / 2;
    04234       iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
    04235    }
    04236
    04237    /* send the command using the appropriate socket for this peer */
    04238    iaxs[callno]->sockfd = cai.sockfd;
    04239
    04240    /* Transmit the string in a "NEW" request */
    04241    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
    04242    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
    04243
    04244    ast_mutex_unlock(&iaxsl[callno]);
    04245    ast_setstate(c, AST_STATE_RINGING);
    04246
    04247    return 0;
    04248 }

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

Definition at line 10759 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

    10760 {
    10761    int res = 0;
    10762    struct iax2_dpcache *dp;
    10763 #if 0
    10764    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
    10765 #endif
    10766    if ((priority != 1) && (priority != 2))
    10767       return 0;
    10768    ast_mutex_lock(&dpcache_lock);
    10769    dp = find_cache(chan, data, context, exten, priority);
    10770    if (dp) {
    10771       if (dp->flags & CACHE_FLAG_CANEXIST)
    10772          res= 1;
    10773    }
    10774    ast_mutex_unlock(&dpcache_lock);
    10775    if (!dp) {
    10776       ast_log(LOG_WARNING, "Unable to make DP cache\n");
    10777    }
    10778    return res;
    10779 }

static unsigned int iax2_datetime | ( | char * | tz | ) | `[static]`

Definition at line 3782 of file chan_iax2.c.

References ast_localtime(), ast_strlen_zero(), and t.

Referenced by iax2_call(), and update_registry().

    03783 {
    03784    time_t t;
    03785    struct tm tm;
    03786    unsigned int tmp;
    03787    time(&t);
    03788    localtime_r(&t, &tm);
    03789    if (!ast_strlen_zero(tz))
    03790       ast_localtime(&t, &tm, tz);
    03791    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
    03792    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
    03793    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
    03794    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
    03795    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
    03796    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
    03797    return tmp;
    03798 }

static void iax2_destroy | ( | int | callno | ) | `[static]`

Definition at line 1135 of file chan_iax2.c.

References ast_channel::_softhangup, ao2_ref(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), AST_SOFTHANGUP_DEV, ast_channel::lock, LOG_NOTICE, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), and update_max_trunk().

Referenced by __unload_module(), destroy_peer(), iax2_destroy_nolock(), iax2_poke_noanswer(), and iax2_poke_peer().

    01136 {
    01137    struct chan_iax2_pvt *pvt;
    01138    struct ast_channel *owner;
    01139
    01140 retry:
    01141    ast_mutex_lock(&iaxsl[callno]);
    01142    pvt = iaxs[callno];
    01143
    01144    if (pvt)
    01145       owner = pvt->owner;
    01146    else
    01147       owner = NULL;
    01148    if (owner) {
    01149       if (ast_mutex_trylock(&owner->lock)) {
    01150          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
    01151          ast_mutex_unlock(&iaxsl[callno]);
    01152          usleep(1);
    01153          goto retry;
    01154       }
    01155    }
    01156    if (!owner)
    01157       iaxs[callno] = NULL;
    01158    if (pvt) {
    01159       if (owner) {
    01160          /* If there's an owner, prod it to give up */
    01161          owner->_softhangup |= AST_SOFTHANGUP_DEV;
    01162          ast_queue_hangup(owner);
    01163       } else {
    01164          pvt->owner = NULL;
    01165       }
    01166
    01167       if (pvt->peercallno) {
    01168          remove_by_peercallno(pvt);
    01169       }
    01170
    01171       if (!owner) {
    01172          ao2_ref(pvt, -1);
    01173          pvt = NULL;
    01174       }
    01175    }
    01176
    01177    if (owner) {
    01178       ast_mutex_unlock(&owner->lock);
    01179    }
    01180
    01181    ast_mutex_unlock(&iaxsl[callno]);
    01182
    01183    if (callno & 0x4000) {
    01184       update_max_trunk();
    01185    }
    01186 }

static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | `[static]`

Definition at line 1073 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, ast_user_list::lock, iax2_user::name, iax2_user::next, chan_iax2_pvt::pingid, user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by pvt_destructor().

    01074 {
    01075    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
    01076       struct iax2_user *user;
    01077
    01078       ast_mutex_lock(&userl.lock);
    01079       user = userl.users;
    01080       while (user) {
    01081          if (!strcmp(user->name, pvt->username)) {
    01082             user->curauthreq--;
    01083             break;
    01084          }
    01085          user = user->next;
    01086       }
    01087       ast_mutex_unlock(&userl.lock);
    01088    }
    01089
    01090    /* No more pings or lagrq's */
    01091    if (pvt->pingid > -1)
    01092       ast_sched_del(sched, pvt->pingid);
    01093    if (pvt->lagid > -1)
    01094       ast_sched_del(sched, pvt->lagid);
    01095    if (pvt->autoid > -1)
    01096       ast_sched_del(sched, pvt->autoid);
    01097    if (pvt->authid > -1)
    01098       ast_sched_del(sched, pvt->authid);
    01099    if (pvt->initid > -1)
    01100       ast_sched_del(sched, pvt->initid);
    01101 #ifdef NEWJB
    01102    if (pvt->jbid > -1)
    01103       ast_sched_del(sched, pvt->jbid);
    01104    pvt->jbid = -1;
    01105 #endif
    01106    pvt->pingid = -1;
    01107    pvt->lagid = -1;
    01108    pvt->autoid = -1;
    01109    pvt->authid = -1;
    01110    pvt->initid = -1;
    01111 }

static void iax2_destroy_nolock | ( | int | callno | ) | `[static]`

Definition at line 2558 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), and iax2_destroy().

Referenced by attempt_transmit(), delete_users(), iax2_hangup(), and socket_read().

    02559 {
    02560    /* Actually it's easier to unlock, kill it, and relock */
    02561    ast_mutex_unlock(&iaxsl[callno]);
    02562    iax2_destroy(callno);
    02563    ast_mutex_lock(&iaxsl[callno]);
    02564 }

static int iax2_devicestate | ( | void * | data | ) | `[static]`

Definition at line 10952 of file chan_iax2.c.

References iax2_peer::addr, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::defaddr, destroy_peer(), find_peer(), iax2_peer::historicms, IAX_TEMPONLY, iax2_peer::lastms, LOG_DEBUG, iax2_peer::maxms, option_debug, parse_dial_string(), and parsed_dial_string::peer.

    10953 {
    10954    struct parsed_dial_string pds;
    10955    char *tmp = ast_strdupa(data);
    10956    struct iax2_peer *p;
    10957    int res = AST_DEVICE_INVALID;
    10958
    10959    memset(&pds, 0, sizeof(pds));
    10960    parse_dial_string(tmp, &pds);
    10961    if (!pds.peer || ast_strlen_zero(pds.peer))
    10962       return res;
    10963
    10964    if (option_debug > 2)
    10965       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
    10966
    10967    /* SLD: FIXME: second call to find_peer during registration */
    10968    if (!(p = find_peer(pds.peer, 1)))
    10969       return res;
    10970
    10971    res = AST_DEVICE_UNAVAILABLE;
    10972    if (option_debug > 2)
    10973       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
    10974          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
    10975
    10976    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
    10977        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
    10978       /* Peer is registered, or have default IP address
    10979          and a valid registration */
    10980       if (p->historicms == 0 || p->historicms <= p->maxms)
    10981          /* let the core figure out whether it is in use or not */
    10982          res = AST_DEVICE_UNKNOWN;
    10983    }
    10984
    10985    if (ast_test_flag(p, IAX_TEMPONLY))
    10986       destroy_peer(p);
    10987
    10988    return res;
    10989 }

static int iax2_digit | ( | struct ast_channel * | c,
|  | char | digit |
| ) |  |  | `[static]`

Definition at line 3409 of file chan_iax2.c.

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

    03410 {
    03411    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
    03412 }

static int iax2_do_debug | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5785 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05786 {
    05787    if (argc != 2)
    05788       return RESULT_SHOWUSAGE;
    05789    iaxdebug = 1;
    05790    ast_cli(fd, "IAX2 Debugging Enabled\n");
    05791    return RESULT_SUCCESS;
    05792 }

static int iax2_do_jb_debug | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5803 of file chan_iax2.c.

References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05804 {
    05805    if (argc != 3)
    05806       return RESULT_SHOWUSAGE;
    05807 #ifdef NEWJB
    05808    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
    05809 #endif
    05810    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
    05811    return RESULT_SUCCESS;
    05812 }

static int iax2_do_register | ( | struct iax2_registry * | reg | ) | `[static]`

Definition at line 9144 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_registry::addr, AST_FRAME_IAX, ast_log(), ast_sched_add(), ast_sched_del(), iax_ie_data::buf, iax2_registry::callno, iax2_registry::expire, find_callno(), iax2_do_register_s(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, iax2_registry::regstate, send_command(), and iax2_registry::username.

Referenced by iax2_do_register_s(), and load_module().

    09145 {
    09146    struct iax_ie_data ied;
    09147    if (option_debug && iaxdebug)
    09148       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
    09149    if (!reg->callno) {
    09150       if (option_debug)
    09151          ast_log(LOG_DEBUG, "Allocate call number\n");
    09152       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd, 0);
    09153       if (reg->callno < 1) {
    09154          ast_log(LOG_WARNING, "Unable to create call for registration\n");
    09155          return -1;
    09156       } else if (option_debug)
    09157          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
    09158       iaxs[reg->callno]->reg = reg;
    09159    }
    09160    /* Schedule the next registration attempt */
    09161    if (reg->expire > -1)
    09162       ast_sched_del(sched, reg->expire);
    09163    /* Setup the next registration a little early */
    09164    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
    09165    /* Send the request */
    09166    memset(&ied, 0, sizeof(ied));
    09167    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
    09168    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
    09169    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
    09170    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
    09171    reg->regstate = REG_STATE_REGSENT;
    09172    return 0;
    09173 }

static int iax2_do_register_s | ( | void * | data | ) | `[static]`

Definition at line 6581 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_ack_registry(), and iax2_do_register().

    06582 {
    06583    struct iax2_registry *reg = data;
    06584    reg->expire = -1;
    06585    iax2_do_register(reg);
    06586    return 0;
    06587 }

static int iax2_do_trunk_debug | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5794 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05795 {
    05796    if (argc != 3)
    05797       return RESULT_SHOWUSAGE;
    05798    iaxtrunkdebug = 1;
    05799    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
    05800    return RESULT_SUCCESS;
    05801 }

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

Definition at line 7239 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_read().

    07240 {
    07241    struct iax_ie_data ied;
    07242    /* Auto-hangup with 30 seconds of inactivity */
    07243    if (iaxs[callno]->autoid > -1)
    07244       ast_sched_del(sched, iaxs[callno]->autoid);
    07245    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
    07246    memset(&ied, 0, sizeof(ied));
    07247    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
    07248    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
    07249    dp->flags |= CACHE_FLAG_TRANSMITTED;
    07250 }

static int iax2_exec | ( | struct ast_channel * | chan,
|  | const char * | context,
|  | const char * | exten,
|  | int | priority,
|  | const char * | callerid,
|  | int | newstack,
|  | const char * | data |
| ) |  |  | `[static]`

Definition at line 10805 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.

    10806 {
    10807    char odata[256];
    10808    char req[256];
    10809    char *ncontext;
    10810    char *dialstatus;
    10811    struct iax2_dpcache *dp;
    10812    struct ast_app *dial;
    10813 #if 0
    10814    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);
    10815 #endif
    10816    if (priority == 2) {
    10817       /* Indicate status, can be overridden in dialplan */
    10818       dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
    10819       if (dialstatus) {
    10820          dial = pbx_findapp(dialstatus);
    10821          if (dial)
    10822             pbx_exec(chan, dial, "", newstack);
    10823       }
    10824       return -1;
    10825    } else if (priority != 1)
    10826       return -1;
    10827    ast_mutex_lock(&dpcache_lock);
    10828    dp = find_cache(chan, data, context, exten, priority);
    10829    if (dp) {
    10830       if (dp->flags & CACHE_FLAG_EXISTS) {
    10831          ast_copy_string(odata, data, sizeof(odata));
    10832          ncontext = strchr(odata, '/');
    10833          if (ncontext) {
    10834             *ncontext = '\0';
    10835             ncontext++;
    10836             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
    10837          } else {
    10838             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
    10839          }
    10840          if (option_verbose > 2)
    10841             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
    10842       } else {
    10843          ast_mutex_unlock(&dpcache_lock);
    10844          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
    10845          return -1;
    10846       }
    10847    }
    10848    ast_mutex_unlock(&dpcache_lock);
    10849    dial = pbx_findapp("Dial");
    10850    if (dial) {
    10851       return pbx_exec(chan, dial, req, newstack);
    10852    } else {
    10853       ast_log(LOG_WARNING, "No dial application registered\n");
    10854    }
    10855    return -1;
    10856 }

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

Definition at line 10736 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

    10737 {
    10738    struct iax2_dpcache *dp;
    10739    int res = 0;
    10740 #if 0
    10741    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
    10742 #endif
    10743    if ((priority != 1) && (priority != 2))
    10744       return 0;
    10745    ast_mutex_lock(&dpcache_lock);
    10746    dp = find_cache(chan, data, context, exten, priority);
    10747    if (dp) {
    10748       if (dp->flags & CACHE_FLAG_EXISTS)
    10749          res= 1;
    10750    }
    10751    ast_mutex_unlock(&dpcache_lock);
    10752    if (!dp) {
    10753       ast_log(LOG_WARNING, "Unable to make DP cache\n");
    10754    }
    10755    return res;
    10756 }

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

Definition at line 3431 of file chan_iax2.c.

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

    03432 {
    03433    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
    03434    ast_mutex_lock(&iaxsl[callno]);
    03435    if (iaxs[callno])
    03436       iaxs[callno]->owner = newchan;
    03437    else
    03438       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
    03439    ast_mutex_unlock(&iaxsl[callno]);
    03440    return 0;
    03441 }

static void iax2_frame_free | ( | struct iax_frame * | fr | ) | `[static]`

Definition at line 1188 of file chan_iax2.c.

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

Referenced by __do_deliver(), attempt_transmit(), complete_transfer(), get_from_jb(), pvt_destructor(), resend_with_token(), and schedule_delivery().

    01189 {
    01190    if (fr->retrans > -1)
    01191       ast_sched_del(sched, fr->retrans);
    01192    iax_frame_free(fr);
    01193 }

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

Definition at line 1027 of file chan_iax2.c.

References iax2_peer::addr, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_peer(), IAX_TEMPONLY, ast_peer_list::lock, iax2_peer::name, iax2_peer::next, peerl, ast_peer_list::peers, and realtime_peer().

Referenced by find_callno().

    01028 {
    01029    struct iax2_peer *peer;
    01030    int res = 0;
    01031
    01032    if (lockpeer)
    01033       ast_mutex_lock(&peerl.lock);
    01034    peer = peerl.peers;
    01035    while (peer) {
    01036       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
    01037             (peer->addr.sin_port == sin.sin_port)) {
    01038                ast_copy_string(host, peer->name, len);
    01039                res = 1;
    01040                break;
    01041       }
    01042       peer = peer->next;
    01043    }
    01044    if (lockpeer)
    01045       ast_mutex_unlock(&peerl.lock);
    01046    if (!peer) {
    01047       peer = realtime_peer(NULL, &sin);
    01048       if (peer) {
    01049          ast_copy_string(host, peer->name, len);
    01050          if (ast_test_flag(peer, IAX_TEMPONLY))
    01051             destroy_peer(peer);
    01052          res = 1;
    01053       }
    01054    }
    01055
    01056    return res;
    01057 }

static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | `[static]`

Definition at line 4597 of file chan_iax2.c.

References iax2_peer::addr, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, IAX_TRUNK, ast_peer_list::lock, iax2_peer::next, peerl, and ast_peer_list::peers.

Referenced by check_access().

    04598 {
    04599    struct iax2_peer *peer;
    04600    int res = 0;
    04601    ast_mutex_lock(&peerl.lock);
    04602    peer = peerl.peers;
    04603    while(peer) {
    04604       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
    04605             (peer->addr.sin_port == sin.sin_port)) {
    04606                res = ast_test_flag(peer, IAX_TRUNK);
    04607                break;
    04608       }
    04609       peer = peer->next;
    04610    }
    04611    ast_mutex_unlock(&peerl.lock);
    04612    return res;
    04613 }

static int iax2_hangup | ( | struct ast_channel * | c | ) | `[static]`

Definition at line 4250 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), iax_ie_data::buf, error(), ast_channel::hangupcause, iax2_destroy_nolock(), iax2_predestroy_nolock(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, LOG_DEBUG, ast_channel::name, option_verbose, iax_ie_data::pos, PTR_TO_CALLNO, send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.

    04251 {
    04252    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
    04253    int alreadygone;
    04254    struct iax_ie_data ied;
    04255    memset(&ied, 0, sizeof(ied));
    04256    ast_mutex_lock(&iaxsl[callno]);
    04257    if (callno && iaxs[callno]) {
    04258       ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
    04259       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
    04260       /* Send the hangup unless we have had a transmission error or are already gone */
    04261       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
    04262       if (!iaxs[callno]->error && !alreadygone)
    04263          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
    04264       /* Explicitly predestroy it */
    04265       iax2_predestroy_nolock(callno);
    04266       /* If we were already gone to begin with, destroy us now */
    04267       if (alreadygone) {
    04268          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
    04269          iax2_destroy_nolock(callno);
    04270       }
    04271    }
    04272    ast_mutex_unlock(&iaxsl[callno]);
    04273    if (option_verbose > 2)
    04274       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
    04275    return 0;
    04276 }

static int iax2_indicate | ( | struct ast_channel * | c,
|  | int | condition |
| ) |  |  | `[static]`

Definition at line 4534 of file chan_iax2.c.

References AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, PTR_TO_CALLNO, send_command(), and ast_channel::tech_pvt.

    04535 {
    04536    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
    04537    struct chan_iax2_pvt *pvt;
    04538    int res;
    04539
    04540    if (option_debug && iaxdebug)
    04541       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
    04542
    04543    ast_mutex_lock(&iaxsl[callno]);
    04544
    04545    pvt = iaxs[callno];
    04546
    04547    if (!pvt->peercallno) {
    04548       /* We don't know the remote side's call number, yet.  :( */
    04549       int count = 10;
    04550       while (count-- && pvt && !pvt->peercallno) {
    04551          ast_mutex_unlock(&iaxsl[callno]);
    04552          usleep(1);
    04553          ast_mutex_lock(&iaxsl[callno]);
    04554          pvt = iaxs[callno];
    04555       }
    04556
    04557       if (!pvt->peercallno) {
    04558          /* Even after waiting, we still haven't completed a handshake with
    04559           * our peer, so we can't send this frame.  Bail out. */
    04560          res = -1;
    04561          goto done;
    04562       }
    04563    }
    04564
    04565
    04566    res = send_command(iaxs[callno], AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
    04567
    04568 done:
    04569    ast_mutex_unlock(&iaxsl[callno]);
    04570
    04571    return res;
    04572 }

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

Definition at line 10782 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.

    10783 {
    10784    int res = 0;
    10785    struct iax2_dpcache *dp;
    10786 #if 0
    10787    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
    10788 #endif
    10789    if ((priority != 1) && (priority != 2))
    10790       return 0;
    10791    ast_mutex_lock(&dpcache_lock);
    10792    dp = find_cache(chan, data, context, exten, priority);
    10793    if (dp) {
    10794       if (dp->flags & CACHE_FLAG_MATCHMORE)
    10795          res= 1;
    10796    }
    10797    ast_mutex_unlock(&dpcache_lock);
    10798    if (!dp) {
    10799       ast_log(LOG_WARNING, "Unable to make DP cache\n");
    10800    }
    10801    return res;
    10802 }

static int iax2_no_debug | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5814 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05815 {
    05816    if (argc != 3)
    05817       return RESULT_SHOWUSAGE;
    05818    iaxdebug = 0;
    05819    ast_cli(fd, "IAX2 Debugging Disabled\n");
    05820    return RESULT_SUCCESS;
    05821 }

static int iax2_no_jb_debug | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5832 of file chan_iax2.c.

References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05833 {
    05834    if (argc != 4)
    05835       return RESULT_SHOWUSAGE;
    05836 #ifdef NEWJB
    05837    jb_setoutput(jb_error_output, jb_warning_output, NULL);
    05838    jb_debug_output("\n");
    05839 #endif
    05840    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
    05841    return RESULT_SUCCESS;
    05842 }

static int iax2_no_trunk_debug | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5823 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05824 {
    05825    if (argc != 4)
    05826       return RESULT_SHOWUSAGE;
    05827    iaxtrunkdebug = 0;
    05828    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
    05829    return RESULT_SUCCESS;
    05830 }

static int iax2_poke_noanswer | ( | void * | data | ) | `[static]`

Definition at line 9296 of file chan_iax2.c.

References ast_device_state_changed(), ast_log(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::name, iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.

Referenced by iax2_poke_peer().

    09297 {
    09298    struct iax2_peer *peer = data;
    09299    peer->pokeexpire = -1;
    09300    if (peer->lastms > -1) {
    09301       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
    09302       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
    09303       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
    09304    }
    09305    if (peer->callno > 0)
    09306       iax2_destroy(peer->callno);
    09307    peer->callno = 0;
    09308    peer->lastms = -1;
    09309    /* Try again quickly */
    09310    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
    09311    return 0;
    09312 }

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

Definition at line 9314 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_add(), ast_sched_del(), iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, send_command(), and iax2_peer::sockfd.

Referenced by iax2_poke_peer_s(), load_module(), reg_source_db(), and update_registry().

    09315 {
    09316    struct iax_ie_data ied = {
    09317       .buf = { 0 },
    09318       .pos = 0,
    09319    };
    09320    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
    09321       /* IF we have no IP, or this isn't to be monitored, return
    09322         imeediately after clearing things out */
    09323       peer->lastms = 0;
    09324       peer->historicms = 0;
    09325       peer->pokeexpire = -1;
    09326       peer->callno = 0;
    09327       return 0;
    09328    }
    09329    if (peer->callno > 0) {
    09330       ast_log(LOG_NOTICE, "Still have a callno...\n");
    09331       iax2_destroy(peer->callno);
    09332    }
    09333    if (heldcall)
    09334       ast_mutex_unlock(&iaxsl[heldcall]);
    09335    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd, 0);
    09336    if (heldcall)
    09337       ast_mutex_lock(&iaxsl[heldcall]);
    09338    if (peer->callno < 1) {
    09339       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
    09340       return -1;
    09341    }
    09342    if (peer->pokeexpire > -1)
    09343       ast_sched_del(sched, peer->pokeexpire);
    09344    /* Speed up retransmission times */
    09345    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
    09346    iaxs[peer->callno]->peerpoke = peer;
    09347
    09348    add_empty_calltoken_ie(iaxs[peer->callno], &ied); /* this _MUST_ be the last ie added */
    09349    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
    09350
    09351    /* If the host is already unreachable then use the unreachable interval instead */
    09352    if (peer->lastms < 0) {
    09353       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
    09354    } else
    09355       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
    09356
    09357    return 0;
    09358 }

static int iax2_poke_peer_s | ( | void * | data | ) | `[static]`

Definition at line 7273 of file chan_iax2.c.

References iax2_poke_peer(), and iax2_peer::pokeexpire.

Referenced by iax2_poke_noanswer(), and socket_read().

    07274 {
    07275    struct iax2_peer *peer = data;
    07276    peer->pokeexpire = -1;
    07277    iax2_poke_peer(peer, 0);
    07278    return 0;
    07279 }

static int iax2_predestroy | ( | int | callno | ) | `[static]`

Definition at line 2484 of file chan_iax2.c.

References ast_channel::_softhangup, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_update_use_count(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_ALREADYGONE, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, ast_user_list::lock, LOG_WARNING, iax2_user::name, iax2_user::next, chan_iax2_pvt::owner, chan_iax2_pvt::pingid, ast_channel::tech_pvt, usecnt_lock, user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by iax2_predestroy_nolock().

    02485 {
    02486    struct ast_channel *c;
    02487    struct chan_iax2_pvt *pvt;
    02488    struct iax2_user *user;
    02489    ast_mutex_lock(&iaxsl[callno]);
    02490    pvt = iaxs[callno];
    02491    if (!pvt) {
    02492       ast_mutex_unlock(&iaxsl[callno]);
    02493       return -1;
    02494    }
    02495    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
    02496       if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
    02497          ast_mutex_lock(&userl.lock);
    02498          user = userl.users;
    02499          while (user) {
    02500             if (!strcmp(user->name, pvt->username)) {
    02501                user->curauthreq--;
    02502                break;
    02503             }
    02504             user = user->next;
    02505          }
    02506          ast_mutex_unlock(&userl.lock);
    02507       }
    02508       /* No more pings or lagrq's */
    02509       if (pvt->pingid > -1)
    02510          ast_sched_del(sched, pvt->pingid);
    02511       if (pvt->lagid > -1)
    02512          ast_sched_del(sched, pvt->lagid);
    02513       if (pvt->autoid > -1)
    02514          ast_sched_del(sched, pvt->autoid);
    02515       if (pvt->authid > -1)
    02516          ast_sched_del(sched, pvt->authid);
    02517       if (pvt->initid > -1)
    02518          ast_sched_del(sched, pvt->initid);
    02519 #ifdef NEWJB
    02520       if (pvt->jbid > -1)
    02521          ast_sched_del(sched, pvt->jbid);
    02522       pvt->jbid = -1;
    02523 #endif
    02524       pvt->pingid = -1;
    02525       pvt->lagid = -1;
    02526       pvt->autoid = -1;
    02527       pvt->initid = -1;
    02528       pvt->authid = -1;
    02529       ast_set_flag(pvt, IAX_ALREADYGONE);
    02530    }
    02531    c = pvt->owner;
    02532    if (c) {
    02533       c->_softhangup |= AST_SOFTHANGUP_DEV;
    02534       c->tech_pvt = NULL;
    02535       ast_queue_hangup(c);
    02536       pvt->owner = NULL;
    02537       ast_mutex_lock(&usecnt_lock);
    02538       usecnt--;
    02539       if (usecnt < 0)
    02540          ast_log(LOG_WARNING, "Usecnt < 0???\n");
    02541       ast_mutex_unlock(&usecnt_lock);
    02542    }
    02543    ast_mutex_unlock(&iaxsl[callno]);
    02544    ast_update_use_count();
    02545    return 0;
    02546 }

static int iax2_predestroy_nolock | ( | int | callno | ) | `[static]`

Definition at line 2548 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), and iax2_predestroy().

Referenced by iax2_hangup(), and send_command_final().

    02549 {
    02550    int res;
    02551    ast_mutex_unlock(&iaxsl[callno]);
    02552    res = iax2_predestroy(callno);
    02553    ast_mutex_lock(&iaxsl[callno]);
    02554    return res;
    02555 }

static int iax2_prov_cmd | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 9274 of file chan_iax2.c.

References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    09275 {
    09276    int force = 0;
    09277    int res;
    09278    if (argc < 4)
    09279       return RESULT_SHOWUSAGE;
    09280    if ((argc > 4)) {
    09281       if (!strcasecmp(argv[4], "forced"))
    09282          force = 1;
    09283       else
    09284          return RESULT_SHOWUSAGE;
    09285    }
    09286    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
    09287    if (res < 0)
    09288       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
    09289    else if (res < 1)
    09290       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
    09291    else
    09292       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
    09293    return RESULT_SUCCESS;
    09294 }

static char* iax2_prov_complete_template_3rd | ( | char * | line,
|  | char * | word,
|  | int | pos,
|  | int | state |
| ) |  |  | `[static]`

Definition at line 9175 of file chan_iax2.c.

References iax_prov_complete_template().

    09176 {
    09177    if (pos != 3)
    09178       return NULL;
    09179    return iax_prov_complete_template(line, word, pos, state);
    09180 }

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

Definition at line 9182 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), LOG_DEBUG, NEW_FORCE, option_debug, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.

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

    09183 {
    09184    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
    09185       is found for template */
    09186    struct iax_ie_data provdata;
    09187    struct iax_ie_data ied;
    09188    unsigned int sig;
    09189    struct sockaddr_in sin;
    09190    int callno;
    09191    struct create_addr_info cai;
    09192
    09193    memset(&cai, 0, sizeof(cai));
    09194
    09195    if (option_debug)
    09196       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
    09197
    09198    if (iax_provision_build(&provdata, &sig, template, force)) {
    09199       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
    09200       return 0;
    09201    }
    09202
    09203    if (end) {
    09204       memcpy(&sin, end, sizeof(sin));
    09205       cai.sockfd = sockfd;
    09206    } else if (create_addr(dest, &sin, &cai))
    09207       return -1;
    09208
    09209    /* Build the rest of the message */
    09210    memset(&ied, 0, sizeof(ied));
    09211    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
    09212
    09213    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd, 0);
    09214    if (!callno)
    09215       return -1;
    09216
    09217    ast_mutex_lock(&iaxsl[callno]);
    09218    if (iaxs[callno]) {
    09219       /* Schedule autodestruct in case they don't ever give us anything back */
    09220       if (iaxs[callno]->autoid > -1)
    09221          ast_sched_del(sched, iaxs[callno]->autoid);
    09222       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
    09223       ast_set_flag(iaxs[callno], IAX_PROVISION);
    09224       /* Got a call number now, so go ahead and send the provisioning information */
    09225       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
    09226    }
    09227    ast_mutex_unlock(&iaxsl[callno]);
    09228
    09229    return 1;
    09230 }

static int iax2_prune_realtime | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 2704 of file chan_iax2.c.

References ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, reload_config(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    02705 {
    02706    struct iax2_peer *peer;
    02707
    02708    if (argc != 4)
    02709         return RESULT_SHOWUSAGE;
    02710    if (!strcmp(argv[3],"all")) {
    02711       reload_config();
    02712       ast_cli(fd, "OK cache is flushed.\n");
    02713    } else if ((peer = find_peer(argv[3], 0))) {
    02714       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
    02715          ast_set_flag(peer, IAX_RTAUTOCLEAR);
    02716          expire_registry(peer);
    02717          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
    02718       } else {
    02719          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
    02720       }
    02721    } else {
    02722       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
    02723    }
    02724
    02725    return RESULT_SUCCESS;
    02726 }

static int iax2_queue_frame | ( | int | callno,
|  | struct ast_frame * | f |
| ) |  |  | `[static]`

Definition at line 2084 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), and ast_queue_frame().

Referenced by __do_deliver(), attempt_transmit(), auto_congest(), get_from_jb(), and socket_read().

    02085 {
    02086    /* Assumes lock for callno is already held... */
    02087    for (;;) {
    02088       if (iaxs[callno] && iaxs[callno]->owner) {
    02089          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
    02090             /* Avoid deadlock by pausing and trying again */
    02091             ast_mutex_unlock(&iaxsl[callno]);
    02092             usleep(1);
    02093             ast_mutex_lock(&iaxsl[callno]);
    02094          } else {
    02095             ast_queue_frame(iaxs[callno]->owner, f);
    02096             ast_mutex_unlock(&iaxs[callno]->owner->lock);
    02097             break;
    02098          }
    02099       } else
    02100          break;
    02101    }
    02102    return 0;
    02103 }

static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | `[static, read]`

Definition at line 4307 of file chan_iax2.c.

References AST_FRAME_NULL, ast_log(), and LOG_NOTICE.

    04308 {
    04309    static struct ast_frame null_frame = {
    04310       AST_FRAME_NULL,
    04311    };
    04312
    04313    ast_log(LOG_NOTICE, "I should never be called!\n");
    04314    return &null_frame;
    04315 }

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

Definition at line 6811 of file chan_iax2.c.

References iax2_registry::addr, ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, copy(), iax2_registry::expire, hostname, hp, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_ERROR, LOG_WARNING, malloc, iax2_registry::next, iax2_registry::refresh, iax2_registry::secret, secret, strsep(), and iax2_registry::username.

Referenced by set_config().

    06812 {
    06813    struct iax2_registry *reg;
    06814    char copy[256];
    06815    char *username, *hostname, *secret;
    06816    char *porta;
    06817    char *stringp=NULL;
    06818
    06819    struct ast_hostent ahp; struct hostent *hp;
    06820    if (!value)
    06821       return -1;
    06822    ast_copy_string(copy, value, sizeof(copy));
    06823    stringp=copy;
    06824    username = strsep(&stringp, "@");
    06825    hostname = strsep(&stringp, "@");
    06826    if (!hostname) {
    06827       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
    06828       return -1;
    06829    }
    06830    stringp=username;
    06831    username = strsep(&stringp, ":");
    06832    secret = strsep(&stringp, ":");
    06833    stringp=hostname;
    06834    hostname = strsep(&stringp, ":");
    06835    porta = strsep(&stringp, ":");
    06836
    06837    if (porta && !atoi(porta)) {
    06838       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
    06839       return -1;
    06840    }
    06841    hp = ast_gethostbyname(hostname, &ahp);
    06842    if (!hp) {
    06843       ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
    06844       return -1;
    06845    }
    06846    reg = malloc(sizeof(struct iax2_registry));
    06847    if (reg) {
    06848       memset(reg, 0, sizeof(struct iax2_registry));
    06849       ast_copy_string(reg->username, username, sizeof(reg->username));
    06850       if (secret)
    06851          ast_copy_string(reg->secret, secret, sizeof(reg->secret));
    06852       reg->expire = -1;
    06853       reg->refresh = IAX_DEFAULT_REG_EXPIRE;
    06854       reg->addr.sin_family = AF_INET;
    06855       memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
    06856       reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
    06857       ast_mutex_lock(&reg_lock);
    06858       reg->next = registrations;
    06859       reg->callno = 0;
    06860       registrations = reg;
    06861       ast_mutex_unlock(&reg_lock);
    06862    } else {
    06863       ast_log(LOG_ERROR, "Out of memory\n");
    06864       return -1;
    06865    }
    06866    return 0;
    06867 }

static int iax2_reload | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 10507 of file chan_iax2.c.

References reload_config().

    10508 {
    10509    return reload_config();
    10510 }

static struct ast_channel * iax2_request | ( | const char * | type,
|  | int | format,
|  | void * | data,
|  | int * | cause |
| ) |  |  | `[static, read]`

Definition at line 9370 of file chan_iax2.c.

References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_test_flag, ast_translator_best_choice(), create_addr_info::capability, create_addr(), find_callno(), fmt, create_addr_info::found, chan_iax2_pvt::host, host, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.

    09371 {
    09372    int callno;
    09373    int res;
    09374    int fmt, native;
    09375    struct sockaddr_in sin;
    09376    struct ast_channel *c;
    09377    struct parsed_dial_string pds;
    09378    struct create_addr_info cai;
    09379    char *tmpstr;
    09380
    09381    memset(&pds, 0, sizeof(pds));
    09382    tmpstr = ast_strdupa(data);
    09383    parse_dial_string(tmpstr, &pds);
    09384
    09385    memset(&cai, 0, sizeof(cai));
    09386    cai.capability = iax2_capability;
    09387
    09388    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
    09389
    09390    if (!pds.peer) {
    09391       ast_log(LOG_WARNING, "No peer given\n");
    09392       return NULL;
    09393    }
    09394
    09395
    09396    /* Populate our address from the given */
    09397    if (create_addr(pds.peer, &sin, &cai)) {
    09398       *cause = AST_CAUSE_UNREGISTERED;
    09399       return NULL;
    09400    }
    09401
    09402    if (pds.port)
    09403       sin.sin_port = htons(atoi(pds.port));
    09404
    09405    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd, 0);
    09406    if (callno < 1) {
    09407       ast_log(LOG_WARNING, "Unable to create call\n");
    09408       *cause = AST_CAUSE_CONGESTION;
    09409       return NULL;
    09410    }
    09411
    09412    ast_mutex_lock(&iaxsl[callno]);
    09413
    09414    /* If this is a trunk, update it now */
    09415    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
    09416    if (ast_test_flag(&cai, IAX_TRUNK)) {
    09417       int new_callno;
    09418       if ((new_callno = make_trunk(callno, 1)) != -1)
    09419          callno = new_callno;
    09420    }
    09421    iaxs[callno]->maxtime = cai.maxtime;
    09422    if (cai.found)
    09423       ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host));
    09424
    09425    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
    09426
    09427    ast_mutex_unlock(&iaxsl[callno]);
    09428
    09429    if (c) {
    09430       /* Choose a format we can live with */
    09431       if (c->nativeformats & format)
    09432          c->nativeformats &= format;
    09433       else {
    09434          native = c->nativeformats;
    09435          fmt = format;
    09436          res = ast_translator_best_choice(&fmt, &native);
    09437          if (res < 0) {
    09438             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
    09439                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
    09440             ast_hangup(c);
    09441             return NULL;
    09442          }
    09443          c->nativeformats = native;
    09444       }
    09445       c->readformat = ast_best_codec(c->nativeformats);
    09446       c->writeformat = c->readformat;
    09447    }
    09448
    09449    return c;
    09450 }

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

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, chan_iax2_pvt::ecx, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, 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, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, chan_iax2_pvt::transfercallno, 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(), and socket_read().

    05175 {
    05176    /* Queue a packet for delivery on a given private structure.  Use "ts" for
    05177       timestamp, or calculate if ts is 0.  Send immediately without retransmission
    05178       or delayed, with retransmission */
    05179    struct ast_iax2_full_hdr *fh;
    05180    struct ast_iax2_mini_hdr *mh;
    05181    struct ast_iax2_video_hdr *vh;
    05182    struct {
    05183       struct iax_frame fr2;
    05184       unsigned char buffer[4096];
    05185    } frb;
    05186    struct iax_frame *fr;
    05187    int res;
    05188    int sendmini=0;
    05189    unsigned int lastsent;
    05190    unsigned int fts;
    05191
    05192    frb.fr2.afdatalen = sizeof(frb.buffer);
    05193
    05194    if (!pvt) {
    05195       ast_log(LOG_WARNING, "No private structure for packet?\n");
    05196       return -1;
    05197    }
    05198
    05199    lastsent = pvt->lastsent;
    05200
    05201    /* Calculate actual timestamp */
    05202    fts = calc_timestamp(pvt, ts, f);
    05203
    05204    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
    05205     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
    05206     * increment the "predicted timestamps" for voice, if we're predecting */
    05207    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
    05208        return 0;
    05209
    05210
    05211    if ((ast_test_flag(pvt, IAX_TRUNK) || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)))
    05212       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
    05213        (f->frametype == AST_FRAME_VOICE)
    05214       /* is a voice frame */ &&
    05215       (f->subclass == pvt->svoiceformat)
    05216       /* is the same type */ ) {
    05217          /* Force immediate rather than delayed transmission */
    05218          now = 1;
    05219          /* Mark that mini-style frame is appropriate */
    05220          sendmini = 1;
    05221    }
    05222    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) &&
    05223       (f->frametype == AST_FRAME_VIDEO) &&
    05224       ((f->subclass & ~0x1) == pvt->svideoformat)) {
    05225          now = 1;
    05226          sendmini = 1;
    05227    }
    05228    /* Allocate an iax_frame */
    05229    if (now) {
    05230       fr = &frb.fr2;
    05231    } else
    05232       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen);
    05233    if (!fr) {
    05234       ast_log(LOG_WARNING, "Out of memory\n");
    05235       return -1;
    05236    }
    05237    /* Copy our prospective frame into our immediate or retransmitted wrapper */
    05238    iax_frame_wrap(fr, f);
    05239
    05240    fr->ts = fts;
    05241    fr->callno = pvt->callno;
    05242    fr->transfer = transfer;
    05243    fr->final = final;
    05244    if (!sendmini) {
    05245       /* We need a full frame */
    05246       if (seqno > -1)
    05247          fr->oseqno = seqno;
    05248       else
    05249          fr->oseqno = pvt->oseqno++;
    05250       fr->iseqno = pvt->iseqno;
    05251       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
    05252       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
    05253       fh->ts = htonl(fr->ts);
    05254       fh->oseqno = fr->oseqno;
    05255       if (transfer) {
    05256          fh->iseqno = 0;
    05257       } else
    05258          fh->iseqno = fr->iseqno;
    05259       /* Keep track of the last thing we've acknowledged */
    05260       if (!transfer)
    05261          pvt->aseqno = fr->iseqno;
    05262       fh->type = fr->af.frametype & 0xFF;
    05263       if (fr->af.frametype == AST_FRAME_VIDEO)
    05264          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
    05265       else
    05266          fh->csub = compress_subclass(fr->af.subclass);
    05267       if (transfer) {
    05268          fr->dcallno = pvt->transfercallno;
    05269       } else
    05270          fr->dcallno = pvt->peercallno;
    05271       fh->dcallno = htons(fr->dcallno);
    05272       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
    05273       fr->data = fh;
    05274       fr->retries = 0;
    05275       /* Retry after 2x the ping time has passed */
    05276       fr->retrytime = pvt->pingtime * 2;
    05277       if (fr->retrytime < MIN_RETRY_TIME)
    05278          fr->retrytime = MIN_RETRY_TIME;
    05279       if (fr->retrytime > MAX_RETRY_TIME)
    05280          fr->retrytime = MAX_RETRY_TIME;
    05281       /* Acks' don't get retried */
    05282       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
    05283          fr->retries = -1;
    05284       else if (f->frametype == AST_FRAME_VOICE)
    05285          pvt->svoiceformat = f->subclass;
    05286       else if (f->frametype == AST_FRAME_VIDEO)
    05287          pvt->svideoformat = f->subclass & ~0x1;
    05288       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
    05289          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
    05290             if (iaxdebug) {
    05291                if (fr->transfer)
    05292                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
    05293                else
    05294                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
    05295             }
    05296             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
    05297          } else
    05298             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
    05299       }
    05300
    05301       if (now) {
    05302          res = send_packet(fr);
    05303       } else
    05304          res = iax2_transmit(fr);
    05305    } else {
    05306       if (ast_test_flag(pvt, IAX_TRUNK)) {
    05307          iax2_trunk_queue(pvt, fr);
    05308          res = 0;
    05309       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
    05310          /* Video frame have no sequence number */
    05311          fr->oseqno = -1;
    05312          fr->iseqno = -1;
    05313          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
    05314          vh->zeros = 0;
    05315          vh->callno = htons(0x8000 | fr->callno);
    05316          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
    05317          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
    05318          fr->data = vh;
    05319          fr->retries = -1;
    05320          res = send_packet(fr);
    05321       } else {
    05322          /* Mini-frames have no sequence number */
    05323          fr->oseqno = -1;
    05324          fr->iseqno = -1;
    05325          /* Mini frame will do */
    05326          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
    05327          mh->callno = htons(fr->callno);
    05328          mh->ts = htons(fr->ts & 0xFFFF);
    05329          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
    05330          fr->data = mh;
    05331          fr->retries = -1;
    05332          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
    05333             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
    05334                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
    05335             } else
    05336                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
    05337          }
    05338          res = send_packet(fr);
    05339       }
    05340    }
    05341    return res;
    05342 }

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

Definition at line 3426 of file chan_iax2.c.

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

    03427 {
    03428    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
    03429 }

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

Definition at line 3421 of file chan_iax2.c.

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

    03422 {
    03423    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
    03424 }

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

Definition at line 3414 of file chan_iax2.c.

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

    03415 {
    03416
    03417    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
    03418       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
    03419 }

static int iax2_set_jitter | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 2668 of file chan_iax2.c.

References ast_cli(), IAX_MAX_CALLS, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    02669 {
    02670 #ifdef NEWJB
    02671    ast_cli(fd, "sorry, this command is deprecated\n");
    02672    return RESULT_SUCCESS;
    02673 #else
    02674    if ((argc != 4) && (argc != 5))
    02675       return RESULT_SHOWUSAGE;
    02676    if (argc == 4) {
    02677       max_jitter_buffer = atoi(argv[3]);
    02678       if (max_jitter_buffer < 0)
    02679          max_jitter_buffer = 0;
    02680    } else {
    02681       if (argc == 5) {
    02682          if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < IAX_MAX_CALLS)) {
    02683             if (iaxs[atoi(argv[3])]) {
    02684                iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]);
    02685                if (iaxs[atoi(argv[3])]->jitterbuffer < 0)
    02686                   iaxs[atoi(argv[3])]->jitterbuffer = 0;
    02687             } else
    02688                ast_cli(fd, "No such call '%d'\n", atoi(argv[3]));
    02689          } else
    02690             ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3]));
    02691       }
    02692    }
    02693    return RESULT_SUCCESS;
    02694 #endif
    02695 }

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

Definition at line 4278 of file chan_iax2.c.

References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_log(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_option_header::data, ast_option_header::flag, free, LOG_WARNING, malloc, ast_option_header::option, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

    04279 {
    04280    struct ast_option_header *h;
    04281    int res;
    04282
    04283    switch (option) {
    04284    case AST_OPTION_TXGAIN:
    04285    case AST_OPTION_RXGAIN:
    04286       /* these two cannot be sent, because they require a result */
    04287       errno = ENOSYS;
    04288       return -1;
    04289    default:
    04290       h = malloc(datalen + sizeof(*h));
    04291       if (h) {
    04292          h->flag = AST_OPTION_FLAG_REQUEST;
    04293          h->option = htons(option);
    04294          memcpy(h->data, data, datalen);
    04295          res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
    04296                     AST_CONTROL_OPTION, 0, (unsigned char *) h,
    04297                     datalen + sizeof(*h), -1);
    04298          free(h);
    04299          return res;
    04300       } else {
    04301          ast_log(LOG_WARNING, "Out of memory\n");
    04302          return -1;
    04303       }
    04304    }
    04305 }

static int iax2_show_cache | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 2903 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, dpcache, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.

    02904 {
    02905    struct iax2_dpcache *dp;
    02906    char tmp[1024], *pc;
    02907    int s;
    02908    int x,y;
    02909    struct timeval tv;
    02910    gettimeofday(&tv, NULL);
    02911    ast_mutex_lock(&dpcache_lock);
    02912    dp = dpcache;
    02913    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
    02914    while(dp) {
    02915       s = dp->expiry.tv_sec - tv.tv_sec;
    02916       tmp[0] = '\0';
    02917       if (dp->flags & CACHE_FLAG_EXISTS)
    02918          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
    02919       if (dp->flags & CACHE_FLAG_NONEXISTENT)
    02920          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
    02921       if (dp->flags & CACHE_FLAG_CANEXIST)
    02922          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
    02923       if (dp->flags & CACHE_FLAG_PENDING)
    02924          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
    02925       if (dp->flags & CACHE_FLAG_TIMEOUT)
    02926          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
    02927       if (dp->flags & CACHE_FLAG_TRANSMITTED)
    02928          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
    02929       if (dp->flags & CACHE_FLAG_MATCHMORE)
    02930          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
    02931       if (dp->flags & CACHE_FLAG_UNKNOWN)
    02932          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
    02933       /* Trim trailing pipe */
    02934       if (!ast_strlen_zero(tmp))
    02935          tmp[strlen(tmp) - 1] = '\0';
    02936       else
    02937          ast_copy_string(tmp, "(none)", sizeof(tmp));
    02938       y=0;
    02939       pc = strchr(dp->peercontext, '@');
    02940       if (!pc)
    02941          pc = dp->peercontext;
    02942       else
    02943          pc++;
    02944       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
    02945          if (dp->waiters[x] > -1)
    02946             y++;
    02947       if (s > 0)
    02948          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
    02949       else
    02950          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
    02951       dp = dp->next;
    02952    }
    02953    ast_mutex_unlock(&dpcache_lock);
    02954    return RESULT_SUCCESS;
    02955 }

static int iax2_show_callnumber_usage | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 1780 of file chan_iax2.c.

References peercnt::addr, ao2_iterator_init(), ao2_iterator_next(), ao2_ref(), ast_cli(), ast_inet_ntoa(), peercnt::cur, peercnt::limit, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    01781 {
    01782    struct ao2_iterator i;
    01783    struct peercnt *peercnt;
    01784    struct sockaddr_in sin;
    01785    int found = 0;
    01786    char iabuf[INET_ADDRSTRLEN];
    01787
    01788    if (argc < 4 || argc > 5)
    01789       return RESULT_SHOWUSAGE;
    01790
    01791    ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
    01792    i = ao2_iterator_init(peercnts, 0);
    01793    while ((peercnt = ao2_iterator_next(&i))) {
    01794       sin.sin_addr.s_addr = peercnt->addr;
    01795       if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr)))) {
    01796             ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), peercnt->cur, peercnt->limit);
    01797             found = 1;
    01798             break;
    01799       } else {
    01800          ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), peercnt->cur, peercnt->limit);
    01801       }
    01802       ao2_ref(peercnt, -1);
    01803    }
    01804    if (argc == 4) {
    01805       ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
    01806    } else if (argc == 5 && !found) {
    01807       ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] );
    01808    }
    01809    return RESULT_SUCCESS;
    01810 }

static int iax2_show_channels | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5627 of file chan_iax2.c.

References iax2_registry::addr, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, FORMATB, IAX_MAX_CALLS, IAX_USEJITTERBUF, jb_getinfo(), jb_info::jitter, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05628 {
    05629 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
    05630 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s\n"
    05631 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
    05632    int x;
    05633    int numchans = 0;
    05634    char iabuf[INET_ADDRSTRLEN];
    05635
    05636    if (argc != 3)
    05637       return RESULT_SHOWUSAGE;
    05638    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
    05639    for (x=0;x<IAX_MAX_CALLS;x++) {
    05640       ast_mutex_lock(&iaxsl[x]);
    05641       if (iaxs[x]) {
    05642 #ifdef BRIDGE_OPTIMIZATION
    05643          if (iaxs[x]->bridgecallno)
    05644             ast_cli(fd, FORMATB,
    05645                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
    05646                   ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr),
    05647                   !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)",
    05648                   iaxs[x]->callno, iaxs[x]->peercallno,
    05649                   iaxs[x]->oseqno, iaxs[x]->iseqno,
    05650                   iaxs[x]->bridgecallno );
    05651          else
    05652 #endif
    05653          {
    05654             int lag, jitter, localdelay;
    05655 #ifdef NEWJB
    05656             jb_info jbinfo;
    05657
    05658             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
    05659                jb_getinfo(iaxs[x]->jb, &jbinfo);
    05660                jitter = jbinfo.jitter;
    05661                localdelay = jbinfo.current - jbinfo.min;
    05662             } else {
    05663                jitter = -1;
    05664                localdelay = 0;
    05665             }
    05666 #else
    05667             jitter = iaxs[x]->jitter;
    05668             localdelay = ast_test_flag(iaxs[x], IAX_USEJITTERBUF) ? jitterbufsize(iaxs[x]) : 0;
    05669 #endif
    05670             lag = iaxs[x]->remote_rr.delay;
    05671             ast_cli(fd, FORMAT,
    05672                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
    05673                   ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr),
    05674                   !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)",
    05675                   iaxs[x]->callno, iaxs[x]->peercallno,
    05676                   iaxs[x]->oseqno, iaxs[x]->iseqno,
    05677                   lag,
    05678                   jitter,
    05679                   localdelay,
    05680                   ast_getformatname(iaxs[x]->voiceformat) );
    05681          }
    05682          numchans++;
    05683       }
    05684       ast_mutex_unlock(&iaxsl[x]);
    05685    }
    05686    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
    05687    return RESULT_SUCCESS;
    05688 #undef FORMAT
    05689 #undef FORMAT2
    05690 #undef FORMATB
    05691 }

static int iax2_show_firmware | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5524 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, FORMAT, FORMAT2, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.

    05525 {
    05526 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
    05527 #if !defined(__FreeBSD__)
    05528 #define FORMAT "%-15.15s  %-15d %-15d\n"
    05529 #else /* __FreeBSD__ */
    05530 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
    05531 #endif /* __FreeBSD__ */
    05532    struct iax_firmware *cur;
    05533    if ((argc != 3) && (argc != 4))
    05534       return RESULT_SHOWUSAGE;
    05535    ast_mutex_lock(&waresl.lock);
    05536
    05537    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
    05538    for (cur = waresl.wares;cur;cur = cur->next) {
    05539       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
    05540          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
    05541             (int)ntohl(cur->fwh->datalen));
    05542    }
    05543    ast_mutex_unlock(&waresl.lock);
    05544    return RESULT_SUCCESS;
    05545 #undef FORMAT
    05546 #undef FORMAT2
    05547 }

static int iax2_show_netstats | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5773 of file chan_iax2.c.

References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    05774 {
    05775    int numchans = 0;
    05776    if (argc != 3)
    05777       return RESULT_SHOWUSAGE;
    05778    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
    05779    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
    05780    numchans = ast_cli_netstats(fd, 1);
    05781    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
    05782    return RESULT_SUCCESS;
    05783 }

static int iax2_show_peer | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 2797 of file chan_iax2.c.

References iax2_peer::addr, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::defaddr, destroy_peer(), iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TEMPONLY, iax2_peer::mailbox, iax2_peer::maxcallno, iax2_peer::name, peer_status(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.

    02798 {
    02799    char status[30];
    02800    char cbuf[256];
    02801    char iabuf[INET_ADDRSTRLEN];
    02802    struct iax2_peer *peer;
    02803    char codec_buf[512];
    02804    int x = 0, codec = 0, load_realtime = 0;
    02805
    02806    if (argc < 4)
    02807       return RESULT_SHOWUSAGE;
    02808
    02809    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
    02810
    02811    peer = find_peer(argv[3], load_realtime);
    02812    if (peer) {
    02813       ast_cli(fd,"\n\n");
    02814       ast_cli(fd, "  * Name       : %s\n", peer->name);
    02815       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
    02816       ast_cli(fd, "  Context      : %s\n", peer->context);
    02817       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
    02818       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
    02819       ast_cli(fd, "  Callnum limit: %d\n", peer->maxcallno);
    02820       ast_cli(fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
    02821       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
    02822       ast_cli(fd, "  Expire       : %d\n", peer->expire);
    02823       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
    02824       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
    02825       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
    02826       ast_cli(fd, "  Username     : %s\n", peer->username);
    02827       ast_cli(fd, "  Codecs       : ");
    02828       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
    02829       ast_cli(fd, "%s\n", codec_buf);
    02830
    02831       ast_cli(fd, "  Codec Order  : (");
    02832       for(x = 0; x < 32 ; x++) {
    02833          codec = ast_codec_pref_index(&peer->prefs,x);
    02834          if(!codec)
    02835             break;
    02836          ast_cli(fd, "%s", ast_getformatname(codec));
    02837          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
    02838             ast_cli(fd, "|");
    02839       }
    02840
    02841       if (!x)
    02842          ast_cli(fd, "none");
    02843       ast_cli(fd, ")\n");
    02844
    02845       ast_cli(fd, "  Status       : ");
    02846       peer_status(peer, status, sizeof(status));
    02847       ast_cli(fd, "%s\n",status);
    02848       ast_cli(fd, " Qualify        : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
    02849       ast_cli(fd,"\n");
    02850       if (ast_test_flag(peer, IAX_TEMPONLY))
    02851          destroy_peer(peer);
    02852    } else {
    02853       ast_cli(fd,"Peer %s not found.\n", argv[3]);
    02854       ast_cli(fd,"\n");
    02855    }
    02856
    02857    return RESULT_SUCCESS;
    02858 }

static int iax2_show_peers | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5513 of file chan_iax2.c.

References __iax2_show_peers().

    05514 {
    05515    return __iax2_show_peers(0, fd, argc, argv);
    05516 }

static int iax2_show_registry | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5585 of file chan_iax2.c.

References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), FORMAT, FORMAT2, host, iax2_registry::next, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.

    05586 {
    05587 #define FORMAT2 "%-20.20s  %-10.10s  %-20.20s %8.8s  %s\n"
    05588 #define FORMAT "%-20.20s  %-10.10s  %-20.20s %8d  %s\n"
    05589    struct iax2_registry *reg;
    05590    char host[80];
    05591    char perceived[80];
    05592    char iabuf[INET_ADDRSTRLEN];
    05593    if (argc != 3)
    05594       return RESULT_SHOWUSAGE;
    05595    ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
    05596    ast_mutex_lock(&reg_lock);
    05597    for (reg = registrations;reg;reg = reg->next) {
    05598       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
    05599       if (reg->us.sin_addr.s_addr)
    05600          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
    05601       else
    05602          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
    05603       ast_cli(fd, FORMAT, host,
    05604                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
    05605    }
    05606    ast_mutex_unlock(&reg_lock);
    05607    return RESULT_SUCCESS;
    05608 #undef FORMAT
    05609 #undef FORMAT2
    05610 }

static int iax2_show_stats | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 2883 of file chan_iax2.c.

References ast_cli(), iax_frame::final, ast_iax2_queue::head, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, iax_frame::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.

    02884 {
    02885    struct iax_frame *cur;
    02886    int cnt = 0, dead=0, final=0;
    02887    if (argc != 3)
    02888       return RESULT_SHOWUSAGE;
    02889    for (cur = iaxq.head; cur ; cur = cur->next) {
    02890       if (cur->retries < 0)
    02891          dead++;
    02892       if (cur->final)
    02893          final++;
    02894       cnt++;
    02895    }
    02896    ast_cli(fd, "    IAX Statistics\n");
    02897    ast_cli(fd, "---------------------\n");
    02898    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
    02899    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
    02900    return RESULT_SUCCESS;
    02901 }

static int iax2_show_users | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 5346 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, ast_user_list::lock, iax2_user::name, iax2_user::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_user::secret, user, userl, and ast_user_list::users.

    05347 {
    05348    regex_t regexbuf;
    05349    int havepattern = 0;
    05350
    05351 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
    05352 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
    05353
    05354    struct iax2_user *user;
    05355    char auth[90];
    05356    char *pstr = "";
    05357
    05358    switch (argc) {
    05359    case 5:
    05360       if (!strcasecmp(argv[3], "like")) {
    05361          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
    05362             return RESULT_SHOWUSAGE;
    05363          havepattern = 1;
    05364       } else
    05365          return RESULT_SHOWUSAGE;
    05366    case 3:
    05367       break;
    05368    default:
    05369       return RESULT_SHOWUSAGE;
    05370    }
    05371
    05372    ast_mutex_lock(&userl.lock);
    05373    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
    05374    for(user=userl.users;user;user=user->next) {
    05375       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
    05376          continue;
    05377
    05378       if (!ast_strlen_zero(user->secret)) {
    05379          ast_copy_string(auth,user->secret,sizeof(auth));
    05380       } else if (!ast_strlen_zero(user->inkeys)) {
    05381          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
    05382       } else
    05383          ast_copy_string(auth, "-no secret-", sizeof(auth));
    05384
    05385       if(ast_test_flag(user,IAX_CODEC_NOCAP))
    05386          pstr = "REQ Only";
    05387       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
    05388          pstr = "Disabled";
    05389       else
    05390          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
    05391
    05392       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
    05393             user->contexts ? user->contexts->context : context,
    05394             user->ha ? "Yes" : "No", pstr);
    05395
    05396    }
    05397    ast_mutex_unlock(&userl.lock);
    05398
    05399    if (havepattern)
    05400       regfree(&regexbuf);
    05401
    05402    return RESULT_SUCCESS;
    05403 #undef FORMAT
    05404 #undef FORMAT2
    05405 }

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

Definition at line 4317 of file chan_iax2.c.

References AST_FRAME_IAX, iax_ie_data::buf, 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_ie_data::pos, send_command(), TRANSFER_BEGIN, and chan_iax2_pvt::transferring.

Referenced by iax2_bridge().

    04318 {
    04319    int res;
    04320    struct iax_ie_data ied0;
    04321    struct iax_ie_data ied1;
    04322    unsigned int transferid = rand();
    04323    memset(&ied0, 0, sizeof(ied0));
    04324    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
    04325    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
    04326    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
    04327
    04328    memset(&ied1, 0, sizeof(ied1));
    04329    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
    04330    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
    04331    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
    04332
    04333    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
    04334    if (res)
    04335       return -1;
    04336    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
    04337    if (res)
    04338       return -1;
    04339    iaxs[callno0]->transferring = TRANSFER_BEGIN;
    04340    iaxs[callno1]->transferring = TRANSFER_BEGIN;
    04341    return 0;
    04342 }

static int iax2_test_losspct | ( | int | fd,
|  | int | argc,
|  | char * | argv[] |
| ) |  |  | `[static]`

Definition at line 2728 of file chan_iax2.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

    02729 {
    02730        if (argc != 4)
    02731                return RESULT_SHOWUSAGE;
    02732
    02733        test_losspct = atoi(argv[3]);
    02734
    02735        return RESULT_SUCCESS;
    02736 }

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

Definition at line 4574 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), iax_ie_data::buf, chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, LOG_DEBUG, ast_channel::name, option_debug, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

    04575 {
    04576    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
    04577    struct iax_ie_data ied;
    04578    char tmp[256], *context;
    04579    ast_copy_string(tmp, dest, sizeof(tmp));
    04580    context = strchr(tmp, '@');
    04581    if (context) {
    04582       *context = '\0';
    04583       context++;
    04584    }
    04585    memset(&ied, 0, sizeof(ied));
    04586    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
    04587    if (context)
    04588       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
    04589    if (option_debug)
    04590       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
    04591    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
    04592 }

static int iax2_transmit | ( | struct iax_frame * | fr | ) | `[static]`

Definition at line 3380 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, ast_iax2_queue::count, ast_iax2_queue::head, iaxq, ast_iax2_queue::lock, iax_frame::next, iax_frame::prev, iax_frame::sentyet, and ast_iax2_queue::tail.

Referenced by iax2_send().

    03381 {
    03382    /* Lock the queue and place this packet at the end */
    03383    fr->next = NULL;
    03384    fr->prev = NULL;
    03385    /* By setting this to 0, the network thread will send it for us, and
    03386       queue retransmission if necessary */
    03387    fr->sentyet = 0;
    03388    ast_mutex_lock(&iaxq.lock);
    03389    if (!iaxq.head) {
    03390       /* Empty queue */
    03391       iaxq.head = fr;
    03392       iaxq.tail = fr;
    03393    } else {
    03394       /* Double link */
    03395       iaxq.tail->next = fr;
    03396       fr->prev = iaxq.tail;
    03397       iaxq.tail = fr;
    03398    }
    03399    iaxq.count++;
    03400    ast_mutex_unlock(&iaxq.lock);
    03401    /* Wake up the network thread */
    03402    if (netthreadid != AST_PTHREADT_NULL)
    03403       pthread_kill(netthreadid, SIGURG);
    03404    return 0;
    03405 }

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

Definition at line 7324 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

    07325 {
    07326    /* Drop when trunk is about 5 seconds idle */
    07327    if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
    07328       return 1;
    07329    return 0;
    07330 }

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

Definition at line 4946 of file chan_iax2.c.

References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_DEBUG, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, realloc, 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().

    04947 {
    04948    struct ast_frame *f;
    04949    struct iax2_trunk_peer *tpeer;
    04950    void *tmp, *ptr;
    04951    struct ast_iax2_meta_trunk_entry *met;
    04952    struct ast_iax2_meta_trunk_mini *mtm;
    04953    char iabuf[INET_ADDRSTRLEN];
    04954
    04955    f = &fr->af;
    04956    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
    04957    if (tpeer) {
    04958       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
    04959          /* Need to reallocate space */
    04960          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
    04961             tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE);
    04962             if (tmp) {
    04963                tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
    04964                tpeer->trunkdata = tmp;
    04965                ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
    04966             } else {
    04967                ast_log(LOG_WARNING, "Insufficient memory to expand trunk data to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
    04968                ast_mutex_unlock(&tpeer->lock);
    04969                return -1;
    04970             }
    04971          } else {
    04972             ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
    04973             ast_mutex_unlock(&tpeer->lock);
    04974             return -1;
    04975          }
    04976       }
    04977
    04978       /* Append to meta frame */
    04979       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
    04980       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
    04981          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
    04982          mtm->len = htons(f->datalen);
    04983          mtm->mini.callno = htons(pvt->callno);
    04984          mtm->mini.ts = htons(0xffff & fr->ts);
    04985          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
    04986          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
    04987       } else {
    04988          met = (struct ast_iax2_meta_trunk_entry *)ptr;
    04989          /* Store call number and length in meta header */
    04990          met->callno = htons(pvt->callno);
    04991          met->len = htons(f->datalen);
    04992          /* Advance pointers/decrease length past trunk entry header */
    04993          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
    04994          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
    04995       }
    04996       /* Copy actual trunk data */
    04997       memcpy(ptr, f->data, f->datalen);
    04998       tpeer->trunkdatalen += f->datalen;
    04999
    05000       tpeer->calls++;
    05001       ast_mutex_unlock(&tpeer->lock);
    05002    }
    05003    return 0;
    05004 }

static int iax2_vnak | ( | int | callno | ) | `[static]`

Definition at line 7252 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().

Referenced by socket_read().

    07253 {
    07254    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
    07255 }

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

Definition at line 5844 of file chan_iax2.c.

References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, error(), ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, LOG_DEBUG, PTR_TO_CALLNO, and ast_channel::tech_pvt.

    05845 {
    05846    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
    05847    int res = -1;
    05848    ast_mutex_lock(&iaxsl[callno]);
    05849    if (iaxs[callno]) {
    05850    /* If there's an outstanding error, return failure now */
    05851       if (!iaxs[callno]->error) {
    05852          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
    05853             res = 0;
    05854             /* Don't waste bandwidth sending null frames */
    05855          else if (f->frametype == AST_FRAME_NULL)
    05856             res = 0;
    05857          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
    05858             res = 0;
    05859          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
    05860             res = 0;
    05861          else
    05862          /* Simple, just queue for transmission */
    05863             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
    05864       } else {
    05865          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
    05866       }
    05867    }
    05868    /* If it's already gone, just return */
    05869    ast_mutex_unlock(&iaxsl[callno]);
    05870    return res;
    05871 }

static int iax_check_version | ( | char * | dev | ) | `[static]`

Definition at line 2262 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.

Referenced by update_registry().

    02263 {
    02264    int res = 0;
    02265    struct iax_firmware *cur;
    02266    if (!ast_strlen_zero(dev)) {
    02267       ast_mutex_lock(&waresl.lock);
    02268       cur = waresl.wares;
    02269       while(cur) {
    02270          if (!strcmp(dev, (char *)cur->fwh->devname)) {
    02271             res = ntohs(cur->fwh->version);
    02272             break;
    02273          }
    02274          cur = cur->next;
    02275       }
    02276       ast_mutex_unlock(&waresl.lock);
    02277    }
    02278    return res;
    02279 }

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

Definition at line 776 of file chan_iax2.c.

References ast_verbose().

Referenced by load_module().

    00777 {
    00778    if (iaxdebug)
    00779       ast_verbose("%s", data);
    00780 }

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

Definition at line 782 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

    00783 {
    00784    ast_log(LOG_WARNING, "%s", data);
    00785 }

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

Definition at line 2281 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_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, ast_firmware_list::lock, iax_firmware::next, ast_firmware_list::wares, and waresl.

Referenced by socket_read().

    02282 {
    02283    int res = -1;
    02284    unsigned int bs = desc & 0xff;
    02285    unsigned int start = (desc >> 8) & 0xffffff;
    02286    unsigned int bytes;
    02287    struct iax_firmware *cur;
    02288    if (!ast_strlen_zero((char *)dev) && bs) {
    02289       start *= bs;
    02290       ast_mutex_lock(&waresl.lock);
    02291       cur = waresl.wares;
    02292       while(cur) {
    02293          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
    02294             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
    02295             if (start < ntohl(cur->fwh->datalen)) {
    02296                bytes = ntohl(cur->fwh->datalen) - start;
    02297                if (bytes > bs)
    02298                   bytes = bs;
    02299                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
    02300             } else {
    02301                bytes = 0;
    02302                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
    02303             }
    02304             if (bytes == bs)
    02305                res = 0;
    02306             else
    02307                res = 1;
    02308             break;
    02309          }
    02310          cur = cur->next;
    02311       }
    02312       ast_mutex_unlock(&waresl.lock);
    02313    }
    02314    return res;
    02315 }

static int iax_park | ( | struct ast_channel * | chan1,
|  | struct ast_channel * | chan2 |
| ) |  |  | `[static]`

Definition at line 7509 of file chan_iax2.c.

References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, malloc, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.

Referenced by socket_read().

    07510 {
    07511    struct iax_dual *d;
    07512    struct ast_channel *chan1m, *chan2m;
    07513    pthread_t th;
    07514    chan1m = ast_channel_alloc(0);
    07515    chan2m = ast_channel_alloc(0);
    07516    if (chan2m && chan1m) {
    07517       snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
    07518       /* Make formats okay */
    07519       chan1m->readformat = chan1->readformat;
    07520       chan1m->writeformat = chan1->writeformat;
    07521       ast_channel_masquerade(chan1m, chan1);
    07522       /* Setup the extensions and such */
    07523       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
    07524       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
    07525       chan1m->priority = chan1->priority;
    07526
    07527       /* We make a clone of the peer channel too, so we can play
    07528          back the announcement */
    07529       snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name);
    07530       /* Make formats okay */
    07531       chan2m->readformat = chan2->readformat;
    07532       chan2m->writeformat = chan2->writeformat;
    07533       ast_channel_masquerade(chan2m, chan2);
    07534       /* Setup the extensions and such */
    07535       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
    07536       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
    07537       chan2m->priority = chan2->priority;
    07538       if (ast_do_masquerade(chan2m)) {
    07539          ast_log(LOG_WARNING, "Masquerade failed :(\n");
    07540          ast_hangup(chan2m);
    07541          return -1;
    07542       }
    07543    } else {
    07544       if (chan1m)
    07545          ast_hangup(chan1m);
    07546       if (chan2m)
    07547          ast_hangup(chan2m);
    07548       return -1;
    07549    }
    07550    d = malloc(sizeof(struct iax_dual));
    07551    if (d) {
    07552       pthread_attr_t attr;
    07553
    07554       pthread_attr_init(&attr);
    07555       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    07556
    07557       memset(d, 0, sizeof(*d));
    07558       d->chan1 = chan1m;
    07559       d->chan2 = chan2m;
    07560       if (!ast_pthread_create(&th, &attr, iax_park_thread, d)) {
    07561          pthread_attr_destroy(&attr);
    07562          return 0;
    07563       }
    07564       pthread_attr_destroy(&attr);
    07565       free(d);
    07566    }
    07567    return -1;
    07568 }

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

Definition at line 7489 of file chan_iax2.c.

References ast_frfree(), ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, free, and LOG_NOTICE.

Referenced by iax_park().

    07490 {
    07491    struct ast_channel *chan1, *chan2;
    07492    struct iax_dual *d;
    07493    struct ast_frame *f;
    07494    int ext;
    07495    int res;
    07496    d = stuff;
    07497    chan1 = d->chan1;
    07498    chan2 = d->chan2;
    07499    free(d);
    07500    f = ast_read(chan1);
    07501    if (f)
    07502       ast_frfree(f);
    07503    res = ast_park_call(chan1, chan2, 0, &ext);
    07504    ast_hangup(chan2);
    07505    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
    07506    return NULL;
    07507 }

static struct iax_frame* iaxfrdup2 | ( | struct iax_frame * | fr | ) | `[static, read]`

Definition at line 1267 of file chan_iax2.c.

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

Referenced by socket_read().

    01268 {
    01269    /* Malloc() a copy of a frame */
    01270    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
    01271    if (new) {
    01272       memcpy(new, fr, sizeof(struct iax_frame));
    01273       iax_frame_wrap(new, &fr->af);
    01274       new->data = NULL;
    01275       new->datalen = 0;
    01276       new->direction = DIRECTION_INGRESS;
    01277       new->retrans = -1;
    01278    }
    01279    return new;
    01280 }

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

Definition at line 812 of file chan_iax2.c.

References ast_verbose().

Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().

    00813 {
    00814    va_list args;
    00815    char buf[1024];
    00816
    00817    va_start(args, fmt);
    00818    vsnprintf(buf, 1024, fmt, args);
    00819    va_end(args);
    00820
    00821    ast_verbose("%s", buf);
    00822 }

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

Definition at line 788 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().

    00789 {
    00790    va_list args;
    00791    char buf[1024];
    00792
    00793    va_start(args, fmt);
    00794    vsnprintf(buf, 1024, fmt, args);
    00795    va_end(args);
    00796
    00797    ast_log(LOG_ERROR, "%s", buf);
    00798 }

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

Definition at line 800 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().

    00801 {
    00802    va_list args;
    00803    char buf[1024];
    00804
    00805    va_start(args, fmt);
    00806    vsnprintf(buf, 1024, fmt, args);
    00807    va_end(args);
    00808
    00809    ast_log(LOG_WARNING, "%s", buf);
    00810 }

char* key | ( | void |  | ) |

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

     char *key(void) {
             return ASTERISK_GPL_KEY;
     }

Returns:
  ASTERISK_GPL_KEY

Definition at line 11377 of file chan_iax2.c.

References ASTERISK_GPL_KEY.

    11378 {
    11379    return ASTERISK_GPL_KEY;
    11380 }

int load_module | ( | void |  | ) |

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
  This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
  int Always 0.

Definition at line 11259 of file chan_iax2.c.

References __unload_module(), ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register(), ast_log(), ast_manager_register, ast_mutex_init(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), iax2_do_register(), iax2_poke_peer(), iax2_prov_app(), iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxq, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), ast_firmware_list::lock, ast_peer_list::lock, ast_user_list::lock, ast_iax2_queue::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), iax2_peer::next, iax2_registry::next, option_verbose, peerl, ast_peer_list::peers, reload_firmware(), sched_context_create(), set_config(), iax2_peer::sockfd, start_network_thread(), userl, VERBOSE_PREFIX_2, and waresl.

    11260 {
    11261    static const char config[] = "iax.conf";
    11262    int res = 0;
    11263    int x;
    11264    struct iax2_registry *reg;
    11265    struct iax2_peer *peer;
    11266
    11267    if (load_objects()) {
    11268       return -1;
    11269    }
    11270
    11271    randomcalltokendata = rand();
    11272
    11273    ast_custom_function_register(&iaxpeer_function);
    11274
    11275    iax_set_output(iax_debug_output);
    11276    iax_set_error(iax_error_output);
    11277 #ifdef NEWJB
    11278    jb_setoutput(jb_error_output, jb_warning_output, NULL);
    11279 #endif
    11280
    11281 #ifdef IAX_TRUNKING
    11282 #ifdef ZT_TIMERACK
    11283    timingfd = open("/dev/zap/timer", O_RDWR);
    11284    if (timingfd < 0)
    11285 #endif
    11286       timingfd = open("/dev/zap/pseudo", O_RDWR);
    11287    if (timingfd < 0)
    11288       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
    11289 #endif
    11290
    11291    memset(iaxs, 0, sizeof(iaxs));
    11292
    11293    for (x=0;x<IAX_MAX_CALLS;x++)
    11294       ast_mutex_init(&iaxsl[x]);
    11295
    11296    io = io_context_create();
    11297    sched = sched_context_create();
    11298
    11299    if (!io || !sched) {
    11300       ast_log(LOG_ERROR, "Out of memory\n");
    11301       return -1;
    11302    }
    11303
    11304    netsock = ast_netsock_list_alloc();
    11305    if (!netsock) {
    11306       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
    11307       return -1;
    11308    }
    11309    ast_netsock_init(netsock);
    11310
    11311    outsock = ast_netsock_list_alloc();
    11312    if (!outsock) {
    11313       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
    11314       return -1;
    11315    }
    11316    ast_netsock_init(outsock);
    11317
    11318    ast_mutex_init(&iaxq.lock);
    11319    ast_mutex_init(&userl.lock);
    11320    ast_mutex_init(&peerl.lock);
    11321    ast_mutex_init(&waresl.lock);
    11322
    11323    ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
    11324
    11325    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
    11326
    11327    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
    11328    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
    11329
    11330    set_config(config, 0);
    11331
    11332    if (ast_channel_register(&iax2_tech)) {
    11333       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
    11334       __unload_module();
    11335       return -1;
    11336    }
    11337
    11338    if (ast_register_switch(&iax2_switch))
    11339       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
    11340
    11341    res = start_network_thread();
    11342    if (!res) {
    11343       if (option_verbose > 1)
    11344          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
    11345    } else {
    11346       ast_log(LOG_ERROR, "Unable to start network thread\n");
    11347       ast_netsock_release(netsock);
    11348       ast_netsock_release(outsock);
    11349    }
    11350
    11351    ast_mutex_lock(&reg_lock);
    11352    for (reg = registrations; reg; reg = reg->next)
    11353       iax2_do_register(reg);
    11354    ast_mutex_unlock(&reg_lock);
    11355    ast_mutex_lock(&peerl.lock);
    11356    for (peer = peerl.peers; peer; peer = peer->next) {
    11357       if (peer->sockfd < 0)
    11358          peer->sockfd = defaultsockfd;
    11359       iax2_poke_peer(peer, 0);
    11360    }
    11361    ast_mutex_unlock(&peerl.lock);
    11362    reload_firmware();
    11363    iax_provision_reload();
    11364    return res;
    11365 }

static int load_objects | ( | void |  | ) | `[static]`

Definition at line 11219 of file chan_iax2.c.

References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc(), ao2_ref(), create_callno_pools(), IAX_MAX_CALLS, MAX_PEER_BUCKETS, peercnt_cmp_cb(), peercnt_hash_cb(), pvt_cmp_cb(), and pvt_hash_cb().

Referenced by load_module().

    11220 {
    11221    iax_peercallno_pvts = peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
    11222    if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
    11223       goto container_fail;
    11224    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
    11225       goto container_fail;
    11226    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
    11227       goto container_fail;
    11228    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
    11229       goto container_fail;
    11230    } else if (create_callno_pools()) {
    11231       goto container_fail;
    11232    }
    11233
    11234    return 0;
    11235
    11236 container_fail:
    11237    if (iax_peercallno_pvts) {
    11238       ao2_ref(iax_peercallno_pvts, -1);
    11239    }
    11240    if (peercnts) {
    11241       ao2_ref(peercnts, -1);
    11242    }
    11243    if (callno_limits) {
    11244       ao2_ref(callno_limits, -1);
    11245    }
    11246    if (calltoken_ignores) {
    11247       ao2_ref(calltoken_ignores, -1);
    11248    }
    11249    if (callno_pool) {
    11250       ao2_ref(callno_pool, -1);
    11251    }
    11252    if (callno_pool_trunk) {
    11253       ao2_ref(callno_pool_trunk, -1);
    11254    }
    11255    return -1;
    11256 }

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

Definition at line 4344 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_trylock(), and ast_mutex_unlock().

Referenced by iax2_bridge().

    04345 {
    04346    ast_mutex_lock(&iaxsl[callno0]);
    04347    while (ast_mutex_trylock(&iaxsl[callno1])) {
    04348       ast_mutex_unlock(&iaxsl[callno0]);
    04349       usleep(10);
    04350       ast_mutex_lock(&iaxsl[callno0]);
    04351    }
    04352 }

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

Note:
  We delete these before switching the slot, because if they fire in the meantime, they will generate a warning.

Definition at line 1330 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), chan_iax2_pvt::lagid, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.

Referenced by iax2_request(), and socket_read().

    01331 {
    01332    int x;
    01333    int res= 0;
    01334    struct callno_entry *callno_entry;
    01335    if (iaxs[callno]->oseqno) {
    01336       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
    01337       return -1;
    01338    }
    01339    if (callno & TRUNK_CALL_START) {
    01340       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
    01341       return -1;
    01342    }
    01343
    01344    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
    01345       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
    01346       return -1;
    01347    }
    01348    x = callno_entry->callno;
    01349    ast_mutex_lock(&iaxsl[x]);
    01350
    01351    /*!
    01352     * \note We delete these before switching the slot, because if
    01353     * they fire in the meantime, they will generate a warning.
    01354     */
    01355    iaxs[x] = iaxs[callno];
    01356    iaxs[x]->callno = x;
    01357    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
    01358     * before assigning the new one */
    01359    if (iaxs[x]->callno_entry) {
    01360       ast_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
    01361    }
    01362    iaxs[x]->callno_entry = callno_entry;
    01363    iaxs[callno] = NULL;
    01364    /* Update the two timers that should have been started */
    01365    if (iaxs[x]->pingid > -1)
    01366       ast_sched_del(sched, iaxs[x]->pingid);
    01367    if (iaxs[x]->lagid > -1)
    01368       ast_sched_del(sched, iaxs[x]->lagid);
    01369    iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
    01370    iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
    01371    if (locked)
    01372       ast_mutex_unlock(&iaxsl[callno]);
    01373    res = x;
    01374    if (!locked)
    01375       ast_mutex_unlock(&iaxsl[x]);
    01376
    01377    if (option_debug)
    01378       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
    01379
    01380    /* We move this call from a non-trunked to a trunked call */
    01381    update_max_trunk();
    01382    update_max_nontrunk();
    01383    return res;
    01384 }

static int manager_iax2_show_netstats | ( | struct mansession * | s,
|  | struct message * | m |
| ) |  |  | `[static]`

Definition at line 5517 of file chan_iax2.c.

References ast_cli(), ast_cli_netstats(), mansession::fd, and RESULT_SUCCESS.

Referenced by load_module().

    05518 {
    05519    ast_cli_netstats(s->fd, 0);
    05520    ast_cli(s->fd, "\r\n");
    05521    return RESULT_SUCCESS;
    05522 }

static int manager_iax2_show_peers | ( | struct mansession * | s,
|  | struct message * | m |
| ) |  |  | `[static]`

Definition at line 5550 of file chan_iax2.c.

References __iax2_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), mansession::fd, and id.

Referenced by load_module().

    05551 {
    05552    char *a[] = { "iax2", "show", "users" };
    05553    int ret;
    05554    char *id;
    05555    id = astman_get_header(m,"ActionID");
    05556    if (!ast_strlen_zero(id))
    05557       ast_cli(s->fd, "ActionID: %s\r\n",id);
    05558    ret = __iax2_show_peers(1, s->fd, 3, a );
    05559    ast_cli(s->fd, "\r\n\r\n" );
    05560    return ret;
    05561 } /* /JDG */

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

Definition at line 1296 of file chan_iax2.c.

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

Referenced by ao2_callback(), ast_extension_close(), ast_extension_match(), ast_parse_device_state(), complete_show_channels(), find_callno(), find_cli(), find_command(), key_matches(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), schedule_delivery(), and softhangup_exec().

    01297 {
    01298    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
    01299       (cur->addr.sin_port == sin->sin_port)) {
    01300       /* This is the main host */
    01301       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
    01302           (check_dcallno ? dcallno == cur->callno : 1) ) {
    01303          /* That's us.  Be sure we keep track of the peer call number */
    01304          return 1;
    01305       }
    01306    }
    01307    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
    01308        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
    01309       /* We're transferring */
    01310       if (dcallno == cur->callno)
    01311          return 1;
    01312    }
    01313    return 0;
    01314 }

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

Definition at line 5012 of file chan_iax2.c.

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

Referenced by decode_frame().

    05013 {
    05014 #if 0
    05015    /* Debug with "fake encryption" */
    05016    int x;
    05017    if (len % 16)
    05018       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
    05019    for (x=0;x<len;x++)
    05020       dst[x] = src[x] ^ 0xff;
    05021 #else
    05022    unsigned char lastblock[16] = { 0 };
    05023    int x;
    05024    while(len > 0) {
    05025       aes_decrypt(src, dst, dcx);
    05026       for (x=0;x<16;x++)
    05027          dst[x] ^= lastblock[x];
    05028       memcpy(lastblock, src, sizeof(lastblock));
    05029       dst += 16;
    05030       src += 16;
    05031       len -= 16;
    05032    }
    05033 #endif
    05034 }

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

Definition at line 5036 of file chan_iax2.c.

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

Referenced by encrypt_frame().

    05037 {
    05038 #if 0
    05039    /* Debug with "fake encryption" */
    05040    int x;
    05041    if (len % 16)
    05042       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
    05043    for (x=0;x<len;x++)
    05044       dst[x] = src[x] ^ 0xff;
    05045 #else
    05046    unsigned char curblock[16] = { 0 };
    05047    int x;
    05048    while(len > 0) {
    05049       for (x=0;x<16;x++)
    05050          curblock[x] ^= src[x];
    05051       aes_encrypt(curblock, dst, ecx);
    05052       memcpy(curblock, dst, sizeof(curblock));
    05053       dst += 16;
    05054       src += 16;
    05055       len -= 16;
    05056    }
    05057 #endif
    05058 }

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

Definition at line 6165 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.

Referenced by authenticate_reply(), and socket_read().

    06166 {
    06167    /* Select exactly one common encryption if there are any */
    06168    p->encmethods &= enc;
    06169    if (p->encmethods) {
    06170       if (p->encmethods & IAX_ENCRYPT_AES128)
    06171          p->encmethods = IAX_ENCRYPT_AES128;
    06172       else
    06173          p->encmethods = 0;
    06174    }
    06175 }

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

Definition at line 9452 of file chan_iax2.c.

References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_runq(), ast_sched_wait(), attempt_transmit(), iax_frame::callno, ast_iax2_queue::count, ast_iax2_queue::head, iax_frame_free(), iaxq, ast_iax2_queue::lock, LOG_DEBUG, iax_frame::next, iax_frame::prev, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, ast_iax2_queue::tail, and timing_read().

Referenced by start_network_thread().

    09453 {
    09454    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames
    09455       from the network, and queue them for delivery to the channels */
    09456    int res, count;
    09457    struct iax_frame *f, *freeme;
    09458    if (timingfd > -1)
    09459       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
    09460    for(;;) {
    09461       /* Go through the queue, sending messages which have not yet been
    09462          sent, and scheduling retransmissions if appropriate */
    09463       ast_mutex_lock(&iaxq.lock);
    09464       f = iaxq.head;
    09465       count = 0;
    09466       while(f) {
    09467          freeme = NULL;
    09468          if (!f->sentyet) {
    09469             f->sentyet++;
    09470             /* Send a copy immediately -- errors here are ok, so don't bother locking */
    09471             if (iaxs[f->callno]) {
    09472                send_packet(f);
    09473                count++;
    09474             }
    09475             if (f->retries < 0) {
    09476                /* This is not supposed to be retransmitted */
    09477                if (f->prev)
    09478                   f->prev->next = f->next;
    09479                else
    09480                   iaxq.head = f->next;
    09481                if (f->next)
    09482                   f->next->prev = f->prev;
    09483                else
    09484                   iaxq.tail = f->prev;
    09485                iaxq.count--;
    09486                /* Free the iax frame */
    09487                freeme = f;
    09488             } else {
    09489                /* We need reliable delivery.  Schedule a retransmission */
    09490                f->retries++;
    09491                f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
    09492             }
    09493          }
    09494          f = f->next;
    09495          if (freeme)
    09496             iax_frame_free(freeme);
    09497       }
    09498       ast_mutex_unlock(&iaxq.lock);
    09499       if (count >= 20)
    09500          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
    09501
    09502       /* Now do the IO, and run scheduled tasks */
    09503       res = ast_sched_wait(sched);
    09504       if ((res > 1000) || (res < 0))
    09505          res = 1000;
    09506       res = ast_io_wait(io, res);
    09507       if (res >= 0) {
    09508          if (res >= 20)
    09509             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
    09510          count = ast_sched_runq(sched);
    09511          if (count >= 20)
    09512             ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
    09513       }
    09514    }
    09515    return NULL;
    09516 }

static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin,
|  | int | lockpeer,
|  | const char * | host |
| ) |  |  | `[static, read]`

Definition at line 1236 of file chan_iax2.c.

References ao2_alloc(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::exten, chan_iax2_pvt::host, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), and jb_conf::resync_threshold.

Referenced by find_callno().

    01237 {
    01238    struct chan_iax2_pvt *tmp;
    01239
    01240    tmp = ao2_alloc(sizeof(*tmp), pvt_destructor);
    01241    if (tmp) {
    01242       tmp->prefs = prefs;
    01243       tmp->pingid = -1;
    01244       tmp->lagid = -1;
    01245       tmp->autoid = -1;
    01246       tmp->authid = -1;
    01247       tmp->initid = -1;
    01248       /* ast_copy_string(tmp->context, context, sizeof(tmp->context)); */
    01249       ast_copy_string(tmp->exten, "s", sizeof(tmp->exten));
    01250       ast_copy_string(tmp->host, host, sizeof(tmp->host));
    01251 #ifdef NEWJB
    01252       {
    01253          jb_conf jbconf;
    01254
    01255          tmp->jb = jb_new();
    01256          tmp->jbid = -1;
    01257          jbconf.max_jitterbuf = maxjitterbuffer;
    01258          jbconf.resync_threshold = resyncthreshold;
    01259          jbconf.max_contig_interp = maxjitterinterps;
    01260          jb_setconf(tmp->jb,&jbconf);
    01261       }
    01262 #endif
    01263    }
    01264    return tmp;
    01265 }

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

    04076 {
    04077    if (ast_strlen_zero(data))
    04078       return;
    04079
    04080    pds->peer = strsep(&data, "/");
    04081    pds->exten = strsep(&data, "/");
    04082    pds->options = data;
    04083
    04084    if (pds->exten) {
    04085       data = pds->exten;
    04086       pds->exten = strsep(&data, "@");
    04087       pds->context = data;
    04088    }
    04089
    04090    if (strchr(pds->peer, '@')) {
    04091       data = pds->peer;
    04092       pds->username = strsep(&data, "@");
    04093       pds->peer = data;
    04094    }
    04095
    04096    if (pds->username) {
    04097       data = pds->username;
    04098       pds->username = strsep(&data, ":");
    04099       pds->password = data;
    04100    }
    04101
    04102    data = pds->peer;
    04103    pds->peer = strsep(&data, ":");
    04104    pds->port = data;
    04105
    04106    /* check for a key name wrapped in [] in the secret position, if found,
    04107       move it to the key field instead
    04108    */
    04109    if (pds->password && (pds->password[0] == '[')) {
    04110       pds->key = ast_strip_quoted(pds->password, "[", "]");
    04111       pds->password = NULL;
    04112    }
    04113 }

static int peer_set_srcaddr | ( | struct iax2_peer * | peer,
|  | const char * | srcaddr |
| ) |  |  | `[static]`

Definition at line 9577 of file chan_iax2.c.

References ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_DEBUG, LOG_WARNING, iax2_peer::name, socket_read(), iax2_peer::sockfd, and strsep().

Referenced by build_peer().

    09578 {
    09579    struct sockaddr_in sin;
    09580    int nonlocal = 1;
    09581    int port = IAX_DEFAULT_PORTNO;
    09582    int sockfd = defaultsockfd;
    09583    char *tmp;
    09584    char *addr;
    09585    char *portstr;
    09586
    09587    tmp = ast_strdupa(srcaddr);
    09588    if (!tmp) {
    09589       ast_log(LOG_WARNING, "Out of memory!\n");
    09590       return -1;
    09591    }
    09592
    09593    addr = strsep(&tmp, ":");
    09594    portstr = tmp;
    09595
    09596    if (portstr) {
    09597       port = atoi(portstr);
    09598       if (port < 1)
    09599          port = IAX_DEFAULT_PORTNO;
    09600    }
    09601
    09602    if (!ast_get_ip(&sin, addr)) {
    09603       struct ast_netsock *sock;
    09604       int res;
    09605
    09606       sin.sin_port = 0;
    09607       sin.sin_family = AF_INET;
    09608       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
    09609       if (res == 0) {
    09610          /* ip address valid. */
    09611          sin.sin_port = htons(port);
    09612          if (!(sock = ast_netsock_find(netsock, &sin)))
    09613             sock = ast_netsock_find(outsock, &sin);
    09614          if (sock) {
    09615             sockfd = ast_netsock_sockfd(sock);
    09616             nonlocal = 0;
    09617          } else {
    09618             unsigned int orig_saddr = sin.sin_addr.s_addr;
    09619             /* INADDR_ANY matches anyway! */
    09620             sin.sin_addr.s_addr = INADDR_ANY;
    09621             if (ast_netsock_find(netsock, &sin)) {
    09622                sin.sin_addr.s_addr = orig_saddr;
    09623                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
    09624                if (sock) {
    09625                   sockfd = ast_netsock_sockfd(sock);
    09626                   ast_netsock_unref(sock);
    09627                   nonlocal = 0;
    09628                } else {
    09629                   nonlocal = 2;
    09630                }
    09631             }
    09632          }
    09633       }
    09634    }
    09635
    09636    peer->sockfd = sockfd;
    09637
    09638    if (nonlocal == 1) {
    09639       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
    09640          srcaddr, peer->name);
    09641       return -1;
    09642         } else if (nonlocal == 2) {
    09643       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
    09644          srcaddr, peer->name);
    09645          return -1;
    09646    } else {
    09647       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
    09648       return 0;
    09649    }
    09650 }

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

peer_status: Report Peer status in character string

Definition at line 2774 of file chan_iax2.c.

References iax2_peer::lastms, and iax2_peer::maxms.

Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), and iax2_show_peer().

    02775 {
    02776    int res = 0;
    02777    if (peer->maxms) {
    02778       if (peer->lastms < 0) {
    02779          ast_copy_string(status, "UNREACHABLE", statuslen);
    02780       } else if (peer->lastms > peer->maxms) {
    02781          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
    02782          res = 1;
    02783       } else if (peer->lastms) {
    02784          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
    02785          res = 1;
    02786       } else {
    02787          ast_copy_string(status, "UNKNOWN", statuslen);
    02788       }
    02789    } else {
    02790       ast_copy_string(status, "Unmonitored", statuslen);
    02791       res = -1;
    02792    }
    02793    return res;
    02794 }

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

Definition at line 1572 of file chan_iax2.c.

References peercnt::addr, ao2_alloc(), ao2_find(), ao2_lock(), ao2_ref(), ao2_unlock(), ast_inet_ntoa(), ast_log(), peercnt::cur, peercnt::limit, LOG_ERROR, LOG_NOTICE, option_debug, and set_peercnt_limit().

Referenced by complete_transfer(), and find_callno().

    01573 {
    01574    struct peercnt *peercnt;
    01575    unsigned long addr = sin->sin_addr.s_addr;
    01576    int res = 0;
    01577    struct peercnt tmp = {
    01578       .addr = addr,
    01579    };
    01580    char iabuf[INET_ADDRSTRLEN];
    01581
    01582    /* Reasoning for peercnts container lock:  Two identical ip addresses
    01583     * could be added by different threads at the "same time". Without the container
    01584     * lock, both threads could alloc space for the same object and attempt
    01585     * to link to table.  With the lock, one would create the object and link
    01586     * to table while the other would find the already created peercnt object
    01587     * rather than creating a new one. */
    01588    ao2_lock(peercnts);
    01589    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
    01590       ao2_lock(peercnt);
    01591    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
    01592       ao2_lock(peercnt);
    01593       /* create and set defaults */
    01594       peercnt->addr = addr;
    01595       set_peercnt_limit(peercnt);
    01596       /* guarantees it does not go away after unlocking table
    01597        * ao2_find automatically adds this */
    01598       ao2_link(peercnts, peercnt);
    01599    } else {
    01600       ao2_unlock(peercnts);
    01601       return -1;
    01602    }
    01603
    01604    /* check to see if the address has hit its callno limit.  If not increment cur. */
    01605    if (peercnt->limit > peercnt->cur) {
    01606       peercnt->cur++;
    01607       if (option_debug) {
    01608          ast_log(LOG_NOTICE, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    01609       }
    01610    } else { /* max num call numbers for this peer has been reached! */
    01611       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    01612       res = -1;
    01613    }
    01614
    01615    /* clean up locks and ref count */
    01616    ao2_unlock(peercnt);
    01617    ao2_unlock(peercnts);
    01618    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
    01619
    01620    return res;
    01621 }

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

Definition at line 1413 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

    01414 {
    01415    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
    01416    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
    01417 }

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

Definition at line 1407 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

    01408 {
    01409    const struct peercnt *peercnt = obj;
    01410    return abs((int) peercnt->addr);
    01411 }

static void peercnt_modify | ( | unsigned char | reg,
|  | uint16_t | limit,
|  | struct sockaddr_in * | sin |
| ) |  |  | `[static]`

Definition at line 1541 of file chan_iax2.c.

References peercnt::addr, ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), peercnt::limit, LOG_NOTICE, option_debug, peercnt::reg, and set_peercnt_limit().

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

    01542 {
    01543    /* this function turns off and on custom callno limits set by peer registration */
    01544    struct peercnt *peercnt;
    01545    struct peercnt tmp = {
    01546       .addr = sin->sin_addr.s_addr,
    01547    };
    01548    char iabuf[INET_ADDRSTRLEN];
    01549
    01550    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
    01551       peercnt->reg = reg;
    01552       if (limit) {
    01553          peercnt->limit = limit;
    01554       } else {
    01555          set_peercnt_limit(peercnt);
    01556       }
    01557       if (option_debug) {
    01558          ast_log(LOG_NOTICE, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), peercnt->limit, peercnt->reg);
    01559       }
    01560       ao2_ref(peercnt, -1); /* decrement ref from find */
    01561    }
    01562 }

static void peercnt_remove | ( | struct peercnt * | peercnt | ) | `[static]`

Definition at line 1627 of file chan_iax2.c.

References peercnt::addr, ao2_lock(), ao2_unlink(), ao2_unlock(), ast_inet_ntoa(), ast_log(), peercnt::cur, LOG_NOTICE, and option_debug.

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

    01628 {
    01629    struct sockaddr_in sin = {
    01630       .sin_addr.s_addr = peercnt->addr,
    01631    };
    01632    char iabuf[INET_ADDRSTRLEN];
    01633
    01634    if (peercnt) {
    01635       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
    01636        * peercnt_add could try and grab this entry from the table and modify it at the
    01637        * "same time" this thread attemps to unlink it.*/
    01638       ao2_lock(peercnts);
    01639       peercnt->cur--;
    01640       if (option_debug) {
    01641          ast_log(LOG_NOTICE, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
    01642       }
    01643       /* if this was the last connection from the peer remove it from table */
    01644       if (peercnt->cur == 0) {
    01645          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
    01646       }
    01647       ao2_unlock(peercnts);
    01648    }
    01649 }

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

Definition at line 1669 of file chan_iax2.c.

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

Referenced by complete_transfer(), and find_callno().

    01670 {
    01671    struct peercnt *peercnt;
    01672    struct peercnt tmp = {
    01673       .addr = sin->sin_addr.s_addr,
    01674    };
    01675
    01676    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
    01677       peercnt_remove(peercnt);
    01678       ao2_ref(peercnt, -1); /* decrement ref from find */
    01679    }
    01680    return 0;
    01681 }

static int peercnt_remove_cb | ( | void * | obj | ) | `[static]`

Definition at line 1655 of file chan_iax2.c.

References ao2_ref(), and peercnt_remove().

Referenced by sched_delay_remove().

    01656 {
    01657    struct peercnt *peercnt = (struct peercnt *) obj;
    01658
    01659    peercnt_remove(peercnt);
    01660    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
    01661
    01662    return 0;
    01663 }

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

Definition at line 1530 of file chan_iax2.c.

References addr_range::delme.

    01531 {
    01532    struct addr_range *addr_range = obj;
    01533
    01534    return addr_range->delme ? CMP_MATCH : 0;
    01535 }

static void prune_peers | ( | void |  | ) | `[static]`

Definition at line 2188 of file chan_h323.c.

References ast_mutex_lock(), ast_mutex_unlock(), free, ast_peer_list::lock, peerl, and ast_peer_list::peers.

Referenced by expire_registry(), h323_do_reload(), set_config(), and unload_module().

    02189 {
    02190    /* Prune peers who still are supposed to be deleted */
    02191    struct oh323_peer *peer, *peerlast, *peernext;
    02192    ast_mutex_lock(&peerl.lock);
    02193    peerlast = NULL;
    02194    for (peer=peerl.peers;peer;) {
    02195       peernext = peer->next;
    02196       if (peer->delme) {
    02197          free(peer);
    02198          if (peerlast) {
    02199             peerlast->next = peernext;
    02200          } else {
    02201             peerl.peers = peernext;
    02202          }
    02203       } else {
    02204          peerlast = peer;
    02205       }
    02206       peer = peernext;
    02207    }
    02208    ast_mutex_unlock(&peerl.lock);
    02209 }

static void prune_users | ( | void |  | ) | `[static]`

Definition at line 10103 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, destroy_user(), IAX_DELME, ast_user_list::lock, iax2_user::next, user, userl, and ast_user_list::users.

    10104 {
    10105    struct iax2_user *user, *usernext, *userlast = NULL;
    10106    ast_mutex_lock(&userl.lock);
    10107    for (user=userl.users;user;) {
    10108       usernext = user->next;
    10109       if (ast_test_flag(user, IAX_DELME)) {
    10110          destroy_user(user);
    10111          if (userlast)
    10112             userlast->next = usernext;
    10113          else
    10114             userl.users = usernext;
    10115       } else
    10116          userlast = user;
    10117       user = usernext;
    10118    }
    10119    ast_mutex_unlock(&userl.lock);
    10120 }

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

Definition at line 11208 of file chan_iax2.c.

References chan_iax2_pvt::frames_received, and match().

Referenced by load_objects().

    11209 {
    11210    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
    11211
    11212    /* The frames_received field is used to hold whether we're matching
    11213     * against a full frame or not ... */
    11214
    11215    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
    11216       pvt2->frames_received) ? CMP_MATCH : 0;
    11217 }

static void pvt_destructor | ( | void * | obj | ) | `[static]`

Definition at line 1195 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_set_flag, ast_translator_free_path(), ast_variables_destroy(), chan_iax2_pvt::bridgetrans, iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, chan_iax2_pvt::callno_entry, jb_frame::data, ast_iax2_queue::head, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax_frame::next, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), and chan_iax2_pvt::vars.

Referenced by new_iax().

    01196 {
    01197    struct chan_iax2_pvt *pvt = obj;
    01198    struct iax_frame *cur;
    01199
    01200    iax2_destroy_helper(pvt);
    01201
    01202    sched_delay_remove(&pvt->addr, pvt->callno_entry);
    01203    pvt->callno_entry = NULL;
    01204
    01205    if (pvt->bridgetrans)
    01206       ast_translator_free_path(pvt->bridgetrans);
    01207    pvt->bridgetrans = NULL;
    01208
    01209    /* Already gone */
    01210    ast_set_flag(pvt, IAX_ALREADYGONE);
    01211
    01212    for (cur = iaxq.head; cur ; cur = cur->next) {
    01213       /* Cancel any pending transmissions */
    01214       if (cur->callno == pvt->callno)
    01215          cur->retries = -1;
    01216    }
    01217    if (pvt->reg) {
    01218       pvt->reg->callno = 0;
    01219    }
    01220    if (!pvt->owner) {
    01221       if (pvt->vars) {
    01222          ast_variables_destroy(pvt->vars);
    01223          pvt->vars = NULL;
    01224       }
    01225 #ifdef NEWJB
    01226       {
    01227          jb_frame frame;
    01228          while (jb_getall(pvt->jb,&frame) == JB_OK)
    01229             iax2_frame_free(frame.data);
    01230          jb_destroy(pvt->jb);
    01231       }
    01232 #endif
    01233    }
    01234 }

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

Definition at line 11201 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

    11202 {
    11203    const struct chan_iax2_pvt *pvt = obj;
    11204
    11205    return pvt->peercallno;
    11206 }

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

Definition at line 6144 of file chan_iax2.c.

References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, LOG_DEBUG, 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_read().

    06145 {
    06146    struct ast_iax2_full_hdr fh;
    06147    char iabuf[INET_ADDRSTRLEN];
    06148    fh.scallno = htons(src | IAX_FLAG_FULL);
    06149    fh.dcallno = htons(dst);
    06150    fh.ts = 0;
    06151    fh.oseqno = 0;
    06152    fh.iseqno = 0;
    06153    fh.type = AST_FRAME_IAX;
    06154    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
    06155    if (iaxdebug)
    06156        iax_showframe(NULL, &fh, 0, sin, 0);
    06157 #if 0
    06158    if (option_debug)
    06159 #endif
    06160       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
    06161          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst);
    06162    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
    06163 }

static struct iax2_peer * realtime_peer | ( | const char * | peername,
|  | struct sockaddr_in * | sin |
| ) |  |  | `[static, read]`

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

References iax2_peer::addr, ast_copy_flags, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), destroy_peer(), iax2_peer::expire, expire_registry(), hp, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, ast_peer_list::lock, LOG_DEBUG, iax2_peer::name, ast_variable::name, iax2_peer::next, ast_variable::next, option_debug, peerl, ast_peer_list::peers, realtime_update_peer(), reg_source_db(), ast_variable::value, and var.

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

    03451 {
    03452    struct ast_variable *var = NULL;
    03453    struct ast_variable *tmp;
    03454    struct iax2_peer *peer=NULL;
    03455    time_t regseconds, nowtime;
    03456    int dynamic=0;
    03457    char iabuf[INET_ADDRSTRLEN];
    03458
    03459    if (peername) {
    03460       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
    03461       if (!var && sin)
    03462          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), (char *) NULL);
    03463    } else if (sin) {
    03464       char porta[25];
    03465       ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
    03466       sprintf(porta, "%d", ntohs(sin->sin_port));
    03467       var = ast_load_realtime("iaxpeers", "ipaddr", iabuf, "port", porta, NULL);
    03468       if (var) {
    03469          /* We'll need the peer name in order to build the structure! */
    03470          tmp = var;
    03471          while(tmp) {
    03472             if (!strcasecmp(tmp->name, "name"))
    03473                peername = tmp->value;
    03474             tmp = tmp->next;
    03475          }
    03476       }
    03477    }
    03478    if (!var && peername) { /* Last ditch effort */
    03479       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
    03480       /*!\note
    03481        * If this one loaded something, then we need to ensure that the host
    03482        * field matched.  The only reason why we can't have this as a criteria
    03483        * is because we only have the IP address and the host field might be
    03484        * set as a name (and the reverse PTR might not match).
    03485        */
    03486       if (var && sin) {
    03487          for (tmp = var; tmp; tmp = tmp->next) {
    03488             if (!strcasecmp(tmp->name, "host")) {
    03489                struct ast_hostent ahp;
    03490                struct hostent *hp;
    03491                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
    03492                   /* No match */
    03493                   ast_variables_destroy(var);
    03494                   var = NULL;
    03495                }
    03496                break;
    03497             }
    03498          }
    03499       }
    03500    }
    03501    if (!var)
    03502       return NULL;
    03503
    03504    peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
    03505
    03506    if (!peer) {
    03507       ast_variables_destroy(var);
    03508       return NULL;
    03509    }
    03510
    03511    tmp = var;
    03512    while(tmp) {
    03513       /* Make sure it's not a user only... */
    03514       if (!strcasecmp(tmp->name, "type")) {
    03515          if (strcasecmp(tmp->value, "friend") &&
    03516              strcasecmp(tmp->value, "peer")) {
    03517             /* Whoops, we weren't supposed to exist! */
    03518             destroy_peer(peer);
    03519             peer = NULL;
    03520             break;
    03521          }
    03522       } else if (!strcasecmp(tmp->name, "regseconds")) {
    03523          if (sscanf(tmp->value, "%30ld", (time_t *)&regseconds) != 1)
    03524             regseconds = 0;
    03525       } else if (!strcasecmp(tmp->name, "ipaddr")) {
    03526          inet_aton(tmp->value, &(peer->addr.sin_addr));
    03527       } else if (!strcasecmp(tmp->name, "port")) {
    03528          peer->addr.sin_port = htons(atoi(tmp->value));
    03529       } else if (!strcasecmp(tmp->name, "host")) {
    03530          if (!strcasecmp(tmp->value, "dynamic"))
    03531             dynamic = 1;
    03532       }
    03533       tmp = tmp->next;
    03534    }
    03535
    03536    ast_variables_destroy(var);
    03537
    03538    if (!peer)
    03539       return NULL;
    03540
    03541    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
    03542       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
    03543       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
    03544          if (peer->expire > -1)
    03545             ast_sched_del(sched, peer->expire);
    03546          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer);
    03547       }
    03548       ast_mutex_lock(&peerl.lock);
    03549       peer->next = peerl.peers;
    03550       peerl.peers = peer;
    03551       ast_mutex_unlock(&peerl.lock);
    03552       if (ast_test_flag(peer, IAX_DYNAMIC))
    03553          reg_source_db(peer);
    03554    } else {
    03555       ast_set_flag(peer, IAX_TEMPONLY);
    03556    }
    03557
    03558    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
    03559       time(&nowtime);
    03560       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
    03561          memset(&peer->addr, 0, sizeof(peer->addr));
    03562          realtime_update_peer(peer->name, &peer->addr, 0);
    03563          if (option_debug)
    03564             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
    03565                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
    03566       }
    03567       else {
    03568          if (option_debug)
    03569             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
    03570                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
    03571       }
    03572    }
    03573
    03574    return peer;
    03575 }

static void realtime_update_peer | ( | const char * | peername,
|  | struct sockaddr_in * | sin,
|  | time_t | regtime |
| ) |  |  | `[static]`

Definition at line 3652 of file chan_iax2.c.

References ast_inet_ntoa(), ast_update_realtime(), and ipaddr.

Referenced by expire_registry(), realtime_peer(), update_peer(), and update_registry().

    03653 {
    03654         char port[10];
    03655         char ipaddr[20];
    03656         char regseconds[20];
    03657
    03658         snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
    03659         ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
    03660         snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
    03661         ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL);
    03662 }

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

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

References ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_user_list::lock, ast_variable::name, iax2_user::next, ast_variable::next, user, userl, ast_user_list::users, ast_variable::value, and var.

Referenced by check_access(), and find_user().

    03578 {
    03579    struct ast_variable *var;
    03580    struct ast_variable *tmp;
    03581    struct iax2_user *user=NULL;
    03582    char iabuf[INET_ADDRSTRLEN];
    03583
    03584    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
    03585    if (!var && sin)
    03586       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), (char *) NULL);
    03587    if (!var && sin) {
    03588       char porta[6];
    03589       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
    03590       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), "port", porta, NULL);
    03591       if (!var)
    03592          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), "port", porta, NULL);
    03593    }
    03594    if (!var) { /* Last ditch effort */
    03595       var = ast_load_realtime("iaxusers", "name", username, NULL);
    03596       /*!\note
    03597        * If this one loaded something, then we need to ensure that the host
    03598        * field matched.  The only reason why we can't have this as a criteria
    03599        * is because we only have the IP address and the host field might be
    03600        * set as a name (and the reverse PTR might not match).
    03601        */
    03602       if (var) {
    03603          for (tmp = var; tmp; tmp = tmp->next) {
    03604             if (!strcasecmp(tmp->name, "host")) {
    03605                struct ast_hostent ahp;
    03606                struct hostent *hp;
    03607                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
    03608                   /* No match */
    03609                   ast_variables_destroy(var);
    03610                   var = NULL;
    03611                }
    03612                break;
    03613             }
    03614          }
    03615       }
    03616    }
    03617    if (!var)
    03618       return NULL;
    03619
    03620    tmp = var;
    03621    while(tmp) {
    03622       /* Make sure it's not a peer only... */
    03623       if (!strcasecmp(tmp->name, "type")) {
    03624          if (strcasecmp(tmp->value, "friend") &&
    03625              strcasecmp(tmp->value, "user")) {
    03626             return NULL;
    03627          }
    03628       }
    03629       tmp = tmp->next;
    03630    }
    03631
    03632    user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
    03633
    03634    ast_variables_destroy(var);
    03635
    03636    if (!user)
    03637       return NULL;
    03638
    03639    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
    03640       ast_set_flag(user, IAX_RTCACHEFRIENDS);
    03641       ast_mutex_lock(&userl.lock);
    03642       user->next = userl.users;
    03643       userl.users = user;
    03644       ast_mutex_unlock(&userl.lock);
    03645    } else {
    03646       ast_set_flag(user, IAX_TEMPONLY);
    03647    }
    03648
    03649    return user;
    03650 }

static void reg_source_db | ( | struct iax2_peer * | p | ) | `[static]`

Definition at line 6920 of file chan_iax2.c.

References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, IAX_TEMPONLY, iax2_peer::name, option_verbose, register_peer_exten(), and VERBOSE_PREFIX_3.

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

    06921 {
    06922    char data[80];
    06923    struct in_addr in;
    06924    char iabuf[INET_ADDRSTRLEN];
    06925    char *c, *d;
    06926    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
    06927       c = strchr(data, ':');
    06928       if (c) {
    06929          *c = '\0';
    06930          c++;
    06931          if (inet_aton(data, &in)) {
    06932             d = strchr(c, ':');
    06933             if (d) {
    06934                *d = '\0';
    06935                d++;
    06936                if (option_verbose > 2)
    06937                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
    06938                   ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d));
    06939                iax2_poke_peer(p, 0);
    06940                p->expiry = atoi(d);
    06941                memset(&p->addr, 0, sizeof(p->addr));
    06942                p->addr.sin_family = AF_INET;
    06943                p->addr.sin_addr = in;
    06944                p->addr.sin_port = htons(atoi(c));
    06945                if (p->expire > -1)
    06946                   ast_sched_del(sched, p->expire);
    06947                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
    06948                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
    06949                if (iax2_regfunk)
    06950                   iax2_regfunk(p->name, 1);
    06951                register_peer_exten(p, 1);
    06952             }
    06953
    06954          }
    06955       }
    06956    }
    06957 }

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

Definition at line 6869 of file chan_iax2.c.

References ast_add_extension(), ast_context_remove_extension(), ast_exists_extension(), ast_strlen_zero(), FREE, iax2_peer::name, iax2_peer::regexten, strdup, and strsep().

Referenced by destroy_peer(), expire_register(), expire_registry(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry().

    06870 {
    06871    char multi[256];
    06872    char *stringp, *ext;
    06873    if (!ast_strlen_zero(regcontext)) {
    06874       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
    06875       stringp = multi;
    06876       while((ext = strsep(&stringp, "&"))) {
    06877          if (onoff) {
    06878             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
    06879                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype);
    06880          } else
    06881             ast_context_remove_extension(regcontext, ext, 1, NULL);
    06882       }
    06883    }
    06884 }

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

Verify inbound registration.

Definition at line 6310 of file chan_iax2.c.

References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_device_state_changed(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), chan_iax2_pvt::expiry, expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, chan_iax2_pvt::inkeys, iax2_peer::inkeys, key(), LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, chan_iax2_pvt::peer, iax_ies::refresh, iax_ies::rsa_result, chan_iax2_pvt::secret, iax2_peer::secret, secret, strsep(), and iax_ies::username.

Referenced by handle_request_register(), and socket_read().

    06311 {
    06312    char requeststr[256] = "";
    06313    char peer[256] = "";
    06314    char md5secret[256] = "";
    06315    char rsasecret[256] = "";
    06316    char secret[256] = "";
    06317    char iabuf[INET_ADDRSTRLEN];
    06318    struct iax2_peer *p;
    06319    struct ast_key *key;
    06320    char *keyn;
    06321    int x;
    06322    int expire = 0;
    06323
    06324    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
    06325    iaxs[callno]->peer[0] = '\0';
    06326    if (ies->username)
    06327       ast_copy_string(peer, ies->username, sizeof(peer));
    06328    if (ies->password)
    06329       ast_copy_string(secret, ies->password, sizeof(secret));
    06330    if (ies->md5_result)
    06331       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
    06332    if (ies->rsa_result)
    06333       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
    06334    if (ies->refresh)
    06335       expire = ies->refresh;
    06336
    06337    if (ast_strlen_zero(peer)) {
    06338       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06339       return -1;
    06340    }
    06341
    06342    ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer));
    06343    /* Choose lowest expiry number */
    06344    if (expire && (expire < iaxs[callno]->expiry))
    06345       iaxs[callno]->expiry = expire;
    06346
    06347    /* We release the lock for the call to prevent a deadlock, but it's okay because
    06348       only the current thread could possibly make it go away or make changes */
    06349    ast_mutex_unlock(&iaxsl[callno]);
    06350
    06351    /* SLD: first call to lookup peer during registration */
    06352    p = find_peer(peer, 1);
    06353    ast_mutex_lock(&iaxsl[callno]);
    06354
    06355    if (!p) {
    06356       if (authdebug)
    06357          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06358       ast_copy_string(iaxs[callno]->secret, "invalidpassword", sizeof(iaxs[callno]->secret));
    06359
    06360       /* A AUTHREQ must be sent to a invalid peer.  By returning 0, a REGAUTH with a md5/rsa challenge
    06361        * will be sent.  If the challenge has already been sent, return -1 to REGREJ the invalid peer. */
    06362       if (ast_strlen_zero(iaxs[callno]->challenge)) {
    06363          return 0;
    06364       }
    06365       return -1;
    06366    }
    06367
    06368    if (!ast_test_flag(p, IAX_DYNAMIC)) {
    06369       if (authdebug)
    06370          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    06371       if (ast_test_flag(p, IAX_TEMPONLY))
    06372          destroy_peer(p);
    06373       return -1;
    06374    }
    06375
    06376    if (!ast_apply_ha(p->ha, sin)) {
    06377       if (authdebug)
    06378          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
    06379       if (ast_test_flag(p, IAX_TEMPONLY))
    06380          destroy_peer(p);
    06381       return -1;
    06382    }
    06383    ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret));
    06384    ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys));
    06385    /* Check secret against what we have on file */
    06386    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
    06387       if (!ast_strlen_zero(p->inkeys)) {
    06388          char tmpkeys[256];
    06389          char *stringp=NULL;
    06390          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
    06391          stringp=tmpkeys;
    06392          keyn = strsep(&stringp, ":");
    06393          while(keyn) {
    06394             key = ast_key_get(keyn, AST_KEY_PUBLIC);
    06395             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
    06396                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
    06397                break;
    06398             } else if (!key)
    06399                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
    06400             keyn = strsep(&stringp, ":");
    06401          }
    06402          if (!keyn) {
    06403             if (authdebug)
    06404                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
    06405             if (ast_test_flag(p, IAX_TEMPONLY))
    06406                destroy_peer(p);
    06407             return -1;
    06408          }
    06409       } else {
    06410          if (authdebug)
    06411             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
    06412          if (ast_test_flag(p, IAX_TEMPONLY))
    06413             destroy_peer(p);
    06414          return -1;
    06415       }
    06416    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
    06417       /* They've provided a plain text password and we support that */
    06418       if (strcmp(secret, p->secret)) {
    06419          if (authdebug)
    06420             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
    06421          if (ast_test_flag(p, IAX_TEMPONLY))
    06422             destroy_peer(p);
    06423          return -1;
    06424       } else
    06425          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
    06426    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
    06427       struct MD5Context md5;
    06428       unsigned char digest[16];
    06429       char *tmppw, *stringp;
    06430
    06431       tmppw = ast_strdupa(p->secret);
    06432       stringp = tmppw;
    06433       while((tmppw = strsep(&stringp, ";"))) {
    06434          MD5Init(&md5);
    06435          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
    06436          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
    06437          MD5Final(digest, &md5);
    06438          for (x=0;x<16;x++)
    06439             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
    06440          if (!strcasecmp(requeststr, md5secret))
    06441             break;
    06442       }
    06443       if (tmppw) {
    06444          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
    06445       } else {
    06446          if (authdebug)
    06447             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name, requeststr, md5secret);
    06448          if (ast_test_flag(p, IAX_TEMPONLY))
    06449             destroy_peer(p);
    06450          return -1;
    06451       }
    06452    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
    06453       /* if challenge has been sent, but no challenge response if given, reject. */
    06454       if (ast_test_flag(p, IAX_TEMPONLY))
    06455          destroy_peer(p);
    06456       return -1;
    06457    }
    06458    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
    06459
    06460    if (ast_test_flag(p, IAX_TEMPONLY))
    06461       destroy_peer(p);
    06462    return 0;
    06463 }

static int registry_authrequest | ( | char * | name,
|  | int | callno |
| ) |  |  | `[static]`

Definition at line 7077 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_test_flag, iax2_peer::authmethods, iax_ie_data::buf, destroy_peer(), 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, IAX_TEMPONLY, LOG_WARNING, iax_ie_data::pos, and send_command().

Referenced by socket_read().

    07078 {
    07079    struct iax_ie_data ied;
    07080    struct iax2_peer *p;
    07081    int authmethods;
    07082
    07083    if (!callno || !iaxs[callno]) {
    07084       return 0;
    07085    }
    07086
    07087    /* SLD: third call to find_peer in registration */
    07088    if ((p = find_peer(name, 1))) {
    07089       lastauthmethod = p->authmethods;
    07090    }
    07091
    07092    authmethods = p ? p->authmethods : lastauthmethod ? lastauthmethod : (IAX_AUTH_PLAINTEXT | IAX_AUTH_MD5);
    07093    if (p && ast_test_flag(p, IAX_TEMPONLY)) {
    07094       destroy_peer(p);
    07095    } else if (!p) {
    07096       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
    07097    }
    07098
    07099    memset(&ied, 0, sizeof(ied));
    07100    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, authmethods);
    07101    if (authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
    07102       /* Build the challenge */
    07103       snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand());
    07104       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
    07105    }
    07106    iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
    07107    return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
    07108 }

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

Definition at line 7110 of file chan_iax2.c.

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

Referenced by socket_read().

    07111 {
    07112    struct iax2_registry *reg;
    07113    /* Start pessimistic */
    07114    struct iax_ie_data ied;
    07115    char peer[256] = "";
    07116    char iabuf[INET_ADDRSTRLEN];
    07117    char challenge[256] = "";
    07118    int res;
    07119    int authmethods = 0;
    07120    if (ies->authmethods)
    07121       authmethods = ies->authmethods;
    07122    if (ies->username)
    07123       ast_copy_string(peer, ies->username, sizeof(peer));
    07124    if (ies->challenge)
    07125       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
    07126    memset(&ied, 0, sizeof(ied));
    07127    reg = iaxs[callno]->reg;
    07128    if (reg) {
    07129          if (inaddrcmp(&reg->addr, sin)) {
    07130             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
    07131             return -1;
    07132          }
    07133          if (ast_strlen_zero(reg->secret)) {
    07134             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
    07135             reg->regstate = REG_STATE_NOAUTH;
    07136             return -1;
    07137          }
    07138          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
    07139          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
    07140          if (reg->secret[0] == '[') {
    07141             char tmpkey[256];
    07142             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
    07143             tmpkey[strlen(tmpkey) - 1] = '\0';
    07144             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
    07145          } else
    07146             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
    07147          if (!res) {
    07148             reg->regstate = REG_STATE_AUTHSENT;
    07149             add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
    07150             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
    07151          } else
    07152             return -1;
    07153          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
    07154    } else
    07155       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
    07156    return -1;
    07157 }

static char* regstate2str | ( | int | regstate | ) | `[static]`

Definition at line 5563 of file chan_iax2.c.

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

Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().

    05564 {
    05565    switch(regstate) {
    05566    case REG_STATE_UNREGISTERED:
    05567       return "Unregistered";
    05568    case REG_STATE_REGSENT:
    05569       return "Request Sent";
    05570    case REG_STATE_AUTHSENT:
    05571       return "Auth. Sent";
    05572    case REG_STATE_REGISTERED:
    05573       return "Registered";
    05574    case REG_STATE_REJECTED:
    05575       return "Rejected";
    05576    case REG_STATE_TIMEOUT:
    05577       return "Timeout";
    05578    case REG_STATE_NOAUTH:
    05579       return "No Authentication";
    05580    default:
    05581       return "Unknown";
    05582    }
    05583 }

int reload | ( | void |  | ) |

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
  The return value is not used.

Definition at line 10512 of file chan_iax2.c.

References reload_config().

    10513 {
    10514    return reload_config();
    10515 }

static int reload_config | ( | void |  | ) | `[static]`

Definition at line 1997 of file chan_h323.c.

References ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_H261, AST_FORMAT_ULAW, ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, format, hp, IPTOS_MINCOST, ast_variable::lineno, ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, update_common_options(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.

Referenced by h323_do_reload(), iax2_prune_realtime(), iax2_reload(), load_module(), mgcp_do_reload(), misdn_reload(), reload(), and sip_do_reload().

    01998 {
    01999    int format;
    02000    struct ast_config *cfg;
    02001    struct ast_variable *v;
    02002    struct oh323_peer *peer   = NULL;
    02003    struct oh323_user *user   = NULL;
    02004    struct oh323_alias *alias = NULL;
    02005    struct ast_hostent ahp; struct hostent *hp;
    02006    char *cat;
    02007       char *utype;
    02008
    02009    cfg = ast_config_load(config);
    02010
    02011    /* We *must* have a config file otherwise stop immediately */
    02012    if (!cfg) {
    02013       ast_log(LOG_NOTICE, "Unable to load config %s, H.323 disabled\n", config);
    02014       return 1;
    02015    }
    02016
    02017        /* fire up the H.323 Endpoint */
    02018    if (!h323_end_point_exist()) {
    02019           h323_end_point_create();
    02020    }
    02021    h323debug = 0;
    02022    memset(&bindaddr, 0, sizeof(bindaddr));
    02023    memset(&global_options, 0, sizeof(global_options));
    02024    global_options.dtmfcodec = 101;
    02025    global_options.dtmfmode = H323_DTMF_RFC2833;
    02026    global_options.capability = AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_H261;
    02027    global_options.bridge = 1;    /* Do native bridging by default */
    02028    v = ast_variable_browse(cfg, "general");
    02029    while(v) {
    02030       /* Create the interface list */
    02031       if (!strcasecmp(v->name, "port")) {
    02032          h323_signalling_port = (int)strtol(v->value, NULL, 10);
    02033       } else if (!strcasecmp(v->name, "bindaddr")) {
    02034          if (!(hp = ast_gethostbyname(v->value, &ahp))) {
    02035             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
    02036          } else {
    02037             memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
    02038          }
    02039       } else if (!strcasecmp(v->name, "tos")) {
    02040          if (sscanf(v->value, "%30d", &format)) {
    02041             tos = format & 0xff;
    02042          } else if (!strcasecmp(v->value, "lowdelay")) {
    02043             tos = IPTOS_LOWDELAY;
    02044          } else if (!strcasecmp(v->value, "throughput")) {
    02045             tos = IPTOS_THROUGHPUT;
    02046          } else if (!strcasecmp(v->value, "reliability")) {
    02047             tos = IPTOS_RELIABILITY;
    02048          } else if (!strcasecmp(v->value, "mincost")) {
    02049             tos = IPTOS_MINCOST;
    02050          } else if (!strcasecmp(v->value, "none")) {
    02051             tos = 0;
    02052          } else {
    02053             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
    02054          }
    02055       } else if (!strcasecmp(v->name, "gatekeeper")) {
    02056          if (!strcasecmp(v->value, "DISABLE")) {
    02057             gatekeeper_disable = 1;
    02058             usingGk = 0;
    02059          } else if (!strcasecmp(v->value, "DISCOVER")) {
    02060             gatekeeper_disable = 0;
    02061             gatekeeper_discover = 1;
    02062             usingGk = 1;
    02063          } else {
    02064             gatekeeper_disable = 0;
    02065             usingGk = 1;
    02066             strncpy(gatekeeper, v->value, sizeof(gatekeeper) - 1);
    02067          }
    02068       } else if (!strcasecmp(v->name, "secret")) {
    02069          strncpy(secret, v->value, sizeof(secret) - 1);
    02070       } else if (!strcasecmp(v->name, "AllowGKRouted")) {
    02071          gkroute = ast_true(v->value);
    02072       } else if (!strcasecmp(v->name, "context")) {
    02073          strncpy(default_context, v->value, sizeof(default_context) - 1);
    02074          ast_verbose(VERBOSE_PREFIX_2 "Setting default context to %s\n", default_context);
    02075       } else if (!strcasecmp(v->name, "UserByAlias")) {
    02076          userbyalias = ast_true(v->value);
    02077       } else if (!update_common_options(v, &global_options)) {
    02078          /* dummy */
    02079       }
    02080       v = v->next;
    02081    }
    02082
    02083    cat = ast_category_browse(cfg, NULL);
    02084    while(cat) {
    02085       if (strcasecmp(cat, "general")) {
    02086          utype = ast_variable_retrieve(cfg, cat, "type");
    02087          if (utype) {
    02088             if (!strcasecmp(utype, "user")) {
    02089                user = build_user(cat, ast_variable_browse(cfg, cat));
    02090                if (user) {
    02091                   ast_mutex_lock(&userl.lock);
    02092                   user->next = userl.users;
    02093                   userl.users = user;
    02094                   ast_mutex_unlock(&userl.lock);
    02095                }
    02096             }  else if (!strcasecmp(utype, "peer")) {
    02097                peer = build_peer(cat, ast_variable_browse(cfg, cat));
    02098                if (peer) {
    02099                   ast_mutex_lock(&peerl.lock);
    02100                   peer->next = peerl.peers;
    02101                   peerl.peers = peer;
    02102                   ast_mutex_unlock(&peerl.lock);
    02103                }
    02104             }  else if (!strcasecmp(utype, "friend")) {
    02105                user = build_user(cat, ast_variable_browse(cfg, cat));
    02106                peer = build_peer(cat, ast_variable_browse(cfg, cat));
    02107                if (user) {
    02108                   ast_mutex_lock(&userl.lock);
    02109                   user->next = userl.users;
    02110                   userl.users = user;
    02111                   ast_mutex_unlock(&userl.lock);
    02112                }
    02113                if (peer) {
    02114                   ast_mutex_lock(&peerl.lock);
    02115                   peer->next = peerl.peers;
    02116                   peerl.peers = peer;
    02117                   ast_mutex_unlock(&peerl.lock);
    02118                }
    02119             }  else if (!strcasecmp(utype, "h323") || !strcasecmp(utype, "alias")) {
    02120                alias = build_alias(cat, ast_variable_browse(cfg, cat));
    02121                if (alias) {
    02122                   ast_mutex_lock(&aliasl.lock);
    02123                   alias->next = aliasl.aliases;
    02124                   aliasl.aliases = alias;
    02125                   ast_mutex_unlock(&aliasl.lock);
    02126                }
    02127             } else {
    02128                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config);
    02129             }
    02130          } else {
    02131             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
    02132          }
    02133       }
    02134       cat = ast_category_browse(cfg, cat);
    02135    }
    02136    ast_config_destroy(cfg);
    02137
    02138    /* Register our H.323 aliases if any*/
    02139    while (alias) {
    02140       if (h323_set_alias(alias)) {
    02141          ast_log(LOG_ERROR, "Alias %s rejected by endpoint\n", alias->name);
    02142          return -1;
    02143       }
    02144       alias = alias->next;
    02145    }
    02146
    02147    return 0;
    02148 }

static void reload_firmware | ( | void |  | ) | `[static]`

Definition at line 2318 of file chan_iax2.c.

References ast_config_AST_VAR_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.

Referenced by load_module().

    02319 {
    02320    struct iax_firmware *cur, *curl, *curp;
    02321    DIR *fwd;
    02322    struct dirent *de;
    02323    char dir[256];
    02324    char fn[256];
    02325    /* Mark all as dead */
    02326    ast_mutex_lock(&waresl.lock);
    02327    cur = waresl.wares;
    02328    while(cur) {
    02329       cur->dead = 1;
    02330       cur = cur->next;
    02331    }
    02332    /* Now that we've freed them, load the new ones */
    02333    snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_VAR_DIR);
    02334    fwd = opendir(dir);
    02335    if (fwd) {
    02336       while((de = readdir(fwd))) {
    02337          if (de->d_name[0] != '.') {
    02338             snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
    02339             if (!try_firmware(fn)) {
    02340                if (option_verbose > 1)
    02341                   ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
    02342             }
    02343          }
    02344       }
    02345       closedir(fwd);
    02346    } else
    02347       ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
    02348
    02349    /* Clean up leftovers */
    02350    cur = waresl.wares;
    02351    curp = NULL;
    02352    while(cur) {
    02353       curl = cur;
    02354       cur = cur->next;
    02355       if (curl->dead) {
    02356          if (curp) {
    02357             curp->next = cur;
    02358          } else {
    02359             waresl.wares = cur;
    02360          }
    02361          destroy_firmware(curl);
    02362       } else {
    02363          curp = cur;
    02364       }
    02365    }
    02366    ast_mutex_unlock(&waresl.lock);
    02367 }

static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | `[static]`

Definition at line 1123 of file chan_iax2.c.

References ao2_unlink(), ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.

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

    01124 {
    01125    if (!pvt->peercallno) {
    01126       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
    01127       return;
    01128    }
    01129
    01130    ao2_unlink(iax_peercallno_pvts, pvt);
    01131 }

static int replace_callno | ( | void * | obj | ) | `[static]`

Definition at line 1849 of file chan_iax2.c.

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

    01850 {
    01851    struct callno_entry *callno_entry = (struct callno_entry *) obj;
    01852
    01853    /* the callno_pool container is locked here primarily to ensure thread
    01854     * safety of the total_nonval_callno_used check and decrement */
    01855    ao2_lock(callno_pool);
    01856
    01857    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
    01858       total_nonval_callno_used--;
    01859    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
    01860       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
    01861    }
    01862
    01863    if (callno_entry->callno < TRUNK_CALL_START) {
    01864       ao2_link(callno_pool, callno_entry);
    01865    } else {
    01866       ao2_link(callno_pool_trunk, callno_entry);
    01867    }
    01868    ao2_ref(callno_entry, -1); /* only container ref remains */
    01869
    01870    ao2_unlock(callno_pool);
    01871    return 0;
    01872 }

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

Definition at line 3938 of file chan_iax2.c.

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

Referenced by handle_call_token().

    03939 {
    03940    struct iax2_user *user = NULL;
    03941    struct iax2_peer *peer = NULL;
    03942
    03943    if (ast_strlen_zero(name)) {
    03944       return; /* no username given */
    03945    }
    03946
    03947    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name, 1)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
    03948       user->calltoken_required = CALLTOKEN_YES;
    03949    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
    03950       peer->calltoken_required = CALLTOKEN_YES;
    03951    }
    03952 }

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

Definition at line 3847 of file chan_iax2.c.

References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, ast_iax2_queue::count, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_frame::frametype, ast_iax2_queue::head, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxq, chan_iax2_pvt::iseqno, ast_iax2_queue::lock, iax_frame::next, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, iax_frame::prev, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), ast_frame::subclass, and ast_iax2_queue::tail.

Referenced by socket_read().

    03848 {
    03849    struct chan_iax2_pvt *pvt = iaxs[callno];
    03850    int frametype = f->af.frametype;
    03851    int subclass = f->af.subclass;
    03852    struct {
    03853       struct ast_iax2_full_hdr fh;
    03854       struct iax_ie_data ied;
    03855    } data = {
    03856       .ied.buf = { 0 },
    03857       .ied.pos = 0,
    03858    };
    03859    /* total len - header len gives us the frame's IE len */
    03860    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
    03861
    03862    if (!pvt) {
    03863       return;  /* this should not be possible if called from socket_process() */
    03864    }
    03865
    03866    /*
    03867     * Check to make sure last frame sent is valid for call token resend
    03868     * 1. Frame should _NOT_ already have a destination callno
    03869     * 2. Frame must be a valid iax_frame subclass capable of starting dialog
    03870     * 3. Pvt must have a calltoken_ie_len which represents the number of
    03871     *    bytes at the end of the frame used for the previous calltoken ie.
    03872     * 4. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
    03873     * 5. Total length of f->data must be _LESS_ than size of our data struct
    03874     *    because f->data must be able to fit within data.
    03875     */
    03876    if (f->dcallno || !iax2_allow_new(frametype, subclass, 0)
    03877       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
    03878       (f->datalen > sizeof(data))) {
    03879
    03880       return;  /* ignore resend, token was not valid for the dialog */
    03881    }
    03882
    03883    /* token is valid
    03884     * 1. Copy frame data over
    03885     * 2. Redo calltoken IE, it will always be the last ie in the frame.
    03886     *    NOTE: Having the ie always be last is not protocol specified,
    03887     *    it is only an implementation choice.  Since we only expect the ie to
    03888     *    be last for frames we have sent, this can no way be affected by
    03889     *    another end point.
    03890     * 3. Remove frame from queue
    03891     * 4. Free old frame
    03892     * 5. Clear previous seqnos
    03893     * 6. Resend with CALLTOKEN ie.
    03894     */
    03895
    03896    /* ---1.--- */
    03897    memcpy(&data, f->data, f->datalen);
    03898    data.ied.pos = ie_data_pos;
    03899
    03900    /* ---2.--- */
    03901    /* move to the beginning of the calltoken ie so we can write over it */
    03902    data.ied.pos -= pvt->calltoken_ie_len;
    03903    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
    03904
    03905    /* make sure to update token length incase it ever has to be stripped off again */
    03906    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
    03907
    03908    /* ---3.--- */
    03909    ast_mutex_lock(&iaxq.lock);
    03910    if (f->prev)
    03911       f->prev->next = f->next;
    03912    else
    03913       iaxq.head = f->next;
    03914    if (f->next)
    03915       f->next->prev = f->prev;
    03916    else
    03917       iaxq.tail = f->prev;
    03918    iaxq.count--;
    03919    ast_mutex_unlock(&iaxq.lock);
    03920
    03921    /* ---4.--- */
    03922    iax2_frame_free(f);
    03923
    03924    /* ---5.--- */
    03925    pvt->oseqno = 0;
    03926    pvt->rseqno = 0;
    03927    pvt->iseqno = 0;
    03928    pvt->aseqno = 0;
    03929    if (pvt->peercallno) {
    03930       remove_by_peercallno(pvt);
    03931       pvt->peercallno = 0;
    03932    }
    03933
    03934    /* ---6.--- */
    03935    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
    03936 }

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

Definition at line 7616 of file chan_iax2.c.

References iax_frame::callno, iax_rr::delay, iax_rr::dropped, 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_read().

    07617 {
    07618    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
    07619    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
    07620    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
    07621    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
    07622    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
    07623    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
    07624    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
    07625 }

static void sched_delay_remove | ( | struct sockaddr_in * | sin,
|  | struct callno_entry * | callno_entry |
| ) |  |  | `[static]`

Definition at line 1921 of file chan_iax2.c.

References peercnt::addr, ao2_find(), ao2_ref(), ast_inet_ntoa(), ast_log(), ast_sched_add(), LOG_NOTICE, MIN_REUSE_TIME, option_debug, peercnt_remove_cb(), and replace_callno().

Referenced by pvt_destructor().

    01922 {
    01923    int i;
    01924    struct peercnt *peercnt;
    01925    struct peercnt tmp = {
    01926       .addr = sin->sin_addr.s_addr,
    01927    };
    01928    char iabuf[INET_ADDRSTRLEN];
    01929
    01930    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
    01931       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
    01932       if (option_debug) {
    01933          ast_log(LOG_NOTICE, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), MIN_REUSE_TIME);
    01934       }
    01935       i = ast_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
    01936       if (i == -1) {
    01937          ao2_ref(peercnt, -1);
    01938       }
    01939    }
    01940
    01941    ast_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
    01942 }

static int schedule_delivery | ( | struct iax_frame * | fr,
|  | int | updatehistory,
|  | int | fromtrunk,
|  | unsigned int * | tsout |
| ) |  |  | `[static]`

Definition at line 3121 of file chan_iax2.c.

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, chan_iax2_pvt::frames_dropped, ast_frame::frametype, GAMMA, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, chan_iax2_pvt::last, LOG_DEBUG, match(), MEMORY_SIZE, chan_iax2_pvt::min, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, iax_frame::retrans, chan_iax2_pvt::rxcore, ast_channel::tech, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, unwrap_timestamp(), and update_jbsched().

Referenced by socket_read().

    03122 {
    03123 #ifdef NEWJB
    03124    int type, len;
    03125    int ret;
    03126    int needfree = 0;
    03127 #else
    03128    int x;
    03129    int ms;
    03130    int delay;
    03131    unsigned int orig_ts;
    03132    int drops[MEMORY_SIZE];
    03133    int min, max=0, prevjitterbuffer, maxone=0,y,z, match;
    03134
    03135    /* Remember current jitterbuffer so we can log any change */
    03136    prevjitterbuffer = iaxs[fr->callno]->jitterbuffer;
    03137    /* Similarly for the frame timestamp */
    03138    orig_ts = fr->ts;
    03139 #endif
    03140
    03141 #if 0
    03142    if (option_debug && iaxdebug)
    03143       ast_log(LOG_DEBUG, "schedule_delivery: ts=%d, last=%d, update=%d\n",
    03144             fr->ts, iaxs[fr->callno]->last, updatehistory);
    03145 #endif
    03146
    03147    /* Attempt to recover wrapped timestamps */
    03148    unwrap_timestamp(fr);
    03149
    03150    if (updatehistory) {
    03151 #ifndef NEWJB
    03152
    03153       /* Attempt to spot a change of timebase on timestamps coming from the other side
    03154          We detect by noticing a jump in consecutive timestamps that can't reasonably be explained
    03155          by network jitter or reordering.  Sometimes, also, the peer stops sending us frames
    03156          for a while - in this case this code might also resync us.  But that's not a bad thing.
    03157          Be careful of non-voice frames which are timestamped differently (especially ACKS!)
    03158          [that's why we only do this when updatehistory is true]
    03159       */
    03160       x = fr->ts - iaxs[fr->callno]->last;
    03161       if (x > TS_GAP_FOR_JB_RESYNC || x < -TS_GAP_FOR_JB_RESYNC) {
    03162          if (option_debug && iaxdebug)
    03163             ast_log(LOG_DEBUG, "schedule_delivery: call=%d: TS jumped.  resyncing rxcore (ts=%d, last=%d)\n",
    03164                      fr->callno, fr->ts, iaxs[fr->callno]->last);
    03165          /* zap rxcore - calc_rxstamp will make a new one based on this frame */
    03166          iaxs[fr->callno]->rxcore = ast_tv(0, 0);
    03167          /* wipe "last" if stamps have jumped backwards */
    03168          if (x<0)
    03169             iaxs[fr->callno]->last = 0;
    03170          /* should we also empty history? */
    03171       }
    03172       /* ms is a measure of the "lateness" of the frame relative to the "reference"
    03173          frame we received.  (initially the very first, but also see code just above here).
    03174          Understand that "ms" can easily be -ve if lag improves since the reference frame.
    03175          Called by IAX thread, with iaxsl lock held. */
    03176       ms = calc_rxstamp(iaxs[fr->callno], fr->ts) - fr->ts;
    03177
    03178       /* Rotate our history queue of "lateness".  Don't worry about those initial
    03179          zeros because the first entry will always be zero */
    03180       for (x=0;x<MEMORY_SIZE - 1;x++)
    03181          iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1];
    03182       /* Add a history entry for this one */
    03183       iaxs[fr->callno]->history[x] = ms;
    03184 #endif
    03185    }
    03186 #ifndef NEWJB
    03187    else
    03188       ms = 0;
    03189 #endif
    03190
    03191
    03192    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
    03193    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
    03194       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
    03195    else {
    03196 #if 0
    03197       ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
    03198 #endif
    03199       fr->af.delivery = ast_tv(0,0);
    03200    }
    03201
    03202 #ifndef NEWJB
    03203    /* Initialize the minimum to reasonable values.  It's too much
    03204       work to do the same for the maximum, repeatedly */
    03205    min=iaxs[fr->callno]->history[0];
    03206    for (z=0;z < iax2_dropcount + 1;z++) {
    03207       /* Start very optimistic ;-) */
    03208       max=-999999999;
    03209       for (x=0;x<MEMORY_SIZE;x++) {
    03210          if (max < iaxs[fr->callno]->history[x]) {
    03211             /* We have a candidate new maximum value.  Make
    03212                sure it's not in our drop list */
    03213             match = 0;
    03214             for (y=0;!match && (y<z);y++)
    03215                match |= (drops[y] == x);
    03216             if (!match) {
    03217                /* It's not in our list, use it as the new maximum */
    03218                max = iaxs[fr->callno]->history[x];
    03219                maxone = x;
    03220             }
    03221
    03222          }
    03223          if (!z) {
    03224             /* On our first pass, find the minimum too */
    03225             if (min > iaxs[fr->callno]->history[x])
    03226                min = iaxs[fr->callno]->history[x];
    03227          }
    03228       }
    03229 #if 1
    03230       drops[z] = maxone;
    03231 #endif
    03232    }
    03233 #endif
    03234
    03235 #ifdef NEWJB
    03236    type = JB_TYPE_CONTROL;
    03237    len = 0;
    03238
    03239    if(fr->af.frametype == AST_FRAME_VOICE) {
    03240       type = JB_TYPE_VOICE;
    03241       len = ast_codec_get_samples(&fr->af) / 8;
    03242    } else if(fr->af.frametype == AST_FRAME_CNG) {
    03243       type = JB_TYPE_SILENCE;
    03244    }
    03245
    03246    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
    03247       if (tsout)
    03248          *tsout = fr->ts;
    03249       __do_deliver(fr);
    03250       return -1;
    03251    }
    03252
    03253    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
    03254     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
    03255    if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
    03256        iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
    03257        (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
    03258                 jb_frame frame;
    03259
    03260                 /* deliver any frames in the jb */
    03261                 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK)
    03262                         __do_deliver(frame.data);
    03263
    03264       jb_reset(iaxs[fr->callno]->jb);
    03265
    03266       if (iaxs[fr->callno]->jbid > -1)
    03267                         ast_sched_del(sched, iaxs[fr->callno]->jbid);
    03268
    03269       iaxs[fr->callno]->jbid = -1;
    03270
    03271       /* deliver this frame now */
    03272       if (tsout)
    03273          *tsout = fr->ts;
    03274       __do_deliver(fr);
    03275       return -1;
    03276
    03277    }
    03278
    03279
    03280    /* insert into jitterbuffer */
    03281    /* TODO: Perhaps we could act immediately if it's not droppable and late */
    03282    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
    03283          calc_rxstamp(iaxs[fr->callno],fr->ts));
    03284    if (ret == JB_DROP) {
    03285       needfree++;
    03286    } else if (ret == JB_SCHED) {
    03287       update_jbsched(iaxs[fr->callno]);
    03288    }
    03289 #else
    03290    /* Just for reference, keep the "jitter" value, the difference between the
    03291       earliest and the latest. */
    03292    if (max >= min)
    03293       iaxs[fr->callno]->jitter = max - min;
    03294
    03295    /* IIR filter for keeping track of historic jitter, but always increase
    03296       historic jitter immediately for increase */
    03297
    03298    if (iaxs[fr->callno]->jitter > iaxs[fr->callno]->historicjitter )
    03299       iaxs[fr->callno]->historicjitter = iaxs[fr->callno]->jitter;
    03300    else
    03301       iaxs[fr->callno]->historicjitter = GAMMA * (double)iaxs[fr->callno]->jitter + (1-GAMMA) *
    03302          iaxs[fr->callno]->historicjitter;
    03303
    03304    /* If our jitter buffer is too big (by a significant margin), then we slowly
    03305       shrink it to avoid letting the change be perceived */
    03306    if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer)
    03307       iaxs[fr->callno]->jitterbuffer -= jittershrinkrate;
    03308
    03309    /* If our jitter buffer headroom is too small (by a significant margin), then we slowly enlarge it */
    03310    /* min_jitter_buffer should be SMALLER than max_jitter_buffer - leaving a "no mans land"
    03311       in between - otherwise the jitterbuffer size will hunt up and down causing unnecessary
    03312       disruption.  Set maxexcessbuffer to say 150msec, minexcessbuffer to say 50 */
    03313    if (max > iaxs[fr->callno]->jitterbuffer - min_jitter_buffer)
    03314       iaxs[fr->callno]->jitterbuffer += jittershrinkrate;
    03315
    03316    /* If our jitter buffer is smaller than our maximum delay, grow the jitter
    03317       buffer immediately to accomodate it (and a little more).  */
    03318    if (max > iaxs[fr->callno]->jitterbuffer)
    03319       iaxs[fr->callno]->jitterbuffer = max
    03320          /* + ((float)iaxs[fr->callno]->jitter) * 0.1 */;
    03321
    03322    /* update "min", just for RRs and stats */
    03323    iaxs[fr->callno]->min = min;
    03324
    03325    /* Subtract the lateness from our jitter buffer to know how long to wait
    03326       before sending our packet.  */
    03327    delay = iaxs[fr->callno]->jitterbuffer - ms;
    03328
    03329    /* Whatever happens, no frame waits longer than maxjitterbuffer */
    03330    if (delay > maxjitterbuffer)
    03331       delay = maxjitterbuffer;
    03332
    03333    /* If jitter buffer is disabled then just pretend the frame is "right on time" */
    03334    /* If frame came from trunk, also don't do any delay */
    03335    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) || fromtrunk )
    03336       delay = 0;
    03337
    03338    if (option_debug && iaxdebug) {
    03339       /* Log jitter stats for possible offline analysis */
    03340       ast_log(LOG_DEBUG, "Jitter: call=%d ts=%d orig=%d last=%d %s: min=%d max=%d jb=%d %+d lateness=%d jbdelay=%d jitter=%d historic=%d\n",
    03341                fr->callno, fr->ts, orig_ts, iaxs[fr->callno]->last,
    03342                (fr->af.frametype == AST_FRAME_VOICE) ? "VOICE" : "CONTROL",
    03343                min, max, iaxs[fr->callno]->jitterbuffer,
    03344                iaxs[fr->callno]->jitterbuffer - prevjitterbuffer,
    03345                ms, delay,
    03346                iaxs[fr->callno]->jitter, iaxs[fr->callno]->historicjitter);
    03347    }
    03348
    03349    if (delay < 1) {
    03350       /* Don't deliver it more than 4 ms late */
    03351       if ((delay > -4) || (fr->af.frametype != AST_FRAME_VOICE)) {
    03352          if (option_debug && iaxdebug)
    03353             ast_log(LOG_DEBUG, "schedule_delivery: Delivering immediately (Calculated delay is %d)\n", delay);
    03354          if (tsout)
    03355             *tsout = fr->ts;
    03356          __do_deliver(fr);
    03357          return -1;
    03358       } else {
    03359          if (option_debug && iaxdebug)
    03360             ast_log(LOG_DEBUG, "schedule_delivery: Dropping voice packet since %dms delay is too old\n", delay);
    03361          iaxs[fr->callno]->frames_dropped++;
    03362          needfree++;
    03363       }
    03364    } else {
    03365       if (option_debug && iaxdebug)
    03366          ast_log(LOG_DEBUG, "schedule_delivery: Scheduling delivery in %d ms\n", delay);
    03367       fr->retrans = ast_sched_add(sched, delay, do_deliver, fr);
    03368    }
    03369 #endif
    03370    if (tsout)
    03371       *tsout = fr->ts;
    03372    if (needfree) {
    03373       /* Free our iax frame */
    03374       iax2_frame_free(fr);
    03375       return -1;
    03376    }
    03377    return 0;
    03378 }

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

References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), and iax_ie_data::pos.

Referenced by handle_call_token(), and socket_read().

    03814 {
    03815    struct {
    03816       struct ast_iax2_full_hdr f;
    03817       struct iax_ie_data ied;
    03818    } data;
    03819    size_t size = sizeof(struct ast_iax2_full_hdr);
    03820
    03821    if (ied) {
    03822       size += ied->pos;
    03823       memcpy(&data.ied, ied->buf, ied->pos);
    03824    }
    03825
    03826    data.f.scallno = htons(0x8000 | callno);
    03827    data.f.dcallno = htons(dcallno);
    03828    data.f.ts = htonl(ts);
    03829    data.f.iseqno = seqno;
    03830    data.f.oseqno = 0;
    03831    data.f.type = AST_FRAME_IAX;
    03832    data.f.csub = compress_subclass(command);
    03833
    03834    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
    03835 }

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

Definition at line 5888 of file chan_iax2.c.

References __send_command().

Referenced by attempt_transmit(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), send_lagrq(), send_ping(), and socket_read().

    05889 {
    05890    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
    05891 }

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

Definition at line 5909 of file chan_iax2.c.

References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy_nolock().

Referenced by auth_reject(), authenticate_request(), auto_hangup(), iax2_hangup(), socket_read(), and update_registry().

    05910 {
    05911    /* It is assumed that the callno has already been locked */
    05912    iax2_predestroy_nolock(i->callno);
    05913    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
    05914 }

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

Definition at line 5916 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_read().

    05917 {
    05918    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
    05919 }

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

Definition at line 5893 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), and send_command().

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

    05894 {
    05895    int res;
    05896    ast_mutex_lock(&iaxsl[callno]);
    05897    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
    05898    ast_mutex_unlock(&iaxsl[callno]);
    05899    return res;
    05900 }

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

Definition at line 5921 of file chan_iax2.c.

References __send_command().

Referenced by socket_read(), and try_transfer().

    05922 {
    05923    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
    05924 }

static int send_lagrq | ( | void * | data | ) | `[static]`

Definition at line 937 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_LAGRQ, and send_command().

Referenced by find_callno(), and make_trunk().

    00938 {
    00939    int callno = (long)data;
    00940    int res = 0;
    00941
    00942    /* Ping only if it's real not if it's bridged */
    00943
    00944    ast_mutex_lock(&iaxsl[callno]);
    00945
    00946    while (iaxs[callno]) {
    00947       res = 1;
    00948       if (!iaxs[callno]->peercallno) {
    00949          break;
    00950       }
    00951 #ifdef BRIDGE_OPTIMIZATION
    00952       if (!iaxs[callno]->bridgecallno)
    00953 #endif
    00954          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
    00955       break;
    00956    }
    00957
    00958    ast_mutex_unlock(&iaxsl[callno]);
    00959
    00960    return res;
    00961 }

static int send_packet | ( | struct iax_frame * | f | ) | `[static]`

Definition at line 2447 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), iax_frame::callno, iax_frame::data, iax_frame::datalen, chan_iax2_pvt::error, handle_error(), iax_showframe(), LOG_DEBUG, LOG_WARNING, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::sockfd, chan_iax2_pvt::transfer, iax_frame::transfer, and iax_frame::ts.

Referenced by attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().

    02448 {
    02449    int res;
    02450    char iabuf[INET_ADDRSTRLEN];
    02451    /* Called with iaxsl held */
    02452    if (!iaxs[f->callno])
    02453       return -1;
    02454    if (option_debug > 2 && iaxdebug)
    02455       ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port));
    02456    /* Don't send if there was an error, but return error instead */
    02457    if (!f->callno) {
    02458       ast_log(LOG_WARNING, "Call number = %d\n", f->callno);
    02459       return -1;
    02460    }
    02461    if (iaxs[f->callno]->error)
    02462       return -1;
    02463    if (f->transfer) {
    02464       if (iaxdebug)
    02465          iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
    02466       res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer,
    02467                sizeof(iaxs[f->callno]->transfer));
    02468    } else {
    02469       if (iaxdebug)
    02470          iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
    02471       res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr,
    02472                sizeof(iaxs[f->callno]->addr));
    02473    }
    02474    if (res < 0) {
    02475       if (option_debug && iaxdebug)
    02476          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
    02477       handle_error();
    02478    } else
    02479       res = 0;
    02480    return res;
    02481 }

static int send_ping | ( | void * | data | ) | `[static]`

Definition at line 899 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_PING, and send_command().

Referenced by find_callno(), and make_trunk().

    00900 {
    00901    int callno = (long)data;
    00902    int res = 0;
    00903
    00904    /* Ping only if it's real, not if it's bridged */
    00905
    00906    ast_mutex_lock(&iaxsl[callno]);
    00907
    00908    while (iaxs[callno]) {
    00909       res = 1;
    00910       if (!iaxs[callno]->peercallno) {
    00911          break;
    00912       }
    00913 #ifdef BRIDGE_OPTIMIZATION
    00914       if (!iaxs[callno]->bridgecallno)
    00915 #endif
    00916          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
    00917       break;
    00918    }
    00919
    00920    ast_mutex_unlock(&iaxsl[callno]);
    00921
    00922    return res;
    00923 }

static int send_trunk | ( | struct iax2_trunk_peer * | tpeer,
|  | struct timeval * | now |
| ) |  |  | `[static]`

Definition at line 7281 of file chan_iax2.c.

References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, 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, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, LOG_DEBUG, 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 timing_read().

    07282 {
    07283    int res = 0;
    07284    struct iax_frame *fr;
    07285    struct ast_iax2_meta_hdr *meta;
    07286    struct ast_iax2_meta_trunk_hdr *mth;
    07287    int calls = 0;
    07288
    07289    /* Point to frame */
    07290    fr = (struct iax_frame *)tpeer->trunkdata;
    07291    /* Point to meta data */
    07292    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
    07293    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
    07294    if (tpeer->trunkdatalen) {
    07295       /* We're actually sending a frame, so fill the meta trunk header and meta header */
    07296       meta->zeros = 0;
    07297       meta->metacmd = IAX_META_TRUNK;
    07298       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
    07299          meta->cmddata = IAX_META_TRUNK_MINI;
    07300       else
    07301          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
    07302       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
    07303       /* And the rest of the ast_iax2 header */
    07304       fr->direction = DIRECTION_OUTGRESS;
    07305       fr->retrans = -1;
    07306       fr->transfer = 0;
    07307       /* Any appropriate call will do */
    07308       fr->data = fr->afdata;
    07309       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
    07310       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
    07311       calls = tpeer->calls;
    07312 #if 0
    07313       ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
    07314 #endif
    07315       /* Reset transmit trunk side data */
    07316       tpeer->trunkdatalen = 0;
    07317       tpeer->calls = 0;
    07318    }
    07319    if (res < 0)
    07320       return res;
    07321    return calls;
    07322 }

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

Definition at line 10183 of file chan_iax2.c.

References add_calltoken_ignore(), ast_category_browse(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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_flag, ast_set_flag, ast_str2tos(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_callno_limits(), build_peer(), build_user(), capability, cfg, DEFAULT_MAXMS, format, get_encrypt_methods(), 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_FORCEJITTERBUF, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, iax2_peer::next, iax2_user::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, portno, prefs, reg_source_db(), set_timing(), socket_read(), user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.

Referenced by load_module(), and reload().

    10184 {
    10185    struct ast_config *cfg;
    10186    int capability=iax2_capability;
    10187    struct ast_variable *v;
    10188    char *cat;
    10189    char *utype;
    10190    char *tosval;
    10191    int format;
    10192    int portno = IAX_DEFAULT_PORTNO;
    10193    int  x;
    10194    struct iax2_user *user;
    10195    struct iax2_peer *peer;
    10196    struct ast_netsock *ns;
    10197 #if 0
    10198    static unsigned short int last_port=0;
    10199 #endif
    10200
    10201    cfg = ast_config_load(config_file);
    10202
    10203    if (!cfg) {
    10204       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
    10205       return -1;
    10206    }
    10207
    10208    /* Reset global codec prefs */
    10209    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
    10210
    10211    /* Reset Global Flags */
    10212    memset(&globalflags, 0, sizeof(globalflags));
    10213    ast_set_flag(&globalflags, IAX_RTUPDATE);
    10214
    10215 #ifdef SO_NO_CHECK
    10216    nochecksums = 0;
    10217 #endif
    10218
    10219    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
    10220    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
    10221    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
    10222    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
    10223
    10224    maxauthreq = 0;
    10225
    10226    v = ast_variable_browse(cfg, "general");
    10227
    10228    /* Seed initial tos value */
    10229    tosval = ast_variable_retrieve(cfg, "general", "tos");
    10230    if (tosval) {
    10231       if (ast_str2tos(tosval, &tos))
    10232          ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n");
    10233    }
    10234    while(v) {
    10235       if (!strcasecmp(v->name, "bindport")){
    10236          if (reload)
    10237             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
    10238          else
    10239             portno = atoi(v->value);
    10240       } else if (!strcasecmp(v->name, "pingtime"))
    10241          ping_time = atoi(v->value);
    10242       else if (!strcasecmp(v->name, "nochecksums")) {
    10243 #ifdef SO_NO_CHECK
    10244          if (ast_true(v->value))
    10245             nochecksums = 1;
    10246          else
    10247             nochecksums = 0;
    10248 #else
    10249          if (ast_true(v->value))
    10250             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
    10251 #endif
    10252       }
    10253       else if (!strcasecmp(v->name, "maxjitterbuffer"))
    10254          maxjitterbuffer = atoi(v->value);
    10255 #ifdef NEWJB
    10256       else if (!strcasecmp(v->name, "resyncthreshold"))
    10257          resyncthreshold = atoi(v->value);
    10258       else if (!strcasecmp(v->name, "maxjitterinterps"))
    10259          maxjitterinterps = atoi(v->value);
    10260 #endif
    10261       else if (!strcasecmp(v->name, "jittershrinkrate"))
    10262          jittershrinkrate = atoi(v->value);
    10263       else if (!strcasecmp(v->name, "maxexcessbuffer"))
    10264          max_jitter_buffer = atoi(v->value);
    10265       else if (!strcasecmp(v->name, "minexcessbuffer"))
    10266          min_jitter_buffer = atoi(v->value);
    10267       else if (!strcasecmp(v->name, "lagrqtime"))
    10268          lagrq_time = atoi(v->value);
    10269       else if (!strcasecmp(v->name, "dropcount"))
    10270          iax2_dropcount = atoi(v->value);
    10271       else if (!strcasecmp(v->name, "maxregexpire"))
    10272          max_reg_expire = atoi(v->value);
    10273       else if (!strcasecmp(v->name, "minregexpire"))
    10274          min_reg_expire = atoi(v->value);
    10275       else if (!strcasecmp(v->name, "bindaddr")) {
    10276          if (reload) {
    10277             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
    10278          } else {
    10279             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
    10280                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
    10281             } else {
    10282                if (option_verbose > 1) {
    10283                   if (strchr(v->value, ':'))
    10284                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
    10285                   else
    10286                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
    10287                }
    10288                if (defaultsockfd < 0)
    10289                   defaultsockfd = ast_netsock_sockfd(ns);
    10290                ast_netsock_unref(ns);
    10291             }
    10292          }
    10293       } else if (!strcasecmp(v->name, "authdebug"))
    10294          authdebug = ast_true(v->value);
    10295       else if (!strcasecmp(v->name, "encryption"))
    10296          iax2_encryption = get_encrypt_methods(v->value);
    10297       else if (!strcasecmp(v->name, "notransfer"))
    10298          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
    10299       else if (!strcasecmp(v->name, "codecpriority")) {
    10300          if(!strcasecmp(v->value, "caller"))
    10301             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
    10302          else if(!strcasecmp(v->value, "disabled"))
    10303             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
    10304          else if(!strcasecmp(v->value, "reqonly")) {
    10305             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
    10306             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
    10307          }
    10308       } else if (!strcasecmp(v->name, "jitterbuffer"))
    10309          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
    10310       else if (!strcasecmp(v->name, "forcejitterbuffer"))
    10311          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
    10312       else if (!strcasecmp(v->name, "delayreject"))
    10313          delayreject = ast_true(v->value);
    10314       else if (!strcasecmp(v->name, "mailboxdetail"))
    10315          ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL);
    10316       else if (!strcasecmp(v->name, "allowfwdownload"))
    10317          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
    10318       else if (!strcasecmp(v->name, "rtcachefriends"))
    10319          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
    10320       else if (!strcasecmp(v->name, "rtignoreregexpire"))
    10321          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
    10322       else if (!strcasecmp(v->name, "rtupdate"))
    10323          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
    10324       else if (!strcasecmp(v->name, "trunktimestamps"))
    10325          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
    10326       else if (!strcasecmp(v->name, "rtautoclear")) {
    10327          int i = atoi(v->value);
    10328          if(i > 0)
    10329             global_rtautoclear = i;
    10330          else
    10331             i = 0;
    10332          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
    10333       } else if (!strcasecmp(v->name, "trunkfreq")) {
    10334          trunkfreq = atoi(v->value);
    10335          if (trunkfreq < 10)
    10336             trunkfreq = 10;
    10337       } else if (!strcasecmp(v->name, "autokill")) {
    10338          if (sscanf(v->value, "%30d", &x) == 1) {
    10339             if (x >= 0)
    10340                autokill = x;
    10341             else
    10342                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
    10343          } else if (ast_true(v->value)) {
    10344             autokill = DEFAULT_MAXMS;
    10345          } else {
    10346             autokill = 0;
    10347          }
    10348       } else if (!strcasecmp(v->name, "bandwidth")) {
    10349          if (!strcasecmp(v->value, "low")) {
    10350             capability = IAX_CAPABILITY_LOWBANDWIDTH;
    10351          } else if (!strcasecmp(v->value, "medium")) {
    10352             capability = IAX_CAPABILITY_MEDBANDWIDTH;
    10353          } else if (!strcasecmp(v->value, "high")) {
    10354             capability = IAX_CAPABILITY_FULLBANDWIDTH;
    10355          } else
    10356             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
    10357       } else if (!strcasecmp(v->name, "allow")) {
    10358          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
    10359       } else if (!strcasecmp(v->name, "disallow")) {
    10360          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
    10361       } else if (!strcasecmp(v->name, "register")) {
    10362          iax2_register(v->value, v->lineno);
    10363       } else if (!strcasecmp(v->name, "iaxcompat")) {
    10364          iaxcompat = ast_true(v->value);
    10365       } else if (!strcasecmp(v->name, "regcontext")) {
    10366          ast_copy_string(regcontext, v->value, sizeof(regcontext));
    10367          /* Create context if it doesn't exist already */
    10368          if (!ast_context_find(regcontext))
    10369             ast_context_create(NULL, regcontext, channeltype);
    10370       } else if (!strcasecmp(v->name, "tos")) {
    10371          if (ast_str2tos(v->value, &tos))
    10372             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
    10373       } else if (!strcasecmp(v->name, "accountcode")) {
    10374          ast_copy_string(accountcode, v->value, sizeof(accountcode));
    10375       } else if (!strcasecmp(v->name, "amaflags")) {
    10376          format = ast_cdr_amaflags2int(v->value);
    10377          if (format < 0) {
    10378             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
    10379          } else {
    10380             amaflags = format;
    10381          }
    10382       } else if (!strcasecmp(v->name, "language")) {
    10383                         ast_copy_string(language, v->value, sizeof(language));
    10384       } else if (!strcasecmp(v->name, "maxauthreq")) {
    10385          maxauthreq = atoi(v->value);
    10386          if (maxauthreq < 0)
    10387             maxauthreq = 0;
    10388       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
    10389          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
    10390             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
    10391          }
    10392       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
    10393          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
    10394             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);
    10395          }
    10396       } else if(!strcasecmp(v->name, "calltokenoptional")) {
    10397          if (add_calltoken_ignore(v->value)) {
    10398             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
    10399          }
    10400       }/*else if (strcasecmp(v->name,"type")) */
    10401       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
    10402       v = v->next;
    10403    }
    10404
    10405    if (defaultsockfd < 0) {
    10406       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
    10407          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
    10408       } else {
    10409          if (option_verbose > 1)
    10410             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
    10411          defaultsockfd = ast_netsock_sockfd(ns);
    10412          ast_netsock_unref(ns);
    10413       }
    10414    }
    10415    if (reload) {
    10416       ast_netsock_release(outsock);
    10417       outsock = ast_netsock_list_alloc();
    10418       if (!outsock) {
    10419          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
    10420          return -1;
    10421       }
    10422       ast_netsock_init(outsock);
    10423    }
    10424
    10425    if (min_reg_expire > max_reg_expire) {
    10426       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
    10427          min_reg_expire, max_reg_expire, max_reg_expire);
    10428       min_reg_expire = max_reg_expire;
    10429    }
    10430    iax2_capability = capability;
    10431    cat = ast_category_browse(cfg, NULL);
    10432    while(cat) {
    10433       if (strcasecmp(cat, "general")) {
    10434          utype = ast_variable_retrieve(cfg, cat, "type");
    10435          if (!strcasecmp(cat, "callnumberlimits")) {
    10436             build_callno_limits(ast_variable_browse(cfg, cat));
    10437          } else if (utype) {
    10438             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
    10439                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
    10440                if (user) {
    10441                   ast_mutex_lock(&userl.lock);
    10442                   user->next = userl.users;
    10443                   userl.users = user;
    10444                   ast_mutex_unlock(&userl.lock);
    10445                }
    10446             }
    10447             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
    10448                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
    10449                if (peer) {
    10450                   ast_mutex_lock(&peerl.lock);
    10451                   peer->next = peerl.peers;
    10452                   peerl.peers = peer;
    10453                   ast_mutex_unlock(&peerl.lock);
    10454                   if (ast_test_flag(peer, IAX_DYNAMIC))
    10455                      reg_source_db(peer);
    10456                }
    10457             } else if (strcasecmp(utype, "user")) {
    10458                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
    10459             }
    10460          } else
    10461             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
    10462       }
    10463       cat = ast_category_browse(cfg, cat);
    10464    }
    10465    ast_config_destroy(cfg);
    10466    set_timing();
    10467    return capability;
    10468 }

static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | `[static]`

Definition at line 1486 of file chan_iax2.c.

References peercnt::addr, addr_range_match_address_cb(), ao2_callback(), ao2_ref(), ast_inet_ntoa(), ast_log(), addr_range::limit, peercnt::limit, LOG_NOTICE, option_debug, and peercnt::reg.

Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().

    01487 {
    01488    uint16_t limit = global_maxcallno;
    01489    struct addr_range *addr_range;
    01490    struct sockaddr_in sin = {
    01491       .sin_addr.s_addr = peercnt->addr,
    01492    };
    01493    char iabuf[INET_ADDRSTRLEN];
    01494
    01495
    01496    if (peercnt->reg && peercnt->limit) {
    01497       return; /* this peercnt has a custom limit set by a registration */
    01498    }
    01499
    01500    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
    01501       limit = addr_range->limit;
    01502       if (option_debug) {
    01503          ast_log(LOG_NOTICE, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
    01504       }
    01505       ao2_ref(addr_range, -1);
    01506    }
    01507
    01508    peercnt->limit = limit;
    01509 }

static int set_peercnt_limit_all_cb | ( | void * | obj,
|  | void * | arg,
|  | int | flags |
| ) |  |  | `[static]`

Definition at line 1515 of file chan_iax2.c.

References ast_log(), LOG_NOTICE, option_debug, and set_peercnt_limit().

    01516 {
    01517    struct peercnt *peercnt = obj;
    01518
    01519    set_peercnt_limit(peercnt);
    01520    if (option_debug) {
    01521       ast_log(LOG_NOTICE, "Reset limits for peercnts table\n");
    01522    }
    01523    return 0;
    01524 }

static void set_timing | ( | void |  | ) | `[static]`

Definition at line 10166 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by set_config().

    10167 {
    10168 #ifdef IAX_TRUNKING
    10169    int bs = trunkfreq * 8;
    10170    if (timingfd > -1) {
    10171       if (
    10172 #ifdef ZT_TIMERACK
    10173          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
    10174 #endif
    10175          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
    10176          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
    10177    }
    10178 #endif
    10179 }

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

Definition at line 7627 of file chan_iax2.c.

References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_device_state_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_getformatname(), ast_iax2_new(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, chan_iax2_pvt::bridgecallno, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, chan_iax2_pvt::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, chan_iax2_pvt::cid_num, ast_iax2_meta_hdr::cmddata, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), chan_iax2_pvt::context, ast_iax2_full_hdr::csub, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, chan_iax2_pvt::exten, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), handle_error(), ast_channel::hangupcause, ast_iax2_queue::head, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy_nolock(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_frame(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, 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_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxq, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::inkeys, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, ast_channel::lock, ast_iax2_queue::lock, iax2_trunk_peer::lock, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_debug, option_verbose, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, iax2_dpcache::peer, chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), chan_iax2_pvt::secret, send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), ast_channel::uniqueid, update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros.

Referenced by network_thread(), peer_set_srcaddr(), and set_config().

    07628 {
    07629    struct sockaddr_in sin;
    07630    int res;
    07631    int updatehistory=1;
    07632    int new = NEW_PREVENT;
    07633    unsigned char buf[4096];
    07634    void *ptr;
    07635    socklen_t len = sizeof(sin);
    07636    int dcallno = 0;
    07637    char decrypted = 0;
    07638    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf;
    07639    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf;
    07640    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf;
    07641    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf;
    07642    struct ast_iax2_meta_trunk_hdr *mth;
    07643    struct ast_iax2_meta_trunk_entry *mte;
    07644    struct ast_iax2_meta_trunk_mini *mtm;
    07645    struct iax_frame *fr;
    07646    struct iax_frame *cur;
    07647    char iabuf[INET_ADDRSTRLEN];
    07648    struct ast_frame f;
    07649    struct iax2_dpcache *dp;
    07650    struct iax2_peer *peer;
    07651    struct iax2_trunk_peer *tpeer;
    07652    struct timeval rxtrunktime;
    07653    struct iax_ies ies;
    07654    struct iax_ie_data ied0, ied1;
    07655    int format;
    07656    int exists;
    07657    int minivid = 0;
    07658    unsigned int ts;
    07659    char empty[32]="";      /* Safety measure */
    07660    struct iax_frame *duped_fr;
    07661    char host_pref_buf[128];
    07662    char caller_pref_buf[128];
    07663    struct ast_codec_pref pref;
    07664    char *using_prefs = "mine";
    07665
    07666    /* allocate an iax_frame with 4096 bytes of data buffer */
    07667    fr = alloca(sizeof(*fr) + 4096);
    07668    fr->callno = 0;
    07669    fr->afdatalen = 4096; /* From alloca() above */
    07670
    07671    res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len);
    07672    if (res < 0) {
    07673       if (errno != ECONNREFUSED)
    07674          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
    07675       handle_error();
    07676       return 1;
    07677    }
    07678    if(test_losspct) { /* simulate random loss condition */
    07679       if( (100.0*rand()/(RAND_MAX+1.0)) < test_losspct)
    07680          return 1;
    07681
    07682    }
    07683    if (res < sizeof(*mh)) {
    07684       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
    07685       return 1;
    07686    }
    07687    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
    07688       if (res < sizeof(*vh)) {
    07689          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
    07690          return 1;
    07691       }
    07692
    07693       /* This is a video frame, get call number */
    07694       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd, 0);
    07695       minivid = 1;
    07696    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
    07697       unsigned char metatype;
    07698
    07699       if (res < sizeof(*meta)) {
    07700          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
    07701          return 1;
    07702       }
    07703
    07704       /* This is a meta header */
    07705       switch(meta->metacmd) {
    07706       case IAX_META_TRUNK:
    07707          if (res < (sizeof(*meta) + sizeof(*mth))) {
    07708             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
    07709                sizeof(*meta) + sizeof(*mth));
    07710             return 1;
    07711          }
    07712          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
    07713          ts = ntohl(mth->ts);
    07714          metatype = meta->cmddata;
    07715          res -= (sizeof(*meta) + sizeof(*mth));
    07716          ptr = mth->data;
    07717          tpeer = find_tpeer(&sin, fd);
    07718          if (!tpeer) {
    07719             ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
    07720             return 1;
    07721          }
    07722          tpeer->trunkact = ast_tvnow();
    07723          if (!ts || ast_tvzero(tpeer->rxtrunktime))
    07724             tpeer->rxtrunktime = tpeer->trunkact;
    07725          rxtrunktime = tpeer->rxtrunktime;
    07726          ast_mutex_unlock(&tpeer->lock);
    07727          while(res >= sizeof(*mte)) {
    07728             /* Process channels */
    07729             unsigned short callno, trunked_ts, len;
    07730
    07731             if (metatype == IAX_META_TRUNK_MINI) {
    07732                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
    07733                ptr += sizeof(*mtm);
    07734                res -= sizeof(*mtm);
    07735                len = ntohs(mtm->len);
    07736                callno = ntohs(mtm->mini.callno);
    07737                trunked_ts = ntohs(mtm->mini.ts);
    07738             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
    07739                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
    07740                ptr += sizeof(*mte);
    07741                res -= sizeof(*mte);
    07742                len = ntohs(mte->len);
    07743                callno = ntohs(mte->callno);
    07744                trunked_ts = 0;
    07745             } else {
    07746                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
    07747                break;
    07748             }
    07749             /* Stop if we don't have enough data */
    07750             if (len > res)
    07751                break;
    07752             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd, 0);
    07753             if (fr->callno) {
    07754                ast_mutex_lock(&iaxsl[fr->callno]);
    07755                /* If it's a valid call, deliver the contents.  If not, we
    07756                   drop it, since we don't have a scallno to use for an INVAL */
    07757                /* Process as a mini frame */
    07758                f.frametype = AST_FRAME_VOICE;
    07759                if (iaxs[fr->callno]) {
    07760                   if (iaxs[fr->callno]->voiceformat > 0) {
    07761                      f.subclass = iaxs[fr->callno]->voiceformat;
    07762                      f.datalen = len;
    07763                      if (f.datalen >= 0) {
    07764                         if (f.datalen)
    07765                            f.data = ptr;
    07766                         else
    07767                            f.data = NULL;
    07768                         if(trunked_ts) {
    07769                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
    07770                         } else
    07771                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
    07772                         /* Don't pass any packets until we're started */
    07773                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
    07774                            /* Common things */
    07775                            f.src = "IAX2";
    07776                            f.mallocd = 0;
    07777                            f.offset = 0;
    07778                            if (f.datalen && (f.frametype == AST_FRAME_VOICE))
    07779                               f.samples = ast_codec_get_samples(&f);
    07780                            else
    07781                               f.samples = 0;
    07782                            fr->outoforder = 0;
    07783                            iax_frame_wrap(fr, &f);
    07784 #ifdef BRIDGE_OPTIMIZATION
    07785                            if (iaxs[fr->callno]->bridgecallno) {
    07786                               forward_delivery(fr);
    07787                            } else {
    07788                               duped_fr = iaxfrdup2(fr);
    07789                               if (duped_fr) {
    07790                                  schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
    07791                               }
    07792                            }
    07793 #else
    07794                            duped_fr = iaxfrdup2(fr);
    07795                            if (duped_fr) {
    07796                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
    07797                            }
    07798 #endif
    07799                            if (iaxs[fr->callno]->last < fr->ts) {
    07800                               iaxs[fr->callno]->last = fr->ts;
    07801 #if 1
    07802                               if (option_debug)
    07803                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
    07804 #endif
    07805                            }
    07806                         }
    07807                      } else {
    07808                         ast_log(LOG_WARNING, "Datalen < 0?\n");
    07809                      }
    07810                   } else {
    07811                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
    07812                      iax2_vnak(fr->callno);
    07813                   }
    07814                }
    07815                ast_mutex_unlock(&iaxsl[fr->callno]);
    07816             }
    07817             ptr += len;
    07818             res -= len;
    07819          }
    07820
    07821       }
    07822       return 1;
    07823    }
    07824
    07825 #ifdef DEBUG_SUPPORT
    07826    if (iaxdebug && (res >= sizeof(*fh)))
    07827       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
    07828 #endif
    07829    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
    07830       if (res < sizeof(*fh)) {
    07831          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
    07832          return 1;
    07833       }
    07834
    07835       /* Get the destination call number */
    07836       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
    07837
    07838
    07839       /* check to make sure this full frame isn't encrypted before we attempt
    07840        * to look inside of it. If it is encrypted, decrypt it first. Its ok if the
    07841        * callno is not found here, that just means one hasn't been allocated for
    07842        * this connection yet. */
    07843       if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, 1, fd, 1))) {
    07844          ast_mutex_lock(&iaxsl[fr->callno]);
    07845          if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
    07846             if (decrypt_frame(fr->callno, fh, &f, &res)) {
    07847                ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
    07848                ast_mutex_unlock(&iaxsl[fr->callno]);
    07849                return 1;
    07850             }
    07851             decrypted = 1;
    07852          }
    07853          ast_mutex_unlock(&iaxsl[fr->callno]);
    07854       }
    07855
    07856       /* Retrieve the type and subclass */
    07857       f.frametype = fh->type;
    07858       if (f.frametype == AST_FRAME_VIDEO) {
    07859          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
    07860       } else {
    07861          f.subclass = uncompress_subclass(fh->csub);
    07862       }
    07863
    07864       /* Deal with POKE/PONG without allocating a callno */
    07865       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
    07866          /* Reply back with a PONG, but don't care about the result. */
    07867          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
    07868          return 1;
    07869       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
    07870          /* Ignore */
    07871          return 1;
    07872       }
    07873       f.datalen = res - sizeof(*fh);
    07874       if (f.datalen) {
    07875          if (f.frametype == AST_FRAME_IAX) {
    07876             if (iax_parse_ies(&ies, buf + sizeof(*fh), f.datalen)) {
    07877                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
    07878                return 1;
    07879             }
    07880             f.data = NULL;
    07881             f.datalen = 0;
    07882          } else {
    07883             f.data = buf + sizeof(*fh);
    07884             memset(&ies, 0, sizeof(ies));
    07885          }
    07886       } else {
    07887          if (f.frametype == AST_FRAME_IAX)
    07888             f.data = NULL;
    07889          else
    07890             f.data = empty;
    07891          memset(&ies, 0, sizeof(ies));
    07892       }
    07893
    07894       if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
    07895          /* only set NEW_ALLOW if calltoken checks out */
    07896          if (handle_call_token(fh, &ies, &sin, fd)) {
    07897             return 1;
    07898          }
    07899
    07900          if (ies.calltoken && ies.calltokendata) {
    07901             /* if we've gotten this far, and the calltoken ie data exists,
    07902              * then calltoken validation _MUST_ have taken place.  If calltoken
    07903              * data is provided, it is always validated reguardless of any
    07904              * calltokenoptional or requirecalltoken options */
    07905             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
    07906          } else {
    07907             new = NEW_ALLOW;
    07908          }
    07909       }
    07910    } else {
    07911       /* Don't know anything about it yet */
    07912       f.frametype = AST_FRAME_NULL;
    07913       f.subclass = 0;
    07914    }
    07915
    07916    if (!fr->callno) {
    07917       int check_dcallno = 0;
    07918
    07919       /*
    07920        * We enforce accurate destination call numbers for all full frames except
    07921        * LAGRQ and PING commands.  This is because older versions of Asterisk
    07922        * schedule these commands to get sent very quickly, and they will sometimes
    07923        * be sent before they receive the first frame from the other side.  When
    07924        * that happens, it doesn't contain the destination call number.  However,
    07925        * not checking it for these frames is safe.
    07926        *
    07927        * Discussed in the following thread:
    07928        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html
    07929        */
    07930
    07931       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
    07932          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
    07933       }
    07934
    07935       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd, check_dcallno))) {
    07936          if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
    07937             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
    07938          } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
    07939             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
    07940          }
    07941          return 1;
    07942       }
    07943    }
    07944
    07945    if (fr->callno > 0)
    07946       ast_mutex_lock(&iaxsl[fr->callno]);
    07947
    07948    if (!fr->callno || !iaxs[fr->callno]) {
    07949       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
    07950          frame, reply with an inval */
    07951       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
    07952          /* We can only raw hangup control frames */
    07953          if (((f.subclass != IAX_COMMAND_INVAL) &&
    07954              (f.subclass != IAX_COMMAND_TXCNT) &&
    07955              (f.subclass != IAX_COMMAND_TXACC) &&
    07956              (f.subclass != IAX_COMMAND_FWDOWNL))||
    07957              (f.frametype != AST_FRAME_IAX))
    07958             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
    07959             fd);
    07960       }
    07961       if (fr->callno > 0)
    07962          ast_mutex_unlock(&iaxsl[fr->callno]);
    07963       return 1;
    07964    }
    07965    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
    07966       if (decrypt_frame(fr->callno, fh, &f, &res)) {
    07967          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
    07968          ast_mutex_unlock(&iaxsl[fr->callno]);
    07969          return 1;
    07970       }
    07971       decrypted = 1;
    07972    }
    07973 #ifdef DEBUG_SUPPORT
    07974    if (decrypted && iaxdebug) {
    07975       iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
    07976    }
    07977 #endif
    07978
    07979    /* count this frame */
    07980    iaxs[fr->callno]->frames_received++;
    07981
    07982    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
    07983       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
    07984       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
    07985       unsigned short new_peercallno;
    07986
    07987       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
    07988       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
    07989          if (iaxs[fr->callno]->peercallno) {
    07990             remove_by_peercallno(iaxs[fr->callno]);
    07991          }
    07992          iaxs[fr->callno]->peercallno = new_peercallno;
    07993          store_by_peercallno(iaxs[fr->callno]);
    07994       }
    07995    }
    07996    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
    07997       if (option_debug  && iaxdebug)
    07998          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
    07999       /* Check if it's out of order (and not an ACK or INVAL) */
    08000       fr->oseqno = fh->oseqno;
    08001       fr->iseqno = fh->iseqno;
    08002       fr->ts = ntohl(fh->ts);
    08003 #ifdef IAXTESTS
    08004       if (test_resync) {
    08005          if (option_debug)
    08006             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
    08007          fr->ts += test_resync;
    08008       }
    08009 #endif /* IAXTESTS */
    08010 #if 0
    08011       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
    08012            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
    08013                         (f.subclass == IAX_COMMAND_NEW ||
    08014                          f.subclass == IAX_COMMAND_AUTHREQ ||
    08015                          f.subclass == IAX_COMMAND_ACCEPT ||
    08016                          f.subclass == IAX_COMMAND_REJECT))      ) )
    08017 #endif
    08018       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
    08019          updatehistory = 0;
    08020       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
    08021          (iaxs[fr->callno]->iseqno ||
    08022             ((f.subclass != IAX_COMMAND_TXCNT) &&
    08023             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
    08024             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
    08025             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
    08026             (f.subclass != IAX_COMMAND_TXACC)) ||
    08027             (f.frametype != AST_FRAME_IAX))) {
    08028          if (
    08029           ((f.subclass != IAX_COMMAND_ACK) &&
    08030            (f.subclass != IAX_COMMAND_INVAL) &&
    08031            (f.subclass != IAX_COMMAND_TXCNT) &&
    08032            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
    08033            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
    08034            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
    08035            (f.subclass != IAX_COMMAND_TXACC) &&
    08036            (f.subclass != IAX_COMMAND_VNAK)) ||
    08037            (f.frametype != AST_FRAME_IAX)) {
    08038             /* If it's not an ACK packet, it's out of order. */
    08039             if (option_debug)
    08040                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
    08041                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
    08042             /* Check to see if we need to request retransmission,
    08043              * and take sequence number wraparound into account */
    08044             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
    08045                /* If we've already seen it, ack it XXX There's a border condition here XXX */
    08046                if ((f.frametype != AST_FRAME_IAX) ||
    08047                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
    08048                   if (option_debug)
    08049                      ast_log(LOG_DEBUG, "Acking anyway\n");
    08050                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
    08051                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
    08052                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08053                }
    08054             } else {
    08055                /* Send a VNAK requesting retransmission */
    08056                iax2_vnak(fr->callno);
    08057             }
    08058             ast_mutex_unlock(&iaxsl[fr->callno]);
    08059             return 1;
    08060          }
    08061       } else {
    08062          /* Increment unless it's an ACK or VNAK */
    08063          if (((f.subclass != IAX_COMMAND_ACK) &&
    08064              (f.subclass != IAX_COMMAND_INVAL) &&
    08065              (f.subclass != IAX_COMMAND_TXCNT) &&
    08066              (f.subclass != IAX_COMMAND_TXACC) &&
    08067             (f.subclass != IAX_COMMAND_VNAK)) ||
    08068              (f.frametype != AST_FRAME_IAX))
    08069             iaxs[fr->callno]->iseqno++;
    08070       }
    08071       /* Ensure text frames are NULL-terminated */
    08072       if (f.frametype == AST_FRAME_TEXT && buf[res - 1] != '\0') {
    08073          if (res < sizeof(buf))
    08074             buf[res++] = '\0';
    08075          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
    08076             buf[res - 1] = '\0';
    08077       }
    08078
    08079       /* Handle implicit ACKing unless this is an INVAL, and only if this is
    08080          from the real peer, not the transfer peer */
    08081       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
    08082           ((f.subclass != IAX_COMMAND_INVAL) ||
    08083            (f.frametype != AST_FRAME_IAX))) {
    08084          unsigned char x;
    08085          /* XXX This code is not very efficient.  Surely there is a better way which still
    08086                 properly handles boundary conditions? XXX */
    08087          /* First we have to qualify that the ACKed value is within our window */
    08088          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
    08089             if (fr->iseqno == x)
    08090                break;
    08091          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
    08092             /* The acknowledgement is within our window.  Time to acknowledge everything
    08093                that it says to */
    08094             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
    08095                /* Ack the packet with the given timestamp */
    08096                if (option_debug && iaxdebug)
    08097                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
    08098                ast_mutex_lock(&iaxq.lock);
    08099                for (cur = iaxq.head; cur ; cur = cur->next) {
    08100                   /* If it's our call, and our timestamp, mark -1 retries */
    08101                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
    08102                      cur->retries = -1;
    08103                      /* Destroy call if this is the end */
    08104                      if (cur->final) {
    08105                         if (iaxdebug && option_debug)
    08106                            ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
    08107                         iax2_destroy_nolock(fr->callno);
    08108                      }
    08109                   }
    08110                }
    08111                ast_mutex_unlock(&iaxq.lock);
    08112             }
    08113             /* Note how much we've received acknowledgement for */
    08114             if (iaxs[fr->callno])
    08115                iaxs[fr->callno]->rseqno = fr->iseqno;
    08116             else {
    08117                /* Stop processing now */
    08118                ast_mutex_unlock(&iaxsl[fr->callno]);
    08119                return 1;
    08120             }
    08121          } else
    08122             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
    08123       }
    08124       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
    08125          ((f.frametype != AST_FRAME_IAX) ||
    08126           ((f.subclass != IAX_COMMAND_TXACC) &&
    08127            (f.subclass != IAX_COMMAND_TXCNT)))) {
    08128          /* Only messages we accept from a transfer host are TXACC and TXCNT */
    08129          ast_mutex_unlock(&iaxsl[fr->callno]);
    08130          return 1;
    08131       }
    08132
    08133       /* when we receive the first full frame for a new incoming channel,
    08134          it is safe to start the PBX on the channel because we have now
    08135          completed a 3-way handshake with the peer */
    08136       if ((f.frametype == AST_FRAME_VOICE) ||
    08137           (f.frametype == AST_FRAME_VIDEO) ||
    08138           (f.frametype == AST_FRAME_IAX)) {
    08139          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
    08140             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
    08141             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
    08142                ast_mutex_unlock(&iaxsl[fr->callno]);
    08143                return 1;
    08144             }
    08145          }
    08146       }
    08147
    08148       if (f.frametype == AST_FRAME_VOICE) {
    08149          if (f.subclass != iaxs[fr->callno]->voiceformat) {
    08150                iaxs[fr->callno]->voiceformat = f.subclass;
    08151                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
    08152                if (iaxs[fr->callno]->owner) {
    08153                   int orignative;
    08154 retryowner:
    08155                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
    08156                      ast_mutex_unlock(&iaxsl[fr->callno]);
    08157                      usleep(1);
    08158                      ast_mutex_lock(&iaxsl[fr->callno]);
    08159                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
    08160                   }
    08161                   if (iaxs[fr->callno]) {
    08162                      if (iaxs[fr->callno]->owner) {
    08163                         orignative = iaxs[fr->callno]->owner->nativeformats;
    08164                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
    08165                         if (iaxs[fr->callno]->owner->readformat)
    08166                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
    08167                         iaxs[fr->callno]->owner->nativeformats = orignative;
    08168                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
    08169                      }
    08170                   } else {
    08171                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
    08172                      ast_mutex_unlock(&iaxsl[fr->callno]);
    08173                      return 1;
    08174                   }
    08175                }
    08176          }
    08177       }
    08178       if (f.frametype == AST_FRAME_VIDEO) {
    08179          if (f.subclass != iaxs[fr->callno]->videoformat) {
    08180             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
    08181             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
    08182          }
    08183       }
    08184       if (f.frametype == AST_FRAME_IAX) {
    08185          if (iaxs[fr->callno]->initid > -1) {
    08186             /* Don't auto congest anymore since we've gotten something usefulb ack */
    08187             ast_sched_del(sched, iaxs[fr->callno]->initid);
    08188             iaxs[fr->callno]->initid = -1;
    08189          }
    08190          /* Handle the IAX pseudo frame itself */
    08191          if (option_debug && iaxdebug)
    08192             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
    08193
    08194                         /* Update last ts unless the frame's timestamp originated with us. */
    08195          if (iaxs[fr->callno]->last < fr->ts &&
    08196                             f.subclass != IAX_COMMAND_ACK &&
    08197                             f.subclass != IAX_COMMAND_PONG &&
    08198                             f.subclass != IAX_COMMAND_LAGRP) {
    08199             iaxs[fr->callno]->last = fr->ts;
    08200             if (option_debug && iaxdebug)
    08201                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
    08202          }
    08203
    08204          switch(f.subclass) {
    08205          case IAX_COMMAND_ACK:
    08206             /* Do nothing */
    08207             break;
    08208          case IAX_COMMAND_QUELCH:
    08209             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
    08210                     /* Generate Manager Hold event, if necessary*/
    08211                if (iaxs[fr->callno]->owner) {
    08212                   manager_event(EVENT_FLAG_CALL, "Hold",
    08213                      "Channel: %s\r\n"
    08214                      "Uniqueid: %s\r\n",
    08215                      iaxs[fr->callno]->owner->name,
    08216                      iaxs[fr->callno]->owner->uniqueid);
    08217                }
    08218
    08219                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
    08220                if (ies.musiconhold) {
    08221                   if (iaxs[fr->callno]->owner &&
    08222                      ast_bridged_channel(iaxs[fr->callno]->owner))
    08223                         ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL);
    08224                }
    08225             }
    08226             break;
    08227          case IAX_COMMAND_UNQUELCH:
    08228             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
    08229                     /* Generate Manager Unhold event, if necessary*/
    08230                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
    08231                   manager_event(EVENT_FLAG_CALL, "Unhold",
    08232                      "Channel: %s\r\n"
    08233                      "Uniqueid: %s\r\n",
    08234                      iaxs[fr->callno]->owner->name,
    08235                      iaxs[fr->callno]->owner->uniqueid);
    08236                }
    08237
    08238                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
    08239                if (iaxs[fr->callno]->owner &&
    08240                   ast_bridged_channel(iaxs[fr->callno]->owner))
    08241                      ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner));
    08242             }
    08243             break;
    08244          case IAX_COMMAND_TXACC:
    08245             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
    08246                /* Ack the packet with the given timestamp */
    08247                ast_mutex_lock(&iaxq.lock);
    08248                for (cur = iaxq.head; cur ; cur = cur->next) {
    08249                   /* Cancel any outstanding txcnt's */
    08250                   if ((fr->callno == cur->callno) && (cur->transfer))
    08251                      cur->retries = -1;
    08252                }
    08253                ast_mutex_unlock(&iaxq.lock);
    08254                memset(&ied1, 0, sizeof(ied1));
    08255                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
    08256                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
    08257                iaxs[fr->callno]->transferring = TRANSFER_READY;
    08258             }
    08259             break;
    08260          case IAX_COMMAND_NEW:
    08261             /* Ignore if it's already up */
    08262             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
    08263                break;
    08264             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
    08265                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
    08266             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
    08267             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
    08268                int new_callno;
    08269                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
    08270                   fr->callno = new_callno;
    08271             }
    08272             /* For security, always ack immediately */
    08273             if (delayreject)
    08274                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08275             if (check_access(fr->callno, &sin, &ies)) {
    08276                /* They're not allowed on */
    08277                auth_fail(fr->callno, IAX_COMMAND_REJECT);
    08278                if (authdebug)
    08279                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
    08280                break;
    08281             }
    08282             /* This might re-enter the IAX code and need the lock */
    08283             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
    08284                ast_mutex_unlock(&iaxsl[fr->callno]);
    08285                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
    08286                ast_mutex_lock(&iaxsl[fr->callno]);
    08287             } else
    08288                exists = 0;
    08289             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
    08290                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
    08291                   memset(&ied0, 0, sizeof(ied0));
    08292                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
    08293                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
    08294                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08295                   if (authdebug)
    08296                      ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
    08297                } else {
    08298                   /* Select an appropriate format */
    08299
    08300                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
    08301                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
    08302                         using_prefs = "reqonly";
    08303                      } else {
    08304                         using_prefs = "disabled";
    08305                      }
    08306                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
    08307                      memset(&pref, 0, sizeof(pref));
    08308                      strcpy(caller_pref_buf, "disabled");
    08309                      strcpy(host_pref_buf, "disabled");
    08310                   } else {
    08311                      using_prefs = "mine";
    08312                      /* If the information elements are in here... use them */
    08313                      if (ies.codec_prefs)
    08314                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
    08315                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
    08316                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
    08317                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
    08318                            pref = iaxs[fr->callno]->rprefs;
    08319                            using_prefs = "caller";
    08320                         } else {
    08321                            pref = iaxs[fr->callno]->prefs;
    08322                         }
    08323                      } else
    08324                         pref = iaxs[fr->callno]->prefs;
    08325
    08326                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
    08327                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
    08328                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
    08329                   }
    08330                   if (!format) {
    08331                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
    08332                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
    08333                      if (!format) {
    08334                         memset(&ied0, 0, sizeof(ied0));
    08335                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
    08336                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
    08337                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08338                         if (authdebug) {
    08339                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
    08340                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
    08341                            else
    08342                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
    08343                         }
    08344                      } else {
    08345                         /* Pick one... */
    08346                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
    08347                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
    08348                               format = 0;
    08349                         } else {
    08350                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
    08351                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
    08352                               memset(&pref, 0, sizeof(pref));
    08353                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
    08354                               strcpy(caller_pref_buf,"disabled");
    08355                               strcpy(host_pref_buf,"disabled");
    08356                            } else {
    08357                               using_prefs = "mine";
    08358                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
    08359                                  /* Do the opposite of what we tried above. */
    08360                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
    08361                                     pref = iaxs[fr->callno]->prefs;
    08362                                  } else {
    08363                                     pref = iaxs[fr->callno]->rprefs;
    08364                                     using_prefs = "caller";
    08365                                  }
    08366                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
    08367
    08368                               } else /* if no codec_prefs IE do it the old way */
    08369                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
    08370                            }
    08371                         }
    08372
    08373                         if (!format) {
    08374                            memset(&ied0, 0, sizeof(ied0));
    08375                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
    08376                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
    08377                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
    08378                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08379                            if (authdebug)
    08380                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
    08381                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
    08382                            break;
    08383                         }
    08384                      }
    08385                   }
    08386                   if (format) {
    08387                      /* No authentication required, let them in */
    08388                      memset(&ied1, 0, sizeof(ied1));
    08389                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
    08390                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
    08391                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
    08392                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
    08393                         if (option_verbose > 2)
    08394                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
    08395                                     "%srequested format = %s,\n"
    08396                                     "%srequested prefs = %s,\n"
    08397                                     "%sactual format = %s,\n"
    08398                                     "%shost prefs = %s,\n"
    08399                                     "%spriority = %s\n",
    08400                                     ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr),
    08401                                     VERBOSE_PREFIX_4,
    08402                                     ast_getformatname(iaxs[fr->callno]->peerformat),
    08403                                     VERBOSE_PREFIX_4,
    08404                                     caller_pref_buf,
    08405                                     VERBOSE_PREFIX_4,
    08406                                     ast_getformatname(format),
    08407                                     VERBOSE_PREFIX_4,
    08408                                     host_pref_buf,
    08409                                     VERBOSE_PREFIX_4,
    08410                                     using_prefs);
    08411
    08412                         iaxs[fr->callno]->chosenformat = format;
    08413                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
    08414                      } else {
    08415                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
    08416                         /* If this is a TBD call, we're ready but now what...  */
    08417                         if (option_verbose > 2)
    08418                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
    08419                      }
    08420                   }
    08421                }
    08422                break;
    08423             }
    08424             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
    08425                merge_encryption(iaxs[fr->callno],ies.encmethods);
    08426             else
    08427                iaxs[fr->callno]->encmethods = 0;
    08428             if (!authenticate_request(iaxs[fr->callno]))
    08429                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
    08430             break;
    08431          case IAX_COMMAND_DPREQ:
    08432             /* Request status in the dialplan */
    08433             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
    08434                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
    08435                if (iaxcompat) {
    08436                   /* Spawn a thread for the lookup */
    08437                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
    08438                } else {
    08439                   /* Just look it up */
    08440                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
    08441                }
    08442             }
    08443             break;
    08444          case IAX_COMMAND_HANGUP:
    08445             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
    08446             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
    08447             /* Set hangup cause according to remote */
    08448             if (ies.causecode && iaxs[fr->callno]->owner)
    08449                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
    08450             /* Send ack immediately, before we destroy */
    08451             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08452             iax2_destroy_nolock(fr->callno);
    08453             break;
    08454          case IAX_COMMAND_REJECT:
    08455             memset(&f, 0, sizeof(f));
    08456             f.frametype = AST_FRAME_CONTROL;
    08457             f.subclass = AST_CONTROL_CONGESTION;
    08458
    08459             /* Set hangup cause according to remote */
    08460             if (ies.causecode && iaxs[fr->callno]->owner)
    08461                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
    08462
    08463             iax2_queue_frame(fr->callno, &f);
    08464             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
    08465                /* Send ack immediately, before we destroy */
    08466                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08467                iax2_destroy_nolock(fr->callno);
    08468                break;
    08469             }
    08470             if (iaxs[fr->callno]->owner) {
    08471                if (authdebug)
    08472                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ies.cause ? ies.cause : "<Unknown>");
    08473             }
    08474             ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr->callno);
    08475             /* Send ack immediately, before we destroy */
    08476             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08477             iaxs[fr->callno]->error = EPERM;
    08478             iax2_destroy_nolock(fr->callno);
    08479             break;
    08480          case IAX_COMMAND_TRANSFER:
    08481             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
    08482                if (!strcmp(ies.called_number, ast_parking_ext())) {
    08483                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
    08484                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
    08485                   } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
    08486                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
    08487                } else {
    08488                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
    08489                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name,
    08490                         ies.called_number, iaxs[fr->callno]->context);
    08491                   else
    08492                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name,
    08493                         ies.called_number, iaxs[fr->callno]->context);
    08494                }
    08495             } else
    08496                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
    08497             break;
    08498          case IAX_COMMAND_ACCEPT:
    08499             /* Ignore if call is already up or needs authentication or is a TBD */
    08500             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
    08501                break;
    08502             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
    08503                /* Send ack immediately, before we destroy */
    08504                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08505                iax2_destroy_nolock(fr->callno);
    08506                break;
    08507             }
    08508             if (ies.format) {
    08509                iaxs[fr->callno]->peerformat = ies.format;
    08510             } else {
    08511                if (iaxs[fr->callno]->owner)
    08512                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
    08513                else
    08514                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
    08515             }
    08516             if (option_verbose > 2)
    08517                ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
    08518             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
    08519                memset(&ied0, 0, sizeof(ied0));
    08520                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
    08521                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
    08522                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08523                if (authdebug)
    08524                   ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
    08525             } else {
    08526                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
    08527                if (iaxs[fr->callno]->owner) {
    08528                   /* Switch us to use a compatible format */
    08529                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
    08530                   if (option_verbose > 2)
    08531                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
    08532 retryowner2:
    08533                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
    08534                      ast_mutex_unlock(&iaxsl[fr->callno]);
    08535                      usleep(1);
    08536                      ast_mutex_lock(&iaxsl[fr->callno]);
    08537                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
    08538                   }
    08539
    08540                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
    08541                      /* Setup read/write formats properly. */
    08542                      if (iaxs[fr->callno]->owner->writeformat)
    08543                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
    08544                      if (iaxs[fr->callno]->owner->readformat)
    08545                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
    08546                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
    08547                   }
    08548                }
    08549             }
    08550             ast_mutex_lock(&dpcache_lock);
    08551             dp = iaxs[fr->callno]->dpentries;
    08552             while(dp) {
    08553                if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
    08554                   iax2_dprequest(dp, fr->callno);
    08555                }
    08556                dp = dp->peer;
    08557             }
    08558             ast_mutex_unlock(&dpcache_lock);
    08559             break;
    08560          case IAX_COMMAND_POKE:
    08561             /* Send back a pong packet with the original timestamp */
    08562             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
    08563             break;
    08564          case IAX_COMMAND_PING:
    08565 #ifdef BRIDGE_OPTIMIZATION
    08566             if (iaxs[fr->callno]->bridgecallno) {
    08567                /* If we're in a bridged call, just forward this */
    08568                forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr->ts, NULL, 0, -1);
    08569             } else {
    08570                struct iax_ie_data pingied;
    08571                construct_rr(iaxs[fr->callno], &pingied);
    08572                /* Send back a pong packet with the original timestamp */
    08573                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
    08574             }
    08575 #else
    08576             {
    08577                struct iax_ie_data pingied;
    08578                construct_rr(iaxs[fr->callno], &pingied);
    08579             /* Send back a pong packet with the original timestamp */
    08580                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
    08581             }
    08582 #endif
    08583             break;
    08584          case IAX_COMMAND_PONG:
    08585 #ifdef BRIDGE_OPTIMIZATION
    08586             if (iaxs[fr->callno]->bridgecallno) {
    08587                /* Forward to the other side of the bridge */
    08588                forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
    08589             } else {
    08590                /* Calculate ping time */
    08591                iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
    08592             }
    08593 #else
    08594             /* Calculate ping time */
    08595             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
    08596 #endif
    08597             /* save RR info */
    08598             save_rr(fr, &ies);
    08599
    08600             if (iaxs[fr->callno]->peerpoke) {
    08601                peer = iaxs[fr->callno]->peerpoke;
    08602                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
    08603                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
    08604                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
    08605                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
    08606                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
    08607                   }
    08608                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
    08609                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
    08610                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
    08611                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
    08612                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
    08613                   }
    08614                }
    08615                peer->lastms = iaxs[fr->callno]->pingtime;
    08616                if (peer->smoothing && (peer->lastms > -1))
    08617                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
    08618                else if (peer->smoothing && peer->lastms < 0)
    08619                   peer->historicms = (0 + peer->historicms) / 2;
    08620                else
    08621                   peer->historicms = iaxs[fr->callno]->pingtime;
    08622
    08623                if (peer->pokeexpire > -1)
    08624                   ast_sched_del(sched, peer->pokeexpire);
    08625                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08626                iax2_destroy_nolock(fr->callno);
    08627                peer->callno = 0;
    08628                /* Try again eventually */
    08629                   ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms);
    08630                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms))
    08631                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
    08632                else
    08633                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
    08634             }
    08635             break;
    08636          case IAX_COMMAND_LAGRQ:
    08637          case IAX_COMMAND_LAGRP:
    08638 #ifdef BRIDGE_OPTIMIZATION
    08639             if (iaxs[fr->callno]->bridgecallno) {
    08640                forward_command(iaxs[fr->callno], AST_FRAME_IAX, f.subclass, fr->ts, NULL, 0, -1);
    08641             } else {
    08642 #endif
    08643                f.src = "LAGRQ";
    08644                f.mallocd = 0;
    08645                f.offset = 0;
    08646                f.samples = 0;
    08647                iax_frame_wrap(fr, &f);
    08648                if(f.subclass == IAX_COMMAND_LAGRQ) {
    08649                    /* Received a LAGRQ - echo back a LAGRP */
    08650                    fr->af.subclass = IAX_COMMAND_LAGRP;
    08651                    iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
    08652                } else {
    08653                    /* Received LAGRP in response to our LAGRQ */
    08654                    unsigned int ts;
    08655                    /* This is a reply we've been given, actually measure the difference */
    08656                    ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
    08657                    iaxs[fr->callno]->lag = ts - fr->ts;
    08658                    if (option_debug && iaxdebug)
    08659                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
    08660                         ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
    08661                }
    08662 #ifdef BRIDGE_OPTIMIZATION
    08663             }
    08664 #endif
    08665             break;
    08666          case IAX_COMMAND_AUTHREQ:
    08667             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
    08668                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>");
    08669                break;
    08670             }
    08671             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
    08672                ast_log(LOG_WARNING,
    08673                   "I don't know how to authenticate %s to %s\n",
    08674                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr));
    08675             }
    08676             break;
    08677          case IAX_COMMAND_AUTHREP:
    08678             /* For security, always ack immediately */
    08679             if (delayreject)
    08680                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08681             /* Ignore once we've started */
    08682             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
    08683                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>");
    08684                break;
    08685             }
    08686             if (authenticate_verify(iaxs[fr->callno], &ies)) {
    08687                if (authdebug)
    08688                   ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
    08689                memset(&ied0, 0, sizeof(ied0));
    08690                auth_fail(fr->callno, IAX_COMMAND_REJECT);
    08691                break;
    08692             }
    08693             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
    08694                /* This might re-enter the IAX code and need the lock */
    08695                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
    08696             } else
    08697                exists = 0;
    08698             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
    08699                if (authdebug)
    08700                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
    08701                memset(&ied0, 0, sizeof(ied0));
    08702                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
    08703                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
    08704                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08705             } else {
    08706                /* Select an appropriate format */
    08707                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
    08708                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
    08709                      using_prefs = "reqonly";
    08710                   } else {
    08711                      using_prefs = "disabled";
    08712                   }
    08713                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
    08714                   memset(&pref, 0, sizeof(pref));
    08715                   strcpy(caller_pref_buf, "disabled");
    08716                   strcpy(host_pref_buf, "disabled");
    08717                } else {
    08718                   using_prefs = "mine";
    08719                   if (ies.codec_prefs)
    08720                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
    08721                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
    08722                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
    08723                         pref = iaxs[fr->callno]->rprefs;
    08724                         using_prefs = "caller";
    08725                      } else {
    08726                         pref = iaxs[fr->callno]->prefs;
    08727                      }
    08728                   } else /* if no codec_prefs IE do it the old way */
    08729                      pref = iaxs[fr->callno]->prefs;
    08730
    08731                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
    08732                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
    08733                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
    08734                }
    08735                if (!format) {
    08736                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
    08737                      ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
    08738                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
    08739                   }
    08740                   if (!format) {
    08741                      if (authdebug) {
    08742                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
    08743                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
    08744                         else
    08745                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
    08746                      }
    08747                      memset(&ied0, 0, sizeof(ied0));
    08748                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
    08749                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
    08750                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08751                   } else {
    08752                      /* Pick one... */
    08753                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
    08754                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
    08755                            format = 0;
    08756                      } else {
    08757                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
    08758                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
    08759                            memset(&pref, 0, sizeof(pref));
    08760                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
    08761                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
    08762                            strcpy(caller_pref_buf,"disabled");
    08763                            strcpy(host_pref_buf,"disabled");
    08764                         } else {
    08765                            using_prefs = "mine";
    08766                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
    08767                               /* Do the opposite of what we tried above. */
    08768                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
    08769                                  pref = iaxs[fr->callno]->prefs;
    08770                               } else {
    08771                                  pref = iaxs[fr->callno]->rprefs;
    08772                                  using_prefs = "caller";
    08773                               }
    08774                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
    08775                            } else /* if no codec_prefs IE do it the old way */
    08776                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
    08777                         }
    08778                      }
    08779                      if (!format) {
    08780                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
    08781                         if (authdebug) {
    08782                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
    08783                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
    08784                            else
    08785                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
    08786                         }
    08787                         memset(&ied0, 0, sizeof(ied0));
    08788                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
    08789                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
    08790                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08791                      }
    08792                   }
    08793                }
    08794                if (format) {
    08795                   struct ast_channel *c;
    08796                   /* Authentication received */
    08797                   memset(&ied1, 0, sizeof(ied1));
    08798                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
    08799                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
    08800                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
    08801                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
    08802                      if (option_verbose > 2)
    08803                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
    08804                                  "%srequested format = %s,\n"
    08805                                  "%srequested prefs = %s,\n"
    08806                                  "%sactual format = %s,\n"
    08807                                  "%shost prefs = %s,\n"
    08808                                  "%spriority = %s\n",
    08809                                  ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr),
    08810                                  VERBOSE_PREFIX_4,
    08811                                  ast_getformatname(iaxs[fr->callno]->peerformat),
    08812                                  VERBOSE_PREFIX_4,
    08813                                  caller_pref_buf,
    08814                                  VERBOSE_PREFIX_4,
    08815                                  ast_getformatname(format),
    08816                                  VERBOSE_PREFIX_4,
    08817                                  host_pref_buf,
    08818                                  VERBOSE_PREFIX_4,
    08819                                  using_prefs);
    08820
    08821                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
    08822                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
    08823                         iax2_destroy_nolock(fr->callno);
    08824                   } else {
    08825                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
    08826                      /* If this is a TBD call, we're ready but now what...  */
    08827                      if (option_verbose > 2)
    08828                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
    08829                   }
    08830                }
    08831             }
    08832             break;
    08833          case IAX_COMMAND_DIAL:
    08834             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
    08835                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
    08836                ast_copy_string(iaxs[fr->callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr->callno]->exten));
    08837                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
    08838                   if (authdebug)
    08839                      ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
    08840                   memset(&ied0, 0, sizeof(ied0));
    08841                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
    08842                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
    08843                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08844                } else {
    08845                   struct ast_channel *c;
    08846                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
    08847                   if (option_verbose > 2)
    08848                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat);
    08849                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
    08850                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
    08851                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
    08852                      iax2_destroy_nolock(fr->callno);
    08853                }
    08854             }
    08855             break;
    08856          case IAX_COMMAND_INVAL:
    08857             iaxs[fr->callno]->error = ENOTCONN;
    08858             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
    08859             iax2_destroy_nolock(fr->callno);
    08860             if (option_debug)
    08861                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
    08862             break;
    08863          case IAX_COMMAND_VNAK:
    08864             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
    08865             /* Force retransmission */
    08866             vnak_retransmit(fr->callno, fr->iseqno);
    08867             break;
    08868          case IAX_COMMAND_REGREQ:
    08869          case IAX_COMMAND_REGREL:
    08870             /* For security, always ack immediately */
    08871             if (delayreject)
    08872                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08873             if (register_verify(fr->callno, &sin, &ies)) {
    08874                /* Send delayed failure */
    08875                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
    08876                break;
    08877             }
    08878             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
    08879                if (f.subclass == IAX_COMMAND_REGREL)
    08880                   memset(&sin, 0, sizeof(sin));
    08881                if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
    08882                   ast_log(LOG_WARNING, "Registry error\n");
    08883                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
    08884                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
    08885                break;
    08886             }
    08887             registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
    08888             break;
    08889          case IAX_COMMAND_REGACK:
    08890             if (iax2_ack_registry(&ies, &sin, fr->callno))
    08891                ast_log(LOG_WARNING, "Registration failure\n");
    08892             /* Send ack immediately, before we destroy */
    08893             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08894             iax2_destroy_nolock(fr->callno);
    08895             break;
    08896          case IAX_COMMAND_REGREJ:
    08897             if (iaxs[fr->callno]->reg) {
    08898                if (authdebug) {
    08899                   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(iabuf, sizeof(iabuf), sin.sin_addr));
    08900                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
    08901                }
    08902                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
    08903             }
    08904             /* Send ack immediately, before we destroy */
    08905             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08906             iax2_destroy_nolock(fr->callno);
    08907             break;
    08908          case IAX_COMMAND_REGAUTH:
    08909             /* Authentication request */
    08910             if (registry_rerequest(&ies, fr->callno, &sin)) {
    08911                memset(&ied0, 0, sizeof(ied0));
    08912                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
    08913                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
    08914                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08915             }
    08916             break;
    08917          case IAX_COMMAND_TXREJ:
    08918             iaxs[fr->callno]->transferring = 0;
    08919             if (option_verbose > 2)
    08920                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
    08921             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
    08922             if (iaxs[fr->callno]->bridgecallno) {
    08923                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
    08924                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
    08925                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
    08926                }
    08927             }
    08928             break;
    08929          case IAX_COMMAND_TXREADY:
    08930             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
    08931                iaxs[fr->callno]->transferring = TRANSFER_READY;
    08932                if (option_verbose > 2)
    08933                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
    08934                if (iaxs[fr->callno]->bridgecallno) {
    08935                   if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) {
    08936                      if (option_verbose > 2)
    08937                         ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
    08938                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
    08939
    08940                      /* They're both ready, now release them. */
    08941                      iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
    08942                      iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
    08943                      ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
    08944                      ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
    08945
    08946                      /* Stop doing lag & ping requests */
    08947                      stop_stuff(fr->callno);
    08948                      stop_stuff(iaxs[fr->callno]->bridgecallno);
    08949
    08950                      memset(&ied0, 0, sizeof(ied0));
    08951                      memset(&ied1, 0, sizeof(ied1));
    08952                      iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
    08953                      iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
    08954                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
    08955                      send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
    08956
    08957                   }
    08958                }
    08959             }
    08960             break;
    08961          case IAX_COMMAND_TXREQ:
    08962             try_transfer(iaxs[fr->callno], &ies);
    08963             break;
    08964          case IAX_COMMAND_TXCNT:
    08965             if (iaxs[fr->callno]->transferring)
    08966                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
    08967             break;
    08968          case IAX_COMMAND_TXREL:
    08969             /* Send ack immediately, rather than waiting until we've changed addresses */
    08970             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    08971             complete_transfer(fr->callno, &ies);
    08972             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
    08973             break;
    08974          case IAX_COMMAND_DPREP:
    08975             complete_dpreply(iaxs[fr->callno], &ies);
    08976             break;
    08977          case IAX_COMMAND_UNSUPPORT:
    08978             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
    08979             break;
    08980          case IAX_COMMAND_FWDOWNL:
    08981             /* Firmware download */
    08982             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
    08983                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
    08984                break;
    08985             }
    08986             memset(&ied0, 0, sizeof(ied0));
    08987             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
    08988             if (res < 0)
    08989                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
    08990             else if (res > 0)
    08991                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
    08992             else
    08993                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
    08994             break;
    08995          case IAX_COMMAND_CALLTOKEN:
    08996          {
    08997             struct iax_frame *cur;
    08998             int found = 0;
    08999
    09000             ast_mutex_lock(&iaxq.lock);
    09001             for (cur = iaxq.head; cur ; cur = cur->next) {
    09002                /* find the last sent frame in our frame queue for this callno.
    09003                 * There are many things to take into account before resending this frame.
    09004                 * All of these are taken care of in resend_with_token() */
    09005                if (cur->callno == iaxs[fr->callno]->callno) {
    09006                   found = 1;
    09007                   break;
    09008                }
    09009             }
    09010             ast_mutex_unlock(&iaxq.lock);
    09011             /* find last sent frame */
    09012             if (cur && found && ies.calltoken && ies.calltokendata) {
    09013                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
    09014             }
    09015             break;
    09016          }
    09017          default:
    09018             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
    09019             memset(&ied0, 0, sizeof(ied0));
    09020             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
    09021             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
    09022          }
    09023          /* Don't actually pass these frames along */
    09024          if ((f.subclass != IAX_COMMAND_ACK) &&
    09025            (f.subclass != IAX_COMMAND_TXCNT) &&
    09026            (f.subclass != IAX_COMMAND_TXACC) &&
    09027            (f.subclass != IAX_COMMAND_INVAL) &&
    09028            (f.subclass != IAX_COMMAND_VNAK)) {
    09029             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
    09030                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    09031          }
    09032          ast_mutex_unlock(&iaxsl[fr->callno]);
    09033          return 1;
    09034       }
    09035       /* Unless this is an ACK or INVAL frame, ack it */
    09036       if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
    09037          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
    09038    } else if (minivid) {
    09039       f.frametype = AST_FRAME_VIDEO;
    09040       if (iaxs[fr->callno]->videoformat > 0)
    09041          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
    09042       else {
    09043          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
    09044          iax2_vnak(fr->callno);
    09045          ast_mutex_unlock(&iaxsl[fr->callno]);
    09046          return 1;
    09047       }
    09048       f.datalen = res - sizeof(*vh);
    09049       if (f.datalen)
    09050          f.data = buf + sizeof(*vh);
    09051       else
    09052          f.data = NULL;
    09053 #ifdef IAXTESTS
    09054       if (test_resync) {
    09055          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
    09056       } else
    09057 #endif /* IAXTESTS */
    09058          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
    09059    } else {
    09060       /* A mini frame */
    09061       f.frametype = AST_FRAME_VOICE;
    09062       if (iaxs[fr->callno]->voiceformat > 0)
    09063          f.subclass = iaxs[fr->callno]->voiceformat;
    09064       else {
    09065          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
    09066          iax2_vnak(fr->callno);
    09067          ast_mutex_unlock(&iaxsl[fr->callno]);
    09068          return 1;
    09069       }
    09070       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
    09071       if (f.datalen < 0) {
    09072          ast_log(LOG_WARNING, "Datalen < 0?\n");
    09073          ast_mutex_unlock(&iaxsl[fr->callno]);
    09074          return 1;
    09075       }
    09076       if (f.datalen)
    09077          f.data = buf + sizeof(*mh);
    09078       else
    09079          f.data = NULL;
    09080 #ifdef IAXTESTS
    09081       if (test_resync) {
    09082          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
    09083       } else
    09084 #endif /* IAXTESTS */
    09085       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
    09086       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
    09087    }
    09088    /* Don't pass any packets until we're started */
    09089    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
    09090       ast_mutex_unlock(&iaxsl[fr->callno]);
    09091       return 1;
    09092    }
    09093    /* Common things */
    09094    f.src = "IAX2";
    09095    f.mallocd = 0;
    09096    f.offset = 0;
    09097    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
    09098       f.samples = ast_codec_get_samples(&f);
    09099       /* We need to byteswap incoming slinear samples from network byte order */
    09100       if (f.subclass == AST_FORMAT_SLINEAR)
    09101          ast_frame_byteswap_be(&f);
    09102    } else
    09103       f.samples = 0;
    09104    iax_frame_wrap(fr, &f);
    09105
    09106    /* If this is our most recent packet, use it as our basis for timestamping */
    09107    if (iaxs[fr->callno]->last < fr->ts) {
    09108       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
    09109       fr->outoforder = 0;
    09110    } else {
    09111       if (option_debug && iaxdebug)
    09112          ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
    09113       fr->outoforder = -1;
    09114    }
    09115 #ifdef BRIDGE_OPTIMIZATION
    09116    if (iaxs[fr->callno]->bridgecallno) {
    09117       forward_delivery(fr);
    09118    } else {
    09119       duped_fr = iaxfrdup2(fr);
    09120       if (duped_fr) {
    09121          schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
    09122       }
    09123    }
    09124 #else
    09125    duped_fr = iaxfrdup2(fr);
    09126    if (duped_fr) {
    09127       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
    09128    }
    09129 #endif
    09130
    09131    if (iaxs[fr->callno]->last < fr->ts) {
    09132       iaxs[fr->callno]->last = fr->ts;
    09133 #if 1
    09134       if (option_debug && iaxdebug)
    09135          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
    09136 #endif
    09137    }
    09138
    09139    /* Always run again */
    09140    ast_mutex_unlock(&iaxsl[fr->callno]);
    09141    return 1;
    09142 }

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

Definition at line 7459 of file chan_iax2.c.

References ast_log(), ast_pthread_create, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), LOG_WARNING, malloc, and strdup.

Referenced by socket_read().

    07460 {
    07461    pthread_t newthread;
    07462    struct dpreq_data *dpr;
    07463    dpr = malloc(sizeof(struct dpreq_data));
    07464    if (dpr) {
    07465       pthread_attr_t attr;
    07466
    07467       pthread_attr_init(&attr);
    07468       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    07469
    07470       memset(dpr, 0, sizeof(struct dpreq_data));
    07471       dpr->callno = callno;
    07472       ast_copy_string(dpr->context, context, sizeof(dpr->context));
    07473       ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
    07474       if (callerid)
    07475          dpr->callerid = strdup(callerid);
    07476       if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
    07477          ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
    07478       }
    07479       pthread_attr_destroy(&attr);
    07480    } else
    07481       ast_log(LOG_WARNING, "Out of memory!\n");
    07482 }

static int start_network_thread | ( | void |  | ) | `[static]`

Definition at line 9518 of file chan_iax2.c.

References ast_pthread_create, and network_thread().

Referenced by load_module().

    09519 {
    09520    return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
    09521 }

static int stop_stuff | ( | int | callno | ) | `[static]`

Definition at line 7159 of file chan_iax2.c.

References ast_sched_del(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, and chan_iax2_pvt::pingid.

Referenced by socket_read().

    07160 {
    07161       if (iaxs[callno]->lagid > -1)
    07162          ast_sched_del(sched, iaxs[callno]->lagid);
    07163       iaxs[callno]->lagid = -1;
    07164       if (iaxs[callno]->pingid > -1)
    07165          ast_sched_del(sched, iaxs[callno]->pingid);
    07166       iaxs[callno]->pingid = -1;
    07167       if (iaxs[callno]->autoid > -1)
    07168          ast_sched_del(sched, iaxs[callno]->autoid);
    07169       iaxs[callno]->autoid = -1;
    07170       if (iaxs[callno]->initid > -1)
    07171          ast_sched_del(sched, iaxs[callno]->initid);
    07172       iaxs[callno]->initid = -1;
    07173       if (iaxs[callno]->authid > -1)
    07174          ast_sched_del(sched, iaxs[callno]->authid);
    07175       iaxs[callno]->authid = -1;
    07176 #ifdef NEWJB
    07177       if (iaxs[callno]->jbid > -1)
    07178          ast_sched_del(sched, iaxs[callno]->jbid);
    07179       iaxs[callno]->jbid = -1;
    07180 #endif
    07181       return 0;
    07182 }

static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | `[static]`

Definition at line 1113 of file chan_iax2.c.

References ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.

Referenced by complete_transfer(), find_callno(), and socket_read().

    01114 {
    01115    if (!pvt->peercallno) {
    01116       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
    01117       return;
    01118    }
    01119
    01120    ao2_link(iax_peercallno_pvts, pvt);
    01121 }

static int timing_read | ( | int * | id,
|  | int | fd,
|  | short | events,
|  | void * | cbdata |
| ) |  |  | `[static]`

Definition at line 7332 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, ast_peer_list::lock, LOG_DEBUG, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, peerl, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

    07333 {
    07334    char buf[1024];
    07335    int res;
    07336    char iabuf[INET_ADDRSTRLEN];
    07337    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
    07338    int processed = 0;
    07339    int totalcalls = 0;
    07340 #ifdef ZT_TIMERACK
    07341    int x = 1;
    07342 #endif
    07343    struct timeval now;
    07344    if (iaxtrunkdebug)
    07345       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
    07346    gettimeofday(&now, NULL);
    07347    if (events & AST_IO_PRI) {
    07348 #ifdef ZT_TIMERACK
    07349       /* Great, this is a timing interface, just call the ioctl */
    07350       if (ioctl(fd, ZT_TIMERACK, &x))
    07351          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
    07352       res = 0;
    07353 #endif
    07354    } else {
    07355       /* Read and ignore from the pseudo channel for timing */
    07356       res = read(fd, buf, sizeof(buf));
    07357       if (res < 1) {
    07358          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
    07359          ast_mutex_unlock(&peerl.lock);
    07360          return 1;
    07361       }
    07362    }
    07363    /* For each peer that supports trunking... */
    07364    ast_mutex_lock(&tpeerlock);
    07365    tpeer = tpeers;
    07366    while(tpeer) {
    07367       processed++;
    07368       res = 0;
    07369       ast_mutex_lock(&tpeer->lock);
    07370       /* We can drop a single tpeer per pass.  That makes all this logic
    07371          substantially easier */
    07372       if (!drop && iax2_trunk_expired(tpeer, &now)) {
    07373          /* Take it out of the list, but don't free it yet, because it
    07374             could be in use */
    07375          if (prev)
    07376             prev->next = tpeer->next;
    07377          else
    07378             tpeers = tpeer->next;
    07379          drop = tpeer;
    07380       } else {
    07381          res = send_trunk(tpeer, &now);
    07382          if (iaxtrunkdebug)
    07383             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(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
    07384       }
    07385       totalcalls += res;
    07386       res = 0;
    07387       ast_mutex_unlock(&tpeer->lock);
    07388       prev = tpeer;
    07389       tpeer = tpeer->next;
    07390    }
    07391    ast_mutex_unlock(&tpeerlock);
    07392    if (drop) {
    07393       ast_mutex_lock(&drop->lock);
    07394       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
    07395          because by the time they could get tpeerlock, we've already grabbed it */
    07396       ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), drop->addr.sin_addr), ntohs(drop->addr.sin_port));
    07397       free(drop->trunkdata);
    07398       ast_mutex_unlock(&drop->lock);
    07399       ast_mutex_destroy(&drop->lock);
    07400       free(drop);
    07401
    07402    }
    07403    if (iaxtrunkdebug)
    07404       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
    07405    iaxtrunkdebug =0;
    07406    return 1;
    07407 }

static int transmit_trunk | ( | struct iax_frame * | f,
|  | struct sockaddr_in * | sin,
|  | int | sockfd |
| ) |  |  | `[static]`

Definition at line 2433 of file chan_iax2.c.

References ast_log(), iax_frame::data, iax_frame::datalen, handle_error(), LOG_DEBUG, and option_debug.

Referenced by send_trunk().

    02434 {
    02435    int res;
    02436    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
    02437                sizeof(*sin));
    02438    if (res < 0) {
    02439       if (option_debug)
    02440          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
    02441       handle_error();
    02442    } else
    02443       res = 0;
    02444    return res;
    02445 }

static int try_firmware | ( | char * | s | ) | `[static]`

Definition at line 2115 of file chan_iax2.c.

References ast_log(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, ast_iax2_firmware_header::magic, malloc, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.

Referenced by reload_firmware().

    02116 {
    02117    struct stat stbuf;
    02118    struct iax_firmware *cur;
    02119    int ifd;
    02120    int fd;
    02121    int res;
    02122
    02123    struct ast_iax2_firmware_header *fwh, fwh2;
    02124    struct MD5Context md5;
    02125    unsigned char sum[16];
    02126    unsigned char buf[1024];
    02127    int len, chunk;
    02128    char *s2;
    02129    char *last;
    02130    s2 = alloca(strlen(s) + 100);
    02131    if (!s2) {
    02132       ast_log(LOG_WARNING, "Alloca failed!\n");
    02133       return -1;
    02134    }
    02135    last = strrchr(s, '/');
    02136    if (last)
    02137       last++;
    02138    else
    02139       last = s;
    02140    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)rand());
    02141    res = stat(s, &stbuf);
    02142    if (res < 0) {
    02143       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
    02144       return -1;
    02145    }
    02146    /* Make sure it's not a directory */
    02147    if (S_ISDIR(stbuf.st_mode))
    02148       return -1;
    02149    ifd = open(s, O_RDONLY);
    02150    if (ifd < 0) {
    02151       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
    02152       return -1;
    02153    }
    02154    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
    02155    if (fd < 0) {
    02156       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
    02157       close(ifd);
    02158       return -1;
    02159    }
    02160    /* Unlink our newly created file */
    02161    unlink(s2);
    02162
    02163    /* Now copy the firmware into it */
    02164    len = stbuf.st_size;
    02165    while(len) {
    02166       chunk = len;
    02167       if (chunk > sizeof(buf))
    02168          chunk = sizeof(buf);
    02169       res = read(ifd, buf, chunk);
    02170       if (res != chunk) {
    02171          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
    02172          close(ifd);
    02173          close(fd);
    02174          return -1;
    02175       }
    02176       res = write(fd, buf, chunk);
    02177       if (res != chunk) {
    02178          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
    02179          close(ifd);
    02180          close(fd);
    02181          return -1;
    02182       }
    02183       len -= chunk;
    02184    }
    02185    close(ifd);
    02186    /* Return to the beginning */
    02187    lseek(fd, 0, SEEK_SET);
    02188    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
    02189       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
    02190       close(fd);
    02191       return -1;
    02192    }
    02193    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
    02194       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
    02195       close(fd);
    02196       return -1;
    02197    }
    02198    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
    02199       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
    02200       close(fd);
    02201       return -1;
    02202    }
    02203    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
    02204       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
    02205       close(fd);
    02206       return -1;
    02207    }
    02208    fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    02209    if (fwh == (void *) -1) {
    02210       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
    02211       close(fd);
    02212       return -1;
    02213    }
    02214    MD5Init(&md5);
    02215    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
    02216    MD5Final(sum, &md5);
    02217    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
    02218       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
    02219       munmap(fwh, stbuf.st_size);
    02220       close(fd);
    02221       return -1;
    02222    }
    02223    cur = waresl.wares;
    02224    while(cur) {
    02225       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
    02226          /* Found a candidate */
    02227          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
    02228             /* The version we have on loaded is older, load this one instead */
    02229             break;
    02230          /* This version is no newer than what we have.  Don't worry about it.
    02231             We'll consider it a proper load anyhow though */
    02232          munmap(fwh, stbuf.st_size);
    02233          close(fd);
    02234          return 0;
    02235       }
    02236       cur = cur->next;
    02237    }
    02238    if (!cur) {
    02239       /* Allocate a new one and link it */
    02240       cur = malloc(sizeof(struct iax_firmware));
    02241       if (cur) {
    02242          memset(cur, 0, sizeof(struct iax_firmware));
    02243          cur->fd = -1;
    02244          cur->next = waresl.wares;
    02245          waresl.wares = cur;
    02246       }
    02247    }
    02248    if (cur) {
    02249       if (cur->fwh) {
    02250          munmap(cur->fwh, cur->mmaplen);
    02251       }
    02252       if (cur->fd > -1)
    02253          close(cur->fd);
    02254       cur->fwh = fwh;
    02255       cur->fd = fd;
    02256       cur->mmaplen = stbuf.st_size;
    02257       cur->dead = 0;
    02258    }
    02259    return 0;
    02260 }

static int try_transfer | ( | struct chan_iax2_pvt * | pvt,
|  | struct iax_ies * | ies |
| ) |  |  | `[static]`

Definition at line 6589 of file chan_iax2.c.

References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.

Referenced by socket_read().

    06590 {
    06591    int newcall = 0;
    06592    char newip[256];
    06593    struct iax_ie_data ied;
    06594    struct sockaddr_in new;
    06595
    06596
    06597    memset(&ied, 0, sizeof(ied));
    06598    if (ies->apparent_addr)
    06599       bcopy(ies->apparent_addr, &new, sizeof(new));
    06600    if (ies->callno)
    06601       newcall = ies->callno;
    06602    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
    06603       ast_log(LOG_WARNING, "Invalid transfer request\n");
    06604       return -1;
    06605    }
    06606    pvt->transfercallno = newcall;
    06607    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
    06608    inet_aton(newip, &pvt->transfer.sin_addr);
    06609    pvt->transfer.sin_family = AF_INET;
    06610    pvt->transferring = TRANSFER_BEGIN;
    06611    pvt->transferid = ies->transferid;
    06612    if (ies->transferid)
    06613       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
    06614    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
    06615    return 0;
    06616 }

static int uncompress_subclass | ( | unsigned char | csub | ) | `[static]`

Definition at line 983 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), handle_call_token(), and socket_read().

    00984 {
    00985    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
    00986    if (csub & IAX_FLAG_SC_LOG) {
    00987       /* special case for 'compressed' -1 */
    00988       if (csub == 0xff)
    00989          return -1;
    00990       else
    00991          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
    00992    }
    00993    else
    00994       return csub;
    00995 }

int unload_module | ( | void |  | ) |

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
  Zero on success, or non-zero on error.

Definition at line 11195 of file chan_iax2.c.

References __unload_module(), and ast_custom_function_unregister().

    11196 {
    11197    ast_custom_function_unregister(&iaxpeer_function);
    11198    return __unload_module();
    11199 }

static void unlock_both | ( | unsigned short | callno0,
|  | unsigned short | callno1 |
| ) |  |  | `[static]`

Definition at line 4354 of file chan_iax2.c.

References ast_mutex_unlock().

Referenced by iax2_bridge().

    04355 {
    04356    ast_mutex_unlock(&iaxsl[callno1]);
    04357    ast_mutex_unlock(&iaxsl[callno0]);
    04358 }

static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | `[static]`

Definition at line 3004 of file chan_iax2.c.

References ast_log(), iax_frame::callno, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.

Referenced by schedule_delivery().

    03005 {
    03006    int x;
    03007
    03008    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
    03009       x = fr->ts - iaxs[fr->callno]->last;
    03010       if (x < -50000) {
    03011          /* Sudden big jump backwards in timestamp:
    03012             What likely happened here is that miniframe timestamp has circled but we haven't
    03013             gotten the update from the main packet.  We'll just pretend that we did, and
    03014             update the timestamp appropriately. */
    03015          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
    03016          if (option_debug && iaxdebug)
    03017             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
    03018       }
    03019       if (x > 50000) {
    03020          /* Sudden apparent big jump forwards in timestamp:
    03021             What's likely happened is this is an old miniframe belonging to the previous
    03022             top-16-bit timestamp that has turned up out of order.
    03023             Adjust the timestamp appropriately. */
    03024          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
    03025          if (option_debug && iaxdebug)
    03026             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
    03027       }
    03028    }
    03029 }

static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | `[static]`

Definition at line 3034 of file chan_iax2.c.

References ast_sched_add(), ast_sched_del(), get_from_jb(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.

Referenced by get_from_jb(), and schedule_delivery().

    03034                                                       {
    03035     int when;
    03036
    03037     when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
    03038
    03039     when = jb_next(pvt->jb) - when;
    03040
    03041     if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
    03042
    03043     if(when <= 0) {
    03044       /* XXX should really just empty until when > 0.. */
    03045       when = 1;
    03046     }
    03047
    03048     pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt);
    03049 }

static void update_max_nontrunk | ( | void |  | ) | `[static]`

Definition at line 1316 of file chan_iax2.c.

References ast_log(), LOG_DEBUG, option_debug, and TRUNK_CALL_START.

Referenced by find_callno(), and make_trunk().

    01317 {
    01318    int max = 1;
    01319    int x;
    01320    /* XXX Prolly don't need locks here XXX */
    01321    for (x=1;x<TRUNK_CALL_START - 1; x++) {
    01322       if (iaxs[x])
    01323          max = x + 1;
    01324    }
    01325    maxnontrunkcall = max;
    01326    if (option_debug && iaxdebug)
    01327       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
    01328 }

static void update_max_trunk | ( | void |  | ) | `[static]`

Definition at line 1059 of file chan_iax2.c.

References ast_log(), IAX_MAX_CALLS, LOG_DEBUG, option_debug, and TRUNK_CALL_START.

Referenced by iax2_destroy(), and make_trunk().

    01060 {
    01061    int max = TRUNK_CALL_START;
    01062    int x;
    01063    /* XXX Prolly don't need locks here XXX */
    01064    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
    01065       if (iaxs[x])
    01066          max = x + 1;
    01067    }
    01068    maxtrunkcall = max;
    01069    if (option_debug && iaxdebug)
    01070       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
    01071 }

static int update_packet | ( | struct iax_frame * | f | ) | `[static]`

Definition at line 2566 of file chan_iax2.c.

References iax_frame::callno, iax_frame::data, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, IAX_FLAG_RETRANS, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, and iax_frame::iseqno.

Referenced by attempt_transmit().

    02567 {
    02568    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
    02569    struct ast_iax2_full_hdr *fh = f->data;
    02570    /* Mark this as a retransmission */
    02571    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
    02572    /* Update iseqno */
    02573    f->iseqno = iaxs[f->callno]->iseqno;
    02574    fh->iseqno = f->iseqno;
    02575    return 0;
    02576 }

static int update_registry | ( | char * | name,
|  | struct sockaddr_in * | sin,
|  | int | callno,
|  | char * | devtype,
|  | int | fd,
|  | unsigned short | refresh |
| ) |  |  | `[static]`

Definition at line 6959 of file chan_iax2.c.

References iax2_peer::addr, ast_app_has_voicemail(), ast_app_messagecount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_strlen_zero(), ast_test_flag, ast_verbose(), iax_ie_data::buf, destroy_peer(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, 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_MESSAGEDETAIL, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), iax2_peer::maxcallno, iax2_peer::name, option_verbose, peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.

Referenced by socket_read().

    06960 {
    06961    /* Called from IAX thread only, with proper iaxsl lock */
    06962    struct iax_ie_data ied;
    06963    struct iax2_peer *p;
    06964    int msgcount;
    06965    char data[80];
    06966    char iabuf[INET_ADDRSTRLEN];
    06967    int version;
    06968
    06969    memset(&ied, 0, sizeof(ied));
    06970
    06971    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
    06972    if (!(p = find_peer(name, 1))) {
    06973       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
    06974       return -1;
    06975    }
    06976
    06977    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
    06978       if (sin->sin_addr.s_addr) {
    06979          time_t nowtime;
    06980          time(&nowtime);
    06981          realtime_update_peer(name, sin, nowtime);
    06982       } else
    06983          realtime_update_peer(name, sin, 0);
    06984    }
    06985    if (inaddrcmp(&p->addr, sin)) {
    06986       if (iax2_regfunk)
    06987          iax2_regfunk(p->name, 1);
    06988
    06989       /* modify entry in peercnts table as _not_ registered */
    06990       peercnt_modify(0, 0, &p->addr);
    06991
    06992       /* Stash the IP address from which they registered */
    06993       memcpy(&p->addr, sin, sizeof(p->addr));
    06994       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry);
    06995       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
    06996          ast_db_put("IAX/Registry", p->name, data);
    06997          if  (option_verbose > 2)
    06998             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
    06999                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
    07000          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
    07001          register_peer_exten(p, 1);
    07002          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
    07003       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
    07004          if  (option_verbose > 2)
    07005             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
    07006                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
    07007          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
    07008          register_peer_exten(p, 0);
    07009          ast_db_del("IAX/Registry", p->name);
    07010          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
    07011       }
    07012       /* Update the host */
    07013       /* Verify that the host is really there */
    07014       iax2_poke_peer(p, callno);
    07015    }
    07016
    07017    /* modify entry in peercnts table as registered */
    07018    if (p->maxcallno) {
    07019       peercnt_modify(1, p->maxcallno, &p->addr);
    07020    }
    07021
    07022    /* Store socket fd */
    07023    p->sockfd = fd;
    07024    /* Setup the expiry */
    07025    if (p->expire > -1)
    07026       ast_sched_del(sched, p->expire);
    07027    /* treat an unspecified refresh interval as the minimum */
    07028    if (!refresh)
    07029       refresh = min_reg_expire;
    07030    if (refresh > max_reg_expire) {
    07031       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
    07032          p->name, max_reg_expire, refresh);
    07033       p->expiry = max_reg_expire;
    07034    } else if (refresh < min_reg_expire) {
    07035       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
    07036          p->name, min_reg_expire, refresh);
    07037       p->expiry = min_reg_expire;
    07038    } else {
    07039       p->expiry = refresh;
    07040    }
    07041    if (p->expiry && sin->sin_addr.s_addr)
    07042       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
    07043    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
    07044    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
    07045    if (sin->sin_addr.s_addr) {
    07046       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
    07047       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
    07048       if (!ast_strlen_zero(p->mailbox)) {
    07049          if (ast_test_flag(p, IAX_MESSAGEDETAIL)) {
    07050             int new, old;
    07051             ast_app_messagecount(p->mailbox, &new, &old);
    07052             if (new > 255)
    07053                new = 255;
    07054             if (old > 255)
    07055                old = 255;
    07056             msgcount = (old << 8) | new;
    07057          } else {
    07058             msgcount = ast_app_has_voicemail(p->mailbox, NULL);
    07059             if (msgcount)
    07060                msgcount = 65535;
    07061          }
    07062          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
    07063       }
    07064       if (ast_test_flag(p, IAX_HASCALLERID)) {
    07065          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
    07066          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
    07067       }
    07068    }
    07069    version = iax_check_version(devtype);
    07070    if (version)
    07071       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
    07072    if (ast_test_flag(p, IAX_TEMPONLY))
    07073       destroy_peer(p);
    07074    return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
    07075 }

int usecount | ( | void |  | ) |

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
  The module's usecount.

Definition at line 11372 of file chan_iax2.c.

    11373 {
    11374    return usecnt;
    11375 }

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

Definition at line 7257 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, ast_iax2_queue::head, iaxq, ast_iax2_queue::lock, iax_frame::next, iax_frame::oseqno, and send_packet().

Referenced by socket_read().

    07258 {
    07259    struct iax_frame *f;
    07260    ast_mutex_lock(&iaxq.lock);
    07261    f = iaxq.head;
    07262    while(f) {
    07263       /* Send a copy immediately */
    07264       if ((f->callno == callno) && iaxs[f->callno] &&
    07265          ((unsigned char ) (f->oseqno - last) < 128)) {
    07266          send_packet(f);
    07267       }
    07268       f = f->next;
    07269    }
    07270    ast_mutex_unlock(&iaxq.lock);
    07271 }

## Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE]`[static]`

Definition at line 228 of file chan_iax2.c.

Referenced by tds_log().

int amaflags = 0`[static]`

Definition at line 229 of file chan_iax2.c.

int authdebug = 1`[static]`

Definition at line 164 of file chan_iax2.c.

int autokill = 0`[static]`

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

struct ao2_container* callno_pool`[static]`

table of available call numbers

Definition at line 643 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699`[static]`

Definition at line 648 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk`[static]`

table of available trunk call numbers

Definition at line 646 of file chan_iax2.c.

struct ao2_container* calltoken_ignores`[static]`

Table containing ip addresses not requiring calltoken validation

Definition at line 670 of file chan_iax2.c.

const char channeltype[] = "IAX2"`[static]`

Definition at line 144 of file chan_iax2.c.

char context[80] = "default"`[static]`

Definition at line 146 of file chan_iax2.c.

char debug_jb_usage[]`[static]`

Initial value:

    "Usage: iax2 jb debug\n"
    "       Enables jitterbuffer debugging information\n"

Definition at line 11075 of file chan_iax2.c.

char debug_trunk_usage[]`[static]`

Initial value:

    "Usage: iax2 trunk debug\n"
    "       Requests current status of IAX trunking\n"

Definition at line 11067 of file chan_iax2.c.

char debug_usage[]`[static]`

Initial value:

    "Usage: iax2 debug\n"
    "       Enables dumping of IAX packets for debugging purposes\n"

Definition at line 11059 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048`[static]`

Definition at line 672 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192`[static]`

Definition at line 674 of file chan_iax2.c.

int defaultsockfd = -1`[static]`

Definition at line 182 of file chan_iax2.c.

int delayreject = 0`[static]`

Definition at line 230 of file chan_iax2.c.

const char desc[] = "Inter Asterisk eXchange (Ver 2)"`[static]`

Definition at line 142 of file chan_iax2.c.

struct iax2_dpcache * dpcache`[static]`

Referenced by find_cache(), and iax2_show_cache().

uint16_t global_maxcallno`[static]`

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

int global_rtautoclear = 120`[static]`

Definition at line 279 of file chan_iax2.c.

Referenced by realtime_peer(), reload_config(), and sip_show_settings().

struct ast_flags globalflags = { 0 }`[static]`

Definition at line 233 of file chan_iax2.c.

int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH`[static]`

Definition at line 212 of file chan_iax2.c.

struct ast_cli_entry iax2_cli[]`[static]`

Definition at line 11101 of file chan_iax2.c.

int iax2_dropcount = DEFAULT_DROP`[static]`

Definition at line 214 of file chan_iax2.c.

int iax2_encryption = 0`[static]`

Definition at line 231 of file chan_iax2.c.

enum { ... } iax2_flags

int(* iax2_regfunk)(char *username, int onoff) = NULL

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

char iax2_reload_usage[]`[static]`

Initial value:

    "Usage: iax2 reload\n"
    "       Reloads IAX configuration from iax.conf\n"

Definition at line 11021 of file chan_iax2.c.

enum { ... } iax2_state

struct ast_switch iax2_switch`[static]`

Definition at line 10991 of file chan_iax2.c.

struct ast_channel_tech iax2_tech`[static]`

Definition at line 875 of file chan_iax2.c.

char iax2_test_losspct_usage[]`[static]`

Initial value:

    "Usage: iax2 test losspct <percentage>\n"
    "       For testing, throws away <percentage> percent of incoming packets\n"

Definition at line 11083 of file chan_iax2.c.

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

int iaxcompat = 0`[static]`

Definition at line 166 of file chan_iax2.c.

int iaxdebug = 0`[static]`

Definition at line 216 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60`[static]`

Definition at line 169 of file chan_iax2.c.

int iaxdefaulttimeout = 5`[static]`

Definition at line 171 of file chan_iax2.c.

struct ast_custom_function iaxpeer_function

Definition at line 10929 of file chan_iax2.c.

struct ast_iax2_queue iaxq`[static]`

Referenced by __unload_module(), attempt_transmit(), complete_transfer(), iax2_show_stats(), iax2_transmit(), load_module(), network_thread(), pvt_destructor(), resend_with_token(), socket_read(), and vnak_retransmit().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS]`[static]`

Definition at line 827 of file chan_iax2.c.

Referenced by iax_showframe().

ast_mutex_t iaxsl[IAX_MAX_CALLS]`[static]`

Definition at line 828 of file chan_iax2.c.

int iaxtrunkdebug = 0`[static]`

Definition at line 218 of file chan_iax2.c.

struct io_context* io`[static]`

Definition at line 209 of file chan_iax2.c.

char jitter_usage[]`[static]`

Definition at line 2697 of file chan_iax2.c.

int jittershrinkrate = 2`[static]`

Definition at line 162 of file chan_iax2.c.

int lagrq_time = 10`[static]`

Definition at line 154 of file chan_iax2.c.

char language[MAX_LANGUAGE] = ""`[static]`

Definition at line 148 of file chan_iax2.c.

int lastauthmethod = 0`[static]`

Definition at line 167 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10`[static]`

Definition at line 659 of file chan_iax2.c.

int max_jitter_buffer = MAX_JITTER_BUFFER`[static]`

Definition at line 455 of file chan_iax2.c.

int max_reg_expire`[static]`

Definition at line 176 of file chan_iax2.c.

int max_retries = 4`[static]`

Definition at line 152 of file chan_iax2.c.

int maxauthreq = 0`[static]`

Definition at line 151 of file chan_iax2.c.

int maxjitterbuffer = 1000`[static]`

Definition at line 157 of file chan_iax2.c.

int maxjitterinterps = 10`[static]`

Definition at line 160 of file chan_iax2.c.

int maxnontrunkcall = 1`[static]`

Definition at line 156 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START`[static]`

Definition at line 155 of file chan_iax2.c.

int min_jitter_buffer = MIN_JITTER_BUFFER`[static]`

Definition at line 457 of file chan_iax2.c.

int min_reg_expire`[static]`

Definition at line 175 of file chan_iax2.c.

struct ast_netsock_list* netsock`[static]`

Definition at line 180 of file chan_iax2.c.

pthread_t netthreadid = AST_PTHREADT_NULL`[static]`

Definition at line 235 of file chan_iax2.c.

char no_debug_jb_usage[]`[static]`

Initial value:

    "Usage: iax2 no jb debug\n"
    "       Disables jitterbuffer debugging information\n"

Definition at line 11079 of file chan_iax2.c.

char no_debug_trunk_usage[]`[static]`

Initial value:

    "Usage: iax2 no trunk debug\n"
    "       Requests current status of IAX trunking\n"

Definition at line 11071 of file chan_iax2.c.

char no_debug_usage[]`[static]`

Initial value:

    "Usage: iax2 no debug\n"
    "       Disables dumping of IAX packets for debugging purposes\n"

Definition at line 11063 of file chan_iax2.c.

struct ast_netsock_list* outsock`[static]`

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 181 of file chan_iax2.c.

char* papp = "IAX2Provision"`[static]`

Definition at line 9232 of file chan_iax2.c.

char* pdescrip`[static]`

Initial value:

    "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
    "the calling entity is in fact an IAXy) with the given template or\n"
    "default if one is not specified.  Returns -1 on error or 0 on success.\n"

Definition at line 9234 of file chan_iax2.c.

struct ao2_container* peercnts`[static]`

Table containing peercnt objects for every ip address consuming a callno

Definition at line 664 of file chan_iax2.c.

struct ast_peer_list peerl`[static]`

int ping_time = 20`[static]`

Definition at line 153 of file chan_iax2.c.

struct ast_codec_pref prefs`[static]`

Definition at line 140 of file chan_iax2.c.

Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), reload_config(), set_config(), sip_alloc(), sip_show_settings(), and temp_peer().

char prune_realtime_usage[]`[static]`

Initial value:

    "Usage: iax2 prune realtime [<peername>|all]\n"
    "       Prunes object(s) from the cache\n"

Definition at line 11017 of file chan_iax2.c.

char* psyn = "Provision a calling IAXy with a given template"`[static]`

Definition at line 9233 of file chan_iax2.c.

int randomcalltokendata`[static]`

Definition at line 657 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = ""`[static]`

Definition at line 149 of file chan_iax2.c.

struct iax2_registry* registrations`[static]`

Definition at line 436 of file chan_iax2.c.

int resyncthreshold = 1000`[static]`

Definition at line 159 of file chan_iax2.c.

struct sched_context* sched`[static]`

Definition at line 210 of file chan_iax2.c.

char show_cache_usage[]`[static]`

Initial value:

    "Usage: iax show cache\n"
    "       Display currently cached IAX Dialplan results.\n"

Definition at line 11005 of file chan_iax2.c.

char show_callnumber_usage[]`[static]`

Initial value:

    "Usage: iax2 show callnumber usage <ip optional>\n"
    "       Show current entries in the ip Call Number Limit table.\n"

Definition at line 11013 of file chan_iax2.c.

char show_channels_usage[]`[static]`

Initial value:

    "Usage: iax2 show channels\n"
    "       Lists all currently active IAX channels.\n"

Definition at line 11037 of file chan_iax2.c.

char show_firmware_usage[]`[static]`

Initial value:

    "Usage: iax2 show firmware\n"
    "       Lists all known IAX firmware images.\n"

Definition at line 11051 of file chan_iax2.c.

char show_netstats_usage[]`[static]`

Initial value:

    "Usage: iax2 show netstats\n"
    "       Lists network status for all currently active IAX channels.\n"

Definition at line 11041 of file chan_iax2.c.

char show_peer_usage[]`[static]`

Initial value:

    "Usage: iax show peer <name>\n"
    "       Display details on specific IAX peer\n"

Definition at line 11009 of file chan_iax2.c.

char show_peers_usage[]`[static]`

Initial value:

    "Usage: iax2 show peers [registered] [like <pattern>]\n"
    "       Lists all known IAX2 peers.\n"
    "       Optional 'registered' argument lists only peers with known addresses.\n"
    "       Optional regular expression pattern is used to filter the peer list.\n"

Definition at line 11045 of file chan_iax2.c.

char show_prov_usage[]`[static]`

Definition at line 11025 of file chan_iax2.c.

char show_reg_usage[]`[static]`

Initial value:

    "Usage: iax2 show registry\n"
    "       Lists all registration requests and status.\n"

Definition at line 11055 of file chan_iax2.c.

char show_stats_usage[]`[static]`

Initial value:

    "Usage: iax show stats\n"
    "       Display statistics on IAX channel driver.\n"

Definition at line 11001 of file chan_iax2.c.

char show_users_usage[]`[static]`

Initial value:

    "Usage: iax2 show users [like <pattern>]\n"
    "       Lists all known IAX2 users.\n"
    "       Optional regular expression pattern is used to filter the user list.\n"

Definition at line 11032 of file chan_iax2.c.

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

Definition at line 143 of file chan_iax2.c.

int test_losspct = 0`[static]`

Definition at line 220 of file chan_iax2.c.

int timingfd = -1`[static]`

Definition at line 178 of file chan_iax2.c.

int tos = 0`[static]`

Definition at line 173 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0`[static]`

Definition at line 681 of file chan_iax2.c.

struct iax2_trunk_peer * tpeers`[static]`

Referenced by find_tpeer(), and timing_read().

int trunkfreq = 20`[static]`

Definition at line 163 of file chan_iax2.c.

int usecnt`[static]`

Definition at line 184 of file chan_iax2.c.

struct ast_user_list userl`[static]`

struct ast_firmware_list waresl`[static]`

Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().