Wed Oct 14 15:02:07 2009

Asterisk developer's documentation


chan_iax2.c File Reference

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

#include "asterisk.h"
#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 <sys/ioctl.h>
#include "asterisk/dahdi_compat.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/stringfields.h"
#include "asterisk/linkedlists.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  active_list
struct  addr_range
struct  ast_firmware_list
struct  ast_iax2_queue
struct  callno_entry
struct  chan_iax2_pvt
struct  create_addr_info
struct  dpreq_data
struct  dynamic_list
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_pkt_buf
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  idle_list
struct  parsed_dial_string
struct  peercnt
struct  registrations

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_SCHED_MULTITHREAD
#define DEBUG_SUPPORT
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAX_THREAD_COUNT   100
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_THREAD_COUNT   10
#define DEFAULT_TRUNKDATA   640 * 10
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-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 %s %9s\n"
#define FORMAT2   "%-20.20s %-6.6s %-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 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 & ~AST_FORMAT_AUDIO_UNDEFINED)
#define IAX_CAPABILITY_LOWBANDWIDTH
#define IAX_CAPABILITY_LOWFREE
#define IAX_CAPABILITY_MEDBANDWIDTH
#define IAX_IOSTATE_IDLE   0
#define IAX_IOSTATE_PROCESSING   2
#define IAX_IOSTATE_READY   1
#define IAX_IOSTATE_SCHEDREADY   3
#define IAX_TYPE_DYNAMIC   2
#define IAX_TYPE_POOL   1
#define IPTOS_MINCOST   0x02
#define MARK_IAX_SUBCLASS_TX   0x8000
#define MAX_JITTER_BUFFER   50
#define MAX_PEER_BUCKETS   1
#define MAX_RETRY_TIME   10000
#define MAX_TIMESTAMP_SKEW   160
#define MAX_TRUNKDATA   640 * 200
#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS
#define MEMORY_SIZE   100
#define MIN_JITTER_BUFFER   10
#define MIN_RETRY_TIME   100
#define MIN_REUSE_TIME   60
#define PTR_TO_CALLNO(a)   ((unsigned short)(unsigned long)(a))
#define SCHED_MULTITHREADED
#define schedule_action(func, data)   __schedule_action(func, data, __PRETTY_FUNCTION__)
#define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

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_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_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24),
  IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26)
}
enum  { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 }
enum  calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 }
 Call token validation settings. More...
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED,
  TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS
}

Functions

static void __attempt_transmit (const void *data)
static void __auth_reject (const void *nothing)
static void __auto_congest (const void *nothing)
static void __auto_hangup (const void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (const void *data)
static int __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
static void __get_from_jb (const void *p)
static void __iax2_do_register_s (const void *data)
static void __iax2_poke_noanswer (const void *data)
static void __iax2_poke_peer_s (const void *data)
static int __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[])
static void __reg_module (void)
static int __schedule_action (void(*func)(const void *data), const void *data, const char *funcname)
static int __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final)
static void __send_lagrq (const void *data)
static void __send_ping (const void *data)
static int __unload_module (void)
static void __unreg_module (void)
static int add_calltoken_ignore (const char *addr)
static void add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
static int addr_range_cmp_cb (void *obj, void *arg, int flags)
static int addr_range_delme_cb (void *obj, void *arg, int flags)
static int addr_range_hash_cb (const void *obj, const int flags)
static int addr_range_match_address_cb (void *obj, void *arg, int flags)
static int apply_context (struct iax2_context *con, const char *context)
static int ast_cli_netstats (struct mansession *s, int fd, int limit_fmt)
static struct ast_channelast_iax2_new (int callno, int state, int capability)
 Create new call, interface with the PBX core.
static int attempt_transmit (const void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (const void *data)
static int authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
static int authenticate_request (int call_num)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (const void *data)
static int auto_hangup (const void *data)
static void build_callno_limits (struct ast_variable *v)
static struct iax2_contextbuild_context (char *context)
static void build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static void build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt)
static struct iax2_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create peer structure based on configuration.
static void build_rand_pad (unsigned char *buf, ssize_t len)
static struct iax2_userbuild_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
 Create in-memory user structure from configuration.
static int cache_get_callno_locked (const char *data)
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *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)
 Check if address can be used as packet source.
static int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static char * complete_iax2_show_peer (const char *line, const char *word, int pos, int state)
static int complete_transfer (int callno, struct iax_ies *ies)
static unsigned char compress_subclass (int subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
static int create_callno_pools (void)
static int decode_frame (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 defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here)
 Queue the last read full frame for processing by a certain thread.
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static int encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (const void *data)
static struct iax2_dpcachefind_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
static int find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static int find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame)
static struct iax2_threadfind_idle_thread (void)
static struct iax2_peerfind_peer (const char *name, int realtime)
static struct iax2_trunk_peerfind_tpeer (struct sockaddr_in *sin, int fd)
static struct iax2_userfind_user (const char *name)
static unsigned int fix_peerts (struct timeval *tv, int callno, unsigned int ts)
static void free_context (struct iax2_context *con)
static int 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 (const void *p)
static struct callno_entryget_unused_callno (int trunk, int validated)
static int handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd)
static void handle_deferred_full_frames (struct iax2_thread *thread)
 Handle any deferred full frames for this thread.
static int handle_error (void)
static int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
static int attribute_pure iax2_allow_new (int frametype, int subclass, int inbound)
static 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)
 part of the IAX2 dial plan switch interface
static unsigned int iax2_datetime (const char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_helper (struct chan_iax2_pvt *pvt)
static int iax2_devicestate (void *data)
 Part of the device state notification system ---.
static int iax2_digit_begin (struct ast_channel *c, char digit)
static int iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration)
static int iax2_do_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 (const 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, const char *data)
 Execute IAX2 dialplan switch.
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 switch interface.
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 Part of the IAX2 Switch interface.
static int iax2_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 (const void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_cb (void *obj, void *arg, int flags)
static int iax2_poke_peer_s (const void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (void *data)
static void iax2_process_thread_cleanup (void *data)
static int iax2_prov_app (struct ast_channel *chan, void *data)
static int iax2_prov_cmd (int fd, int argc, char *argv[])
static char * iax2_prov_complete_template_3rd (const char *line, const 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_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame on the ast_channel owner.
static int iax2_queue_frame (int callno, struct ast_frame *f)
 Queue a frame to a call's owning asterisk channel.
static int iax2_queue_hangup (int callno)
 Queue a hangup frame on the ast_channel owner.
static struct ast_frameiax2_read (struct ast_channel *c)
static int iax2_register (char *value, int lineno)
static int iax2_reload (int fd, int argc, char *argv[])
static struct ast_channeliax2_request (const char *type, int format, void *data, int *cause)
static int iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data)
static int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
static int iax2_sendtext (struct ast_channel *c, const char *text)
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int iax2_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[])
 Show one peer in detail.
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_threads (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, int mediaonly)
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_frameiaxfrdup2 (struct iax_frame *fr)
static void insert_idle_thread (struct iax2_thread *thread)
static void jb_debug_output (const char *fmt,...)
static void jb_error_output (const char *fmt,...)
static void jb_warning_output (const char *fmt,...)
static int load_module (void)
 Load IAX2 module, load configuraiton ---.
static int load_objects (void)
static void lock_both (unsigned short callno0, unsigned short callno1)
static int make_trunk (unsigned short callno, int locked)
static int manager_iax2_show_netstats (struct mansession *s, const struct message *m)
static int manager_iax2_show_peers (struct mansession *s, const 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_pvtnew_iax (struct sockaddr_in *sin, const char *host)
static void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_delme_cb (void *obj, void *arg, int flags)
static void peer_destructor (void *obj)
static int peer_hash_cb (const void *obj, const int flags)
static struct iax2_peerpeer_ref (struct iax2_peer *peer)
static int peer_set_sock_cb (void *obj, void *arg, int flags)
static int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
 Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
static int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
static struct iax2_peerpeer_unref (struct iax2_peer *peer)
static int peercnt_add (struct sockaddr_in *sin)
static int peercnt_cmp_cb (void *obj, void *arg, int flags)
static int peercnt_hash_cb (const void *obj, const int flags)
static void peercnt_modify (unsigned char reg, uint16_t limit, struct 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 (const void *obj)
static void poke_all_peers (void)
static int prune_addr_range_cb (void *obj, void *arg, int flags)
static void prune_peers (void)
static void prune_users (void)
static int pvt_cmp_cb (void *obj, void *arg, int flags)
static void pvt_destructor (void *obj)
static int pvt_hash_cb (const void *obj, const int flags)
static int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime)
static struct iax2_userrealtime_user (const char *username, struct sockaddr_in *sin)
static void reg_source_db (struct iax2_peer *p)
static void register_peer_exten (struct iax2_peer *peer, int onoff)
static int register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
 Verify inbound registration.
static int registry_authrequest (int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * regstate2str (int regstate)
static int reload (void)
static int reload_config (void)
static void reload_firmware (int unload)
static void remove_by_peercallno (struct chan_iax2_pvt *pvt)
static void remove_by_transfercallno (struct chan_iax2_pvt *pvt)
static int replace_callno (const void *obj)
static void requirecalltoken_mark_auto (const char *name, int subclass)
static void resend_with_token (int callno, struct iax_frame *f, const char *newtoken)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
static void sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry)
static void * sched_thread (void *ignore)
static int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
static int scheduled_destroy (const void *vid)
static int send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied)
static int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
static int send_lagrq (const void *data)
static int send_packet (struct iax_frame *f)
static int send_ping (const void *data)
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int set_config (const char *config_file, int reload)
 Load configuration.
static void set_config_destroy (void)
static void set_peercnt_limit (struct peercnt *peercnt)
static int set_peercnt_limit_all_cb (void *obj, void *arg, int flags)
static void set_timing (void)
static void signal_condition (ast_mutex_t *lock, ast_cond_t *cond)
static int socket_process (struct iax2_thread *thread)
static int socket_read (int *id, int fd, short events, void *cbdata)
static void spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid)
static int start_network_thread (void)
static void stop_stuff (int callno)
static void store_by_peercallno (struct chan_iax2_pvt *pvt)
static void store_by_transfercallno (struct chan_iax2_pvt *pvt)
static int timing_read (int *id, int fd, short events, void *cbdata)
static int transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags)
static int transfercallno_pvt_hash_cb (const void *obj, const int flags)
static int transmit_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)
static void unlink_peer (struct iax2_peer *peer)
static int unload_module (void)
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static int user_cmp_cb (void *obj, void *arg, int flags)
static int user_delme_cb (void *obj, void *arg, int flags)
static void user_destructor (void *obj)
static int user_hash_cb (const void *obj, const int flags)
static struct iax2_useruser_ref (struct iax2_user *user)
static struct iax2_useruser_unref (struct iax2_user *user)
static void vnak_retransmit (int callno, int last)
static int wait_for_peercallno (struct chan_iax2_pvt *pvt)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, }
static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static const struct ast_module_infoast_module_info = &__mod_info
static int authdebug = 1
static int autokill = 0
static struct ao2_containercallno_limits
static struct ao2_containercallno_pool
static const unsigned int CALLNO_POOL_BUCKETS = 2699
static struct ao2_containercallno_pool_trunk
static struct ao2_containercalltoken_ignores
static struct ast_cli_entry cli_iax2 []
static struct ast_cli_entry cli_iax2_jb_debug_deprecated
static struct ast_cli_entry cli_iax2_no_debug_deprecated
static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated
static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated
static struct ast_cli_entry cli_iax2_trunk_debug_deprecated
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 struct iax2_dpcachedpcache
static ast_mutex_t dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
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 int iax2_encryption = 0
enum { ... }  iax2_flags
int(*) iax2_regfunk (const 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_containeriax_peercallno_pvts
 Another container of iax2_pvt structures.
static struct ao2_containeriax_transfercallno_pvts
 Another container of iax2_pvt structures.
static int iaxactivethreadcount = 0
static int iaxcompat = 0
static int iaxdebug = 0
static int iaxdefaultdpcache = 10 * 60
static int iaxdefaulttimeout = 5
static int iaxdynamicthreadcount = 0
static int iaxdynamicthreadnum = 0
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
ast_custom_function iaxpeer_function
static struct ast_iax2_queue iaxq
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
static ast_mutex_t iaxsl [ARRAY_LEN(iaxs)]
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct io_contextio
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static int last_authmethod = 0
static const time_t MAX_CALLTOKEN_DELAY = 10
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 3
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int maxnontrunkcall = 1
static int maxtrunkcall = TRUNK_CALL_START
static int min_reg_expire
static char mohinterpret [MAX_MUSICCLASS]
static char mohsuggest [MAX_MUSICCLASS]
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static char no_debug_jb_usage []
static char no_debug_trunk_usage []
static char no_debug_usage []
static struct ast_netsock_listoutsock
static char * papp = "IAX2Provision"
static char * pdescrip
static struct ao2_containerpeercnts
static struct ao2_containerpeers
static int ping_time = 21
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 int resyncthreshold = 1000
static struct sched_contextsched
static ast_cond_t sched_cond
static ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static pthread_t schedthreadid = AST_PTHREADT_NULL
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_threads_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 unsigned int tos = 0
static uint16_t total_nonval_callno_used = 0
static ast_mutex_t tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
static struct iax2_trunk_peertpeers
static int trunkfreq = 20
static struct ao2_containerusers
static struct ast_firmware_list waresl


Detailed Description

Implementation of Inter-Asterisk eXchange Version 2.

Author:
Mark Spencer <markster@digium.com>
See also

Definition in file chan_iax2.c.


Define Documentation

#define CACHE_FLAG_CANEXIST   (1 << 2)

Extension can exist

Definition at line 758 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 754 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 768 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 756 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 760 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 762 of file chan_iax2.c.

Referenced by find_cache(), and iax2_show_cache().

#define CACHE_FLAG_TRANSMITTED   (1 << 5)

Request transmitted

Definition at line 764 of file chan_iax2.c.

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

#define CACHE_FLAG_UNKNOWN   (1 << 6)

Timeout

Definition at line 766 of file chan_iax2.c.

Referenced by complete_dpreply(), and iax2_show_cache().

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

Definition at line 123 of file chan_iax2.c.

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

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

Referenced by handle_call_token().

#define CALLTOKEN_IE_FORMAT   "%u?%s"

Referenced by handle_call_token().

#define DEBUG_SCHED_MULTITHREAD

Definition at line 111 of file chan_iax2.c.

#define DEBUG_SUPPORT

Definition at line 131 of file chan_iax2.c.

#define DEFAULT_DROP   3

Definition at line 129 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

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

Referenced by build_peer(), and handle_response_peerpoke().

#define DEFAULT_MAX_THREAD_COUNT   100

Definition at line 126 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000

Definition at line 195 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME   1000

Definition at line 127 of file chan_iax2.c.

Referenced by __find_callno(), and complete_transfer().

#define DEFAULT_THREAD_COUNT   10

Definition at line 125 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10

40ms, uncompressed linear * 10 channels

Definition at line 456 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 %s%s %3s%s\n"

#define FORMAT   "%-20.20s %-6.6s %-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 %s %9s\n"

#define FORMAT2   "%-20.20s %-6.6s %-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 GAMMA   (0.01)

Definition at line 136 of file chan_iax2.c.

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

Definition at line 377 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define IAX_CAPABILITY_FULLBANDWIDTH   (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)

Definition at line 178 of file chan_iax2.c.

Referenced by cache_get_callno_locked(), and set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH

Value:

Definition at line 186 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE

Value:

Definition at line 191 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH

Value:

Definition at line 180 of file chan_iax2.c.

Referenced by set_config().

#define IAX_IOSTATE_IDLE   0

Definition at line 789 of file chan_iax2.c.

Referenced by socket_read().

#define IAX_IOSTATE_PROCESSING   2

Definition at line 791 of file chan_iax2.c.

#define IAX_IOSTATE_READY   1

Definition at line 790 of file chan_iax2.c.

Referenced by socket_read().

#define IAX_IOSTATE_SCHEDREADY   3

Definition at line 792 of file chan_iax2.c.

Referenced by __schedule_action().

#define IAX_TYPE_DYNAMIC   2

Definition at line 795 of file chan_iax2.c.

Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().

#define IAX_TYPE_POOL   1

Definition at line 794 of file chan_iax2.c.

Referenced by start_network_thread().

#define IPTOS_MINCOST   0x02

Definition at line 114 of file chan_iax2.c.

#define MARK_IAX_SUBCLASS_TX   0x8000

Definition at line 465 of file chan_iax2.c.

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

#define MAX_JITTER_BUFFER   50

Definition at line 453 of file chan_iax2.c.

#define MAX_PEER_BUCKETS   1

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

Definition at line 688 of file chan_iax2.c.

Referenced by load_objects(), and set_config().

#define MAX_RETRY_TIME   10000

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

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 457 of file chan_iax2.c.

Referenced by iax2_trunk_queue(), and timing_read().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

Definition at line 693 of file chan_iax2.c.

Referenced by load_objects().

#define MEMORY_SIZE   100

Definition at line 128 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10

Definition at line 454 of file chan_iax2.c.

#define MIN_RETRY_TIME   100

Definition at line 450 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60

Definition at line 133 of file chan_iax2.c.

Referenced by make_trunk(), and sched_delay_remove().

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

Definition at line 122 of file chan_iax2.c.

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

#define SCHED_MULTITHREADED

Definition at line 107 of file chan_iax2.c.

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

Definition at line 1090 of file chan_iax2.c.

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

#define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2

Definition at line 928 of file chan_iax2.c.

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

#define TS_GAP_FOR_JB_RESYNC   5000

Definition at line 462 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 231 of file chan_iax2.c.

00231      {
00232    IAX_STATE_STARTED =        (1 << 0),
00233    IAX_STATE_AUTHENTICATED =  (1 << 1),
00234    IAX_STATE_TBD =            (1 << 2),
00235 } 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_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_TRANSFERMEDIA  When doing IAX2 transfers, transfer media only
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 242 of file chan_iax2.c.

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

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1608 of file chan_iax2.c.

01608      {
01609    /* do not allow a new call number, only search ones in use for match */
01610    NEW_PREVENT = 0,
01611    /* search for match first, then allow a new one to be allocated */
01612    NEW_ALLOW = 1,
01613    /* do not search for match, force a new call number */
01614    NEW_FORCE = 2,
01615    /* do not search for match, force a new call number.  Signifies call number
01616     * has been calltoken validated */
01617    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01618 };

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

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

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

enum iax_transfer_state

Enumerator:
TRANSFER_NONE 
TRANSFER_BEGIN 
TRANSFER_READY 
TRANSFER_RELEASED 
TRANSFER_PASSTHROUGH 
TRANSFER_MBEGIN 
TRANSFER_MREADY 
TRANSFER_MRELEASED 
TRANSFER_MPASSTHROUGH 
TRANSFER_MEDIA 
TRANSFER_MEDIAPASS 

Definition at line 418 of file chan_iax2.c.


Function Documentation

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

Definition at line 2987 of file chan_iax2.c.

References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax2_registry::callno, ast_iax2_queue::count, chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, ast_iax2_queue::queue, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), ast_frame::subclass, update_packet(), and iax2_registry::us.

Referenced by attempt_transmit().

02988 {
02989    /* Attempt to transmit the frame to the remote peer...
02990       Called without iaxsl held. */
02991    struct iax_frame *f = (struct iax_frame *)data;
02992    int freeme=0;
02993    int callno = f->callno;
02994    /* Make sure this call is still active */
02995    if (callno) 
02996       ast_mutex_lock(&iaxsl[callno]);
02997    if (callno && iaxs[callno]) {
02998       if ((f->retries < 0) /* Already ACK'd */ ||
02999           (f->retries >= max_retries) /* Too many attempts */) {
03000             /* Record an error if we've transmitted too many times */
03001             if (f->retries >= max_retries) {
03002                if (f->transfer) {
03003                   /* Transfer timeout */
03004                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03005                } else if (f->final) {
03006                   if (f->final) 
03007                      iax2_destroy(callno);
03008                } else {
03009                   if (iaxs[callno]->owner)
03010                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
03011                   iaxs[callno]->error = ETIMEDOUT;
03012                   if (iaxs[callno]->owner) {
03013                      struct ast_frame fr = { 0, };
03014                      /* Hangup the fd */
03015                      fr.frametype = AST_FRAME_CONTROL;
03016                      fr.subclass = AST_CONTROL_HANGUP;
03017                      iax2_queue_frame(callno, &fr); // XXX
03018                      /* Remember, owner could disappear */
03019                      if (iaxs[callno] && iaxs[callno]->owner)
03020                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03021                   } else {
03022                      if (iaxs[callno]->reg) {
03023                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03024                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03025                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03026                      }
03027                      iax2_destroy(callno);
03028                   }
03029                }
03030 
03031             }
03032             freeme++;
03033       } else {
03034          /* Update it if it needs it */
03035          update_packet(f);
03036          /* Attempt transmission */
03037          send_packet(f);
03038          f->retries++;
03039          /* Try again later after 10 times as long */
03040          f->retrytime *= 10;
03041          if (f->retrytime > MAX_RETRY_TIME)
03042             f->retrytime = MAX_RETRY_TIME;
03043          /* Transfer messages max out at one second */
03044          if (f->transfer && (f->retrytime > 1000))
03045             f->retrytime = 1000;
03046          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03047       }
03048    } else {
03049       /* Make sure it gets freed */
03050       f->retries = -1;
03051       freeme++;
03052    }
03053    if (callno)
03054       ast_mutex_unlock(&iaxsl[callno]);
03055    /* Do not try again */
03056    if (freeme) {
03057       /* Don't attempt delivery, just remove it from the queue */
03058       AST_LIST_LOCK(&iaxq.queue);
03059       AST_LIST_REMOVE(&iaxq.queue, f, list);
03060       iaxq.count--;
03061       AST_LIST_UNLOCK(&iaxq.queue);
03062       f->retrans = -1;
03063       /* Free the IAX frame */
03064       iax2_frame_free(f);
03065    }
03066 }

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

Definition at line 7630 of file chan_iax2.c.

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

Referenced by auth_reject().

07631 {
07632    /* Called from IAX thread only, without iaxs lock */
07633    int callno = (int)(long)(nothing);
07634    struct iax_ie_data ied;
07635    ast_mutex_lock(&iaxsl[callno]);
07636    if (iaxs[callno]) {
07637       memset(&ied, 0, sizeof(ied));
07638       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07639          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07640          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07641       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07642          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07643          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07644       }
07645       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07646    }
07647    ast_mutex_unlock(&iaxsl[callno]);
07648 }

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

Definition at line 3971 of file chan_iax2.c.

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

Referenced by auto_congest().

03972 {
03973    int callno = PTR_TO_CALLNO(nothing);
03974    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03975    ast_mutex_lock(&iaxsl[callno]);
03976    if (iaxs[callno]) {
03977       iaxs[callno]->initid = -1;
03978       iax2_queue_frame(callno, &f);
03979       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03980    }
03981    ast_mutex_unlock(&iaxsl[callno]);
03982 }

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

Definition at line 7679 of file chan_iax2.c.

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

Referenced by auto_hangup().

07680 {
07681    /* Called from IAX thread only, without iaxs lock */
07682    int callno = (int)(long)(nothing);
07683    struct iax_ie_data ied;
07684    ast_mutex_lock(&iaxsl[callno]);
07685    if (iaxs[callno]) {
07686       memset(&ied, 0, sizeof(ied));
07687       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07688       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07689       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07690    }
07691    ast_mutex_unlock(&iaxsl[callno]);
07692 }

static int __do_deliver ( void *  data  )  [static]

Note:
This function assumes that iaxsl[callno] is locked when called.

IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 2840 of file chan_iax2.c.

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

Referenced by __get_from_jb(), and schedule_delivery().

02841 {
02842    /* Just deliver the packet by using queueing.  This is called by
02843      the IAX thread with the iaxsl lock held. */
02844    struct iax_frame *fr = data;
02845    fr->retrans = -1;
02846    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02847    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02848       iax2_queue_frame(fr->callno, &fr->af);
02849    /* Free our iax frame */
02850    iax2_frame_free(fr);
02851    /* And don't run again */
02852    return 0;
02853 }

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

Definition at line 7296 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), iax2_peer::name, option_debug, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().

Referenced by expire_registry().

07297 {
07298    struct iax2_peer *peer = (struct iax2_peer *) data;
07299 
07300    if (!peer)
07301       return;
07302 
07303    peer->expire = -1;
07304 
07305    if (option_debug)
07306       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
07307    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07308       realtime_update_peer(peer->name, &peer->addr, 0);
07309    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07310    /* modify entry in peercnts table as _not_ registered */
07311    peercnt_modify(0, 0, &peer->addr);
07312    /* Reset the address */
07313    memset(&peer->addr, 0, sizeof(peer->addr));
07314    /* Reset expiry value */
07315    peer->expiry = min_reg_expire;
07316    if (!ast_test_flag(peer, IAX_TEMPONLY))
07317       ast_db_del("IAX/Registry", peer->name);
07318    register_peer_exten(peer, 0);
07319    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07320    if (iax2_regfunk)
07321       iax2_regfunk(peer->name, 0);
07322 
07323    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07324       unlink_peer(peer);
07325 
07326    peer_unref(peer);
07327 }

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

Note:
Calling this function while holding another pvt lock can cause a deadlock.

Definition at line 2299 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_string_field_set, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, 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(), sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().

Referenced by find_callno(), and find_callno_locked().

02300 {
02301    int res = 0;
02302    int x;
02303    /* this call is calltoken validated as long as it is either NEW_FORCE
02304     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02305    int validated = (new > NEW_ALLOW) ? 1 : 0;
02306    char host[80];
02307 
02308    if (new <= NEW_ALLOW) {
02309       if (callno) {
02310          struct chan_iax2_pvt *pvt;
02311          struct chan_iax2_pvt tmp_pvt = {
02312             .callno = dcallno,
02313             .peercallno = callno,
02314             .transfercallno = callno,
02315             /* hack!! */
02316             .frames_received = check_dcallno,
02317          };
02318 
02319          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02320          /* this works for finding normal call numbers not involving transfering */ 
02321          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02322             if (return_locked) {
02323                ast_mutex_lock(&iaxsl[pvt->callno]);
02324             }
02325             res = pvt->callno;
02326             ao2_ref(pvt, -1);
02327             pvt = NULL;
02328             return res;
02329          }
02330          /* this searches for transfer call numbers that might not get caught otherwise */
02331          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02332          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
02333          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02334             if (return_locked) {
02335                ast_mutex_lock(&iaxsl[pvt->callno]);
02336             }
02337             res = pvt->callno;
02338             ao2_ref(pvt, -1);
02339             pvt = NULL;
02340             return res;
02341          }
02342       }
02343       /* This will occur on the first response to a message that we initiated,
02344        * such as a PING. */
02345       if (dcallno) {
02346          ast_mutex_lock(&iaxsl[dcallno]);
02347       }
02348       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02349          iaxs[dcallno]->peercallno = callno;
02350          res = dcallno;
02351          store_by_peercallno(iaxs[dcallno]);
02352          if (!res || !return_locked) {
02353             ast_mutex_unlock(&iaxsl[dcallno]);
02354          }
02355          return res;
02356       }
02357       if (dcallno) {
02358          ast_mutex_unlock(&iaxsl[dcallno]);
02359       }
02360 #ifdef IAX_OLD_FIND
02361       /* If we get here, we SHOULD NOT find a call structure for this
02362          callno; if we do, it means that there is a call structure that
02363          has a peer callno but did NOT get entered into the hash table,
02364          which is bad.
02365 
02366          If we find a call structure using this old, slow method, output a log
02367          message so we'll know about it. After a few months of leaving this in
02368          place, if we don't hear about people seeing these messages, we can
02369          remove this code for good.
02370       */
02371 
02372       for (x = 1; !res && x < maxnontrunkcall; x++) {
02373          ast_mutex_lock(&iaxsl[x]);
02374          if (iaxs[x]) {
02375             /* Look for an exact match */
02376             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02377                res = x;
02378             }
02379          }
02380          if (!res || !return_locked)
02381             ast_mutex_unlock(&iaxsl[x]);
02382       }
02383 
02384       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02385          ast_mutex_lock(&iaxsl[x]);
02386          if (iaxs[x]) {
02387             /* Look for an exact match */
02388             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02389                res = x;
02390             }
02391          }
02392          if (!res || !return_locked)
02393             ast_mutex_unlock(&iaxsl[x]);
02394       }
02395 
02396       if (res) {
02397          ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
02398       }
02399 #endif
02400    }
02401    if (!res && (new >= NEW_ALLOW)) {
02402       struct callno_entry *callno_entry;
02403       /* It may seem odd that we look through the peer list for a name for
02404        * this *incoming* call.  Well, it is weird.  However, users don't
02405        * have an IP address/port number that we can match against.  So,
02406        * this is just checking for a peer that has that IP/port and
02407        * assuming that we have a user of the same name.  This isn't always
02408        * correct, but it will be changed if needed after authentication. */
02409       if (!iax2_getpeername(*sin, host, sizeof(host)))
02410          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02411 
02412       if (peercnt_add(sin)) {
02413          /* This address has hit its callnumber limit.  When the limit
02414           * is reached, the connection is not added to the peercnts table.*/
02415          return 0;
02416       }
02417 
02418       if (!(callno_entry = get_unused_callno(0, validated))) {
02419          /* since we ran out of space, remove the peercnt
02420           * entry we added earlier */
02421          peercnt_remove_by_addr(sin);
02422          ast_log(LOG_WARNING, "No more space\n");
02423          return 0;
02424       }
02425       x = callno_entry->callno;
02426       ast_mutex_lock(&iaxsl[x]);
02427 
02428       iaxs[x] = new_iax(sin, host);
02429       update_max_nontrunk();
02430       if (iaxs[x]) {
02431          if (option_debug && iaxdebug)
02432             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
02433          iaxs[x]->callno_entry = callno_entry;
02434          iaxs[x]->sockfd = sockfd;
02435          iaxs[x]->addr.sin_port = sin->sin_port;
02436          iaxs[x]->addr.sin_family = sin->sin_family;
02437          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02438          iaxs[x]->peercallno = callno;
02439          iaxs[x]->callno = x;
02440          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02441          iaxs[x]->expiry = min_reg_expire;
02442          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02443          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02444          iaxs[x]->amaflags = amaflags;
02445          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02446          
02447          ast_string_field_set(iaxs[x], accountcode, accountcode);
02448          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02449          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02450 
02451          if (iaxs[x]->peercallno) {
02452             store_by_peercallno(iaxs[x]);
02453          }
02454       } else {
02455          ast_log(LOG_WARNING, "Out of resources\n");
02456          ast_mutex_unlock(&iaxsl[x]);
02457          replace_callno(callno_entry);
02458          return 0;
02459       }
02460       if (!return_locked)
02461          ast_mutex_unlock(&iaxsl[x]);
02462       res = x;
02463    }
02464    return res;
02465 }

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

Definition at line 3413 of file chan_iax2.c.

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

Referenced by get_from_jb().

03414 {
03415    int callno = PTR_TO_CALLNO(p);
03416    struct chan_iax2_pvt *pvt = NULL;
03417    struct iax_frame *fr;
03418    jb_frame frame;
03419    int ret;
03420    long now;
03421    long next;
03422    struct timeval tv;
03423    
03424    /* Make sure we have a valid private structure before going on */
03425    ast_mutex_lock(&iaxsl[callno]);
03426    pvt = iaxs[callno];
03427    if (!pvt) {
03428       /* No go! */
03429       ast_mutex_unlock(&iaxsl[callno]);
03430       return;
03431    }
03432 
03433    pvt->jbid = -1;
03434    
03435    gettimeofday(&tv,NULL);
03436    /* round up a millisecond since ast_sched_runq does; */
03437    /* prevents us from spinning while waiting for our now */
03438    /* to catch up with runq's now */
03439    tv.tv_usec += 1000;
03440    
03441    now = ast_tvdiff_ms(tv, pvt->rxcore);
03442    
03443    if(now >= (next = jb_next(pvt->jb))) {
03444       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
03445       switch(ret) {
03446       case JB_OK:
03447          fr = frame.data;
03448          __do_deliver(fr);
03449          /* __do_deliver() can cause the call to disappear */
03450          pvt = iaxs[callno];
03451          break;
03452       case JB_INTERP:
03453       {
03454          struct ast_frame af = { 0, };
03455          
03456          /* create an interpolation frame */
03457          af.frametype = AST_FRAME_VOICE;
03458          af.subclass = pvt->voiceformat;
03459          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03460          af.src  = "IAX2 JB interpolation";
03461          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03462          af.offset = AST_FRIENDLY_OFFSET;
03463          
03464          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
03465           * which we'd need to malloc, and then it would free it.  That seems like a drag */
03466          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03467             iax2_queue_frame(callno, &af);
03468             /* iax2_queue_frame() could cause the call to disappear */
03469             pvt = iaxs[callno];
03470          }
03471       }
03472          break;
03473       case JB_DROP:
03474          iax2_frame_free(frame.data);
03475          break;
03476       case JB_NOFRAME:
03477       case JB_EMPTY:
03478          /* do nothing */
03479          break;
03480       default:
03481          /* shouldn't happen */
03482          break;
03483       }
03484    }
03485    if (pvt)
03486       update_jbsched(pvt);
03487    ast_mutex_unlock(&iaxsl[callno]);
03488 }

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

Definition at line 6977 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

06978 {
06979    struct iax2_registry *reg = (struct iax2_registry *)data;
06980    reg->expire = -1;
06981    iax2_do_register(reg);
06982 }

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

Definition at line 10165 of file chan_iax2.c.

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

Referenced by iax2_poke_noanswer().

10166 {
10167    struct iax2_peer *peer = (struct iax2_peer *)data;
10168    int callno;
10169 
10170    if (peer->lastms > -1) {
10171       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10172       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10173       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
10174    }
10175    if ((callno = peer->callno) > 0) {
10176       ast_mutex_lock(&iaxsl[callno]);
10177       iax2_destroy(callno);
10178       ast_mutex_unlock(&iaxsl[callno]);
10179    }
10180    peer->callno = 0;
10181    peer->lastms = -1;
10182    /* Try again quickly */
10183    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10184    if (peer->pokeexpire == -1)
10185       peer_unref(peer);
10186 }

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

Definition at line 7742 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

07743 {
07744    struct iax2_peer *peer = (struct iax2_peer *)data;
07745    iax2_poke_peer(peer, 0);
07746    peer_unref(peer);
07747 }

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

Definition at line 5707 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and iax2_peer::username.

Referenced by iax2_show_peers(), and manager_iax2_show_peers().

05708 {
05709    regex_t regexbuf;
05710    int havepattern = 0;
05711    int total_peers = 0;
05712    int online_peers = 0;
05713    int offline_peers = 0;
05714    int unmonitored_peers = 0;
05715    struct ao2_iterator i;
05716 
05717 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
05718 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
05719 
05720    struct iax2_peer *peer = NULL;
05721    char name[256];
05722    int registeredonly=0;
05723    char *term = manager ? "\r\n" : "\n";
05724 
05725    switch (argc) {
05726    case 6:
05727       if (!strcasecmp(argv[3], "registered"))
05728          registeredonly = 1;
05729       else
05730          return RESULT_SHOWUSAGE;
05731       if (!strcasecmp(argv[4], "like")) {
05732          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05733             return RESULT_SHOWUSAGE;
05734          havepattern = 1;
05735       } else
05736          return RESULT_SHOWUSAGE;
05737       break;
05738    case 5:
05739       if (!strcasecmp(argv[3], "like")) {
05740          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05741             return RESULT_SHOWUSAGE;
05742          havepattern = 1;
05743       } else
05744          return RESULT_SHOWUSAGE;
05745       break;
05746    case 4:
05747       if (!strcasecmp(argv[3], "registered"))
05748          registeredonly = 1;
05749       else
05750          return RESULT_SHOWUSAGE;
05751       break;
05752    case 3:
05753       break;
05754    default:
05755       return RESULT_SHOWUSAGE;
05756    }
05757 
05758 
05759    if (s)
05760       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
05761    else
05762       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
05763 
05764    i = ao2_iterator_init(peers, 0);
05765    for (peer = ao2_iterator_next(&i); peer; 
05766       peer_unref(peer), peer = ao2_iterator_next(&i)) {
05767       char nm[20];
05768       char status[20];
05769       char srch[2000];
05770       int retstatus;
05771 
05772       if (registeredonly && !peer->addr.sin_addr.s_addr)
05773          continue;
05774       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
05775          continue;
05776 
05777       if (!ast_strlen_zero(peer->username))
05778          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05779       else
05780          ast_copy_string(name, peer->name, sizeof(name));
05781       
05782       retstatus = peer_status(peer, status, sizeof(status));
05783       if (retstatus > 0)
05784          online_peers++;
05785       else if (!retstatus)
05786          offline_peers++;
05787       else
05788          unmonitored_peers++;
05789       
05790       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05791       
05792       snprintf(srch, sizeof(srch), FORMAT, name, 
05793           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05794           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05795           nm,
05796           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05797           peer->encmethods ? "(E)" : "   ", status, term);
05798       
05799       if (s)
05800          astman_append(s, FORMAT, name, 
05801                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
05802                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05803                   nm,
05804                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05805                   peer->encmethods ? "(E)" : "   ", status, term);
05806       else
05807          ast_cli(fd, FORMAT, name, 
05808             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05809             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05810             nm,
05811             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05812             peer->encmethods ? "(E)" : "   ", status, term);
05813       total_peers++;
05814    }
05815 
05816    if (s)
05817       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05818    else
05819       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05820 
05821    if (havepattern)
05822       regfree(&regexbuf);
05823 
05824    return RESULT_SUCCESS;
05825 #undef FORMAT
05826 #undef FORMAT2
05827 }

static void __reg_module ( void   )  [static]

Definition at line 12686 of file chan_iax2.c.

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

Definition at line 1065 of file chan_iax2.c.

References ast_copy_string(), ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.

01066 {
01067    struct iax2_thread *thread = NULL;
01068    static time_t lasterror;
01069    static time_t t;
01070 
01071    thread = find_idle_thread();
01072 
01073    if (thread != NULL) {
01074       thread->schedfunc = func;
01075       thread->scheddata = data;
01076       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01077 #ifdef DEBUG_SCHED_MULTITHREAD
01078       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01079 #endif
01080       signal_condition(&thread->lock, &thread->cond);
01081       return 0;
01082    }
01083    time(&t);
01084    if (t != lasterror && option_debug) 
01085       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
01086    lasterror = t;
01087 
01088    return -1;
01089 }

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

References f, and iax2_send().

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

06234 {
06235    struct ast_frame f = { 0, };
06236 
06237    f.frametype = type;
06238    f.subclass = command;
06239    f.datalen = datalen;
06240    f.src = __FUNCTION__;
06241    f.data = (void *) data;
06242 
06243    return iax2_send(i, &f, ts, seqno, now, transfer, final);
06244 }

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

Definition at line 1152 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, chan_iax2_pvt::lagid, LOG_WARNING, sched, send_command(), and send_lagrq().

Referenced by send_lagrq().

01153 {
01154    int callno = (long) data;
01155 
01156    ast_mutex_lock(&iaxsl[callno]);
01157 
01158    if (iaxs[callno]) {
01159       if (iaxs[callno]->peercallno) {
01160          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01161          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01162       } else {
01163          /* I am the schedule, so I'm allowed to do this */
01164          iaxs[callno]->lagid = -1;
01165       }
01166    } else {
01167       ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno);
01168    }
01169 
01170    ast_mutex_unlock(&iaxsl[callno]);
01171 }

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

Definition at line 1107 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().

Referenced by send_ping().

01108 {
01109    int callno = (long) data;
01110 
01111    ast_mutex_lock(&iaxsl[callno]);
01112 
01113    if (iaxs[callno]) {
01114       if (iaxs[callno]->peercallno) {
01115          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01116          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01117       } else {
01118          /* I am the schedule, so I'm allowed to do this */
01119          iaxs[callno]->pingid = -1;
01120       }
01121    } else if (option_debug > 0) {
01122       ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno);
01123    }
01124 
01125    ast_mutex_unlock(&iaxsl[callno]);
01126 }

static int __unload_module ( void   )  [static]

Definition at line 12374 of file chan_iax2.c.

References ao2_ref(), ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), callno_limits, callno_pool, callno_pool_trunk, calltoken_ignores, cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxactivethreadcount, iaxq, iaxs, iaxsl, iax2_thread::list, ast_firmware_list::lock, netsock, outsock, peercnts, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, and waresl.

12375 {
12376    struct iax2_thread *thread = NULL;
12377    int x;
12378 
12379    /* Make sure threads do not hold shared resources when they are canceled */
12380    
12381    /* Grab the sched lock resource to keep it away from threads about to die */
12382    /* Cancel the network thread, close the net socket */
12383    if (netthreadid != AST_PTHREADT_NULL) {
12384       AST_LIST_LOCK(&iaxq.queue);
12385       ast_mutex_lock(&sched_lock);
12386       pthread_cancel(netthreadid);
12387       ast_cond_signal(&sched_cond);
12388       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
12389       AST_LIST_UNLOCK(&iaxq.queue);
12390       pthread_join(netthreadid, NULL);
12391    }
12392    if (schedthreadid != AST_PTHREADT_NULL) {
12393       ast_mutex_lock(&sched_lock);  
12394       pthread_cancel(schedthreadid);
12395       ast_cond_signal(&sched_cond);
12396       ast_mutex_unlock(&sched_lock);   
12397       pthread_join(schedthreadid, NULL);
12398    }
12399    
12400    /* Call for all threads to halt */
12401    AST_LIST_LOCK(&idle_list);
12402    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
12403       AST_LIST_REMOVE_CURRENT(&idle_list, list);
12404       pthread_cancel(thread->threadid);
12405    }
12406    AST_LIST_TRAVERSE_SAFE_END
12407    AST_LIST_UNLOCK(&idle_list);
12408 
12409    AST_LIST_LOCK(&active_list);
12410    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
12411       AST_LIST_REMOVE_CURRENT(&active_list, list);
12412       pthread_cancel(thread->threadid);
12413    }
12414    AST_LIST_TRAVERSE_SAFE_END
12415    AST_LIST_UNLOCK(&active_list);
12416 
12417    AST_LIST_LOCK(&dynamic_list);
12418         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
12419       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
12420       pthread_cancel(thread->threadid);
12421         }
12422    AST_LIST_TRAVERSE_SAFE_END
12423         AST_LIST_UNLOCK(&dynamic_list);
12424 
12425    AST_LIST_HEAD_DESTROY(&iaxq.queue);
12426 
12427    /* Wait for threads to exit */
12428    while(0 < iaxactivethreadcount)
12429       usleep(10000);
12430    
12431    ast_netsock_release(netsock);
12432    ast_netsock_release(outsock);
12433    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12434       if (iaxs[x]) {
12435          iax2_destroy(x);
12436       }
12437    }
12438    ast_manager_unregister( "IAXpeers" );
12439    ast_manager_unregister( "IAXnetstats" );
12440    ast_unregister_application(papp);
12441    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12442    ast_unregister_switch(&iax2_switch);
12443    ast_channel_unregister(&iax2_tech);
12444    delete_users();
12445    iax_provision_unload();
12446    sched_context_destroy(sched);
12447    reload_firmware(1);
12448 
12449    ast_mutex_destroy(&waresl.lock);
12450 
12451    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12452       ast_mutex_destroy(&iaxsl[x]);
12453    }
12454 
12455    ao2_ref(peers, -1);
12456    ao2_ref(users, -1);
12457    ao2_ref(iax_peercallno_pvts, -1);
12458    ao2_ref(iax_transfercallno_pvts, -1);  
12459    ao2_ref(peercnts, -1);
12460    ao2_ref(callno_limits, -1);
12461    ao2_ref(calltoken_ignores, -1);
12462    ao2_ref(callno_pool, -1);
12463    ao2_ref(callno_pool_trunk, -1);
12464 
12465    return 0;
12466 }

static void __unreg_module ( void   )  [static]

Definition at line 12686 of file chan_iax2.c.

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

Definition at line 2067 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(), calltoken_ignores, addr_range::ha, and LOG_WARNING.

Referenced by set_config().

02068 {
02069    struct addr_range tmp;
02070    struct addr_range *addr_range = NULL;
02071    struct ast_ha *ha = NULL;
02072 
02073    if (ast_strlen_zero(addr)) {
02074       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02075       return -1;
02076    }
02077 
02078    ha = ast_append_ha("permit", addr, NULL);
02079 
02080    /* check for valid config information */
02081    if (!ha) {
02082       ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr);
02083       return -1;
02084    }
02085 
02086    ast_copy_ha(ha, &tmp.ha);
02087    /* find or create the addr_range */
02088    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02089       ao2_lock(addr_range);
02090       addr_range->delme = 0;
02091       ao2_unlock(addr_range);
02092    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02093       /* copy over config data into addr_range object */
02094       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02095       ao2_link(calltoken_ignores, addr_range);
02096    } else {
02097       ast_free_ha(ha);
02098       return -1;
02099    }
02100 
02101    ast_free_ha(ha);
02102    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02103 
02104    return 0;
02105 }

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

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

04050 {
04051    /* first make sure their are two empty bytes left in ied->buf */
04052    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04053       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04054       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04055       pvt->calltoken_ie_len = 2;
04056    }
04057 }

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

Definition at line 1725 of file chan_iax2.c.

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

Referenced by load_objects().

01726 {
01727    struct addr_range *lim1 = obj, *lim2 = arg;
01728    return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01729       (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01730       CMP_MATCH | CMP_STOP : 0;
01731 }

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

Definition at line 1712 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

01713 {
01714    struct addr_range *lim = obj;
01715    lim->delme = 1;
01716    return 0;
01717 }

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

Definition at line 1719 of file chan_iax2.c.

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

Referenced by load_objects().

01720 {
01721    const struct addr_range *lim = obj;
01722    return abs((int) lim->ha.netaddr.s_addr);
01723 }

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

Definition at line 1745 of file chan_iax2.c.

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

Referenced by calltoken_required(), and set_peercnt_limit().

01746 {
01747    struct addr_range *addr_range = obj;
01748    struct sockaddr_in *sin = arg;
01749 
01750    if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01751       return CMP_MATCH | CMP_STOP;
01752    }
01753    return 0;
01754 }

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

Definition at line 6285 of file chan_iax2.c.

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

Referenced by check_access().

06286 {
06287    while(con) {
06288       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
06289          return -1;
06290       con = con->next;
06291    }
06292    return 0;
06293 }

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

Definition at line 6048 of file chan_iax2.c.

References ARRAY_LEN, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.

Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().

06049 {
06050    int x;
06051    int numchans = 0;
06052    char first_message[10] = { 0, };
06053    char last_message[10] = { 0, };
06054    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06055       ast_mutex_lock(&iaxsl[x]);
06056       if (iaxs[x]) {
06057          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06058          char *fmt;
06059          jb_info jbinfo;
06060 
06061          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06062             jb_getinfo(iaxs[x]->jb, &jbinfo);
06063             localjitter = jbinfo.jitter;
06064             localdelay = jbinfo.current - jbinfo.min;
06065             locallost = jbinfo.frames_lost;
06066             locallosspct = jbinfo.losspct/1000;
06067             localdropped = jbinfo.frames_dropped;
06068             localooo = jbinfo.frames_ooo;
06069          } else {
06070             localjitter = -1;
06071             localdelay = 0;
06072             locallost = -1;
06073             locallosspct = -1;
06074             localdropped = 0;
06075             localooo = -1;
06076          }
06077          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06078          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06079          if (limit_fmt)
06080             fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n";
06081          else
06082             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n";
06083          if (s)
06084 
06085             astman_append(s, fmt,
06086                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06087                      iaxs[x]->pingtime,
06088                      localjitter,
06089                      localdelay,
06090                      locallost,
06091                      locallosspct,
06092                      localdropped,
06093                      localooo,
06094                      iaxs[x]->frames_received/1000,
06095                      iaxs[x]->remote_rr.jitter,
06096                      iaxs[x]->remote_rr.delay,
06097                      iaxs[x]->remote_rr.losscnt,
06098                      iaxs[x]->remote_rr.losspct,
06099                      iaxs[x]->remote_rr.dropped,
06100                      iaxs[x]->remote_rr.ooo,
06101                      iaxs[x]->remote_rr.packets/1000,
06102                           (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06103                     first_message,
06104                     (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06105                     last_message);
06106          else
06107             ast_cli(fd, fmt,
06108                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06109                iaxs[x]->pingtime,
06110                localjitter,
06111                localdelay,
06112                locallost,
06113                locallosspct,
06114                localdropped,
06115                localooo,
06116                iaxs[x]->frames_received/1000,
06117                iaxs[x]->remote_rr.jitter,
06118                iaxs[x]->remote_rr.delay,
06119                iaxs[x]->remote_rr.losscnt,
06120                iaxs[x]->remote_rr.losspct,
06121                iaxs[x]->remote_rr.dropped,
06122                iaxs[x]->remote_rr.ooo,
06123                iaxs[x]->remote_rr.packets/1000,
06124                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06125                first_message,
06126                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06127                last_message);
06128          numchans++;
06129       }
06130       ast_mutex_unlock(&iaxsl[x]);
06131    }
06132    return numchans;
06133 }

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

Create new call, interface with the PBX core.

Definition at line 4873 of file chan_iax2.c.

References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_channel_free(), ast_copy_string(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), 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, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, chan_iax2_pvt::dnid, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_tech, iaxs, iaxsl, chan_iax2_pvt::language, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

04874 {
04875    struct ast_channel *tmp;
04876    struct chan_iax2_pvt *i;
04877    struct ast_variable *v = NULL;
04878 
04879    if (!(i = iaxs[callno])) {
04880       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04881       return NULL;
04882    }
04883 
04884    /* Don't hold call lock */
04885    ast_mutex_unlock(&iaxsl[callno]);
04886    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
04887    ast_mutex_lock(&iaxsl[callno]);
04888    if (i != iaxs[callno]) {
04889       if (tmp) {
04890          /* unlock and relock iaxsl[callno] to preserve locking order */
04891          ast_mutex_unlock(&iaxsl[callno]);
04892          ast_channel_free(tmp);
04893          ast_mutex_lock(&iaxsl[callno]);
04894       }
04895       return NULL;
04896    }
04897 
04898    if (!tmp)
04899       return NULL;
04900    tmp->tech = &iax2_tech;
04901    /* We can support any format by default, until we get restricted */
04902    tmp->nativeformats = capability;
04903    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04904    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04905    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04906 
04907    /* Don't use ast_set_callerid() here because it will
04908     * generate a NewCallerID event before the NewChannel event */
04909    if (!ast_strlen_zero(i->ani))
04910       tmp->cid.cid_ani = ast_strdup(i->ani);
04911    else
04912       tmp->cid.cid_ani = ast_strdup(i->cid_num);
04913    tmp->cid.cid_dnid = ast_strdup(i->dnid);
04914    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04915    tmp->cid.cid_pres = i->calling_pres;
04916    tmp->cid.cid_ton = i->calling_ton;
04917    tmp->cid.cid_tns = i->calling_tns;
04918    if (!ast_strlen_zero(i->language))
04919       ast_string_field_set(tmp, language, i->language);
04920    if (!ast_strlen_zero(i->accountcode))
04921       ast_string_field_set(tmp, accountcode, i->accountcode);
04922    if (i->amaflags)
04923       tmp->amaflags = i->amaflags;
04924    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04925    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04926    if (i->adsi)
04927       tmp->adsicpe = i->peeradsicpe;
04928    else
04929       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04930    i->owner = tmp;
04931    i->capability = capability;
04932 
04933    for (v = i->vars ; v ; v = v->next)
04934       pbx_builtin_setvar_helper(tmp, v->name, v->value);
04935 
04936    if (state != AST_STATE_DOWN) {
04937       if (ast_pbx_start(tmp)) {
04938          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04939          ast_hangup(tmp);
04940          i->owner = NULL;
04941          return NULL;
04942       }
04943    }
04944 
04945    ast_module_ref(ast_module_info->self);
04946    
04947    return tmp;
04948 }

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

Definition at line 3068 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and network_thread().

03069 {
03070 #ifdef SCHED_MULTITHREADED
03071    if (schedule_action(__attempt_transmit, data))
03072 #endif      
03073       __attempt_transmit(data);
03074    return 0;
03075 }

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

Definition at line 7664 of file chan_iax2.c.

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

Referenced by socket_process().

07665 {
07666    /* Schedule sending the authentication failure in one second, to prevent
07667       guessing */
07668    if (iaxs[callno]) {
07669       iaxs[callno]->authfail = failcode;
07670       if (delayreject) {
07671          AST_SCHED_DEL(sched, iaxs[callno]->authid);
07672          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
07673       } else
07674          auth_reject((void *)(long)callno);
07675    }
07676    return 0;
07677 }

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

Definition at line 7650 of file chan_iax2.c.

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

Referenced by auth_fail().

07651 {
07652    int callno = (int)(long)(data);
07653    ast_mutex_lock(&iaxsl[callno]);
07654    if (iaxs[callno])
07655       iaxs[callno]->authid = -1;
07656    ast_mutex_unlock(&iaxsl[callno]);
07657 #ifdef SCHED_MULTITHREADED
07658    if (schedule_action(__auth_reject, data))
07659 #endif      
07660       __auth_reject(data);
07661    return 0;
07662 }

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

Definition at line 6845 of file chan_iax2.c.

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

06846 {
06847    int res = -1;
06848    int x;
06849    if (!ast_strlen_zero(keyn)) {
06850       if (!(authmethods & IAX_AUTH_RSA)) {
06851          if (ast_strlen_zero(secret)) 
06852             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
06853       } else if (ast_strlen_zero(challenge)) {
06854          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06855       } else {
06856          char sig[256];
06857          struct ast_key *key;
06858          key = ast_key_get(keyn, AST_KEY_PRIVATE);
06859          if (!key) {
06860             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06861          } else {
06862             if (ast_sign(key, (char*)challenge, sig)) {
06863                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06864                res = -1;
06865             } else {
06866                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06867                res = 0;
06868             }
06869          }
06870       }
06871    } 
06872    /* Fall back */
06873    if (res && !ast_strlen_zero(secret)) {
06874       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06875          struct MD5Context md5;
06876          unsigned char digest[16];
06877          char digres[128];
06878          MD5Init(&md5);
06879          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06880          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06881          MD5Final(digest, &md5);
06882          /* If they support md5, authenticate with it.  */
06883          for (x=0;x<16;x++)
06884             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
06885          if (pvt) {
06886             build_encryption_keys(digest, pvt);
06887          }
06888          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06889          res = 0;
06890       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06891          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06892          res = 0;
06893       } else
06894          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06895    }
06896    return res;
06897 }

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

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

Definition at line 6903 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax2_peer::authmethods, chan_iax2_pvt::callno, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, ies, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), realtime_peer(), iax2_peer::secret, send_command(), and iax2_peer::username.

Referenced by socket_process().

06904 {
06905    struct iax2_peer *peer = NULL;
06906    /* Start pessimistic */
06907    int res = -1;
06908    int authmethods = 0;
06909    struct iax_ie_data ied;
06910    uint16_t callno = p->callno;
06911 
06912    memset(&ied, 0, sizeof(ied));
06913    
06914    if (ies->username)
06915       ast_string_field_set(p, username, ies->username);
06916    if (ies->challenge)
06917       ast_string_field_set(p, challenge, ies->challenge);
06918    if (ies->authmethods)
06919       authmethods = ies->authmethods;
06920    if (authmethods & IAX_AUTH_MD5)
06921       merge_encryption(p, ies->encmethods);
06922    else
06923       p->encmethods = 0;
06924 
06925    /* Check for override RSA authentication first */
06926    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06927       /* Normal password authentication */
06928       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06929    } else {
06930       struct ao2_iterator i = ao2_iterator_init(peers, 0);
06931       while ((peer = ao2_iterator_next(&i))) {
06932          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
06933              /* No peer specified at our end, or this is the peer */
06934              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06935              /* No username specified in peer rule, or this is the right username */
06936              && (!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)))
06937              /* No specified host, or this is our host */
06938             ) {
06939             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06940             if (!res) {
06941                peer_unref(peer);
06942                break;
06943             }
06944          }
06945          peer_unref(peer);
06946       }
06947       if (!peer) {
06948          /* We checked our list and didn't find one.  It's unlikely, but possible, 
06949             that we're trying to authenticate *to* a realtime peer */
06950          const char *peer_name = ast_strdupa(p->peer);
06951          ast_mutex_unlock(&iaxsl[callno]);
06952          if ((peer = realtime_peer(peer_name, NULL))) {
06953             ast_mutex_lock(&iaxsl[callno]);
06954             if (!(p = iaxs[callno])) {
06955                peer_unref(peer);
06956                return -1;
06957             }
06958             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06959             peer_unref(peer);
06960          }
06961          if (!peer) {
06962             ast_mutex_lock(&iaxsl[callno]);
06963             if (!(p = iaxs[callno]))
06964                return -1;
06965          }
06966       }
06967    }
06968    if (ies->encmethods)
06969       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06970    if (!res)
06971       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06972    return res;
06973 }

static int authenticate_request ( int  call_num  )  [static]

Precondition:
iaxsl[call_num] is locked
Note:
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 6554 of file chan_iax2.c.

References ao2_find(), AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, 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, iaxs, iax2_user::maxauthreq, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process().

06555 {
06556    struct iax_ie_data ied;
06557    int res = -1, authreq_restrict = 0;
06558    char challenge[10];
06559    struct chan_iax2_pvt *p = iaxs[call_num];
06560 
06561    memset(&ied, 0, sizeof(ied));
06562 
06563    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
06564    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06565       struct iax2_user *user, tmp_user = {
06566          .name = p->username, 
06567       };
06568 
06569       user = ao2_find(users, &tmp_user, OBJ_POINTER);
06570       if (user) {
06571          if (user->curauthreq == user->maxauthreq)
06572             authreq_restrict = 1;
06573          else
06574             user->curauthreq++;
06575          user = user_unref(user);
06576       }
06577    }
06578 
06579    /* If the AUTHREQ limit test failed, send back an error */
06580    if (authreq_restrict) {
06581       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06582       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06583       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06584       return 0;
06585    }
06586 
06587    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06588    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06589       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06590       ast_string_field_set(p, challenge, challenge);
06591       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
06592       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06593    }
06594    if (p->encmethods)
06595       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06596 
06597    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06598 
06599    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06600 
06601    if (p->encmethods)
06602       ast_set_flag(p, IAX_ENCRYPTED);
06603 
06604    return res;
06605 }

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

Definition at line 6607 of file chan_iax2.c.

References ao2_find(), ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, chan_iax2_pvt::inkeys, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_user::name, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, user_unref(), and chan_iax2_pvt::username.

Referenced by socket_process().

06608 {
06609    char requeststr[256];
06610    char md5secret[256] = "";
06611    char secret[256] = "";
06612    char rsasecret[256] = "";
06613    int res = -1; 
06614    int x;
06615    struct iax2_user *user, tmp_user = {
06616       .name = p->username, 
06617    };
06618 
06619    if (p->authrej) {
06620       return res;
06621    }
06622    user = ao2_find(users, &tmp_user, OBJ_POINTER);
06623    if (user) {
06624       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06625          ast_atomic_fetchadd_int(&user->curauthreq, -1);
06626          ast_clear_flag(p, IAX_MAXAUTHREQ);
06627       }
06628       ast_string_field_set(p, host, user->name);
06629       user = user_unref(user);
06630    }
06631 
06632    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06633       return res;
06634    if (ies->password)
06635       ast_copy_string(secret, ies->password, sizeof(secret));
06636    if (ies->md5_result)
06637       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06638    if (ies->rsa_result)
06639       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06640    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06641       struct ast_key *key;
06642       char *keyn;
06643       char tmpkey[256];
06644       char *stringp=NULL;
06645       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06646       stringp=tmpkey;
06647       keyn = strsep(&stringp, ":");
06648       while(keyn) {
06649          key = ast_key_get(keyn, AST_KEY_PUBLIC);
06650          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06651             res = 0;
06652             break;
06653          } else if (!key)
06654             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06655          keyn = strsep(&stringp, ":");
06656       }
06657    } else if (p->authmethods & IAX_AUTH_MD5) {
06658       struct MD5Context md5;
06659       unsigned char digest[16];
06660       char *tmppw, *stringp;
06661       
06662       tmppw = ast_strdupa(p->secret);
06663       stringp = tmppw;
06664       while((tmppw = strsep(&stringp, ";"))) {
06665          MD5Init(&md5);
06666          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06667          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06668          MD5Final(digest, &md5);
06669          /* If they support md5, authenticate with it.  */
06670          for (x=0;x<16;x++)
06671             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06672          if (!strcasecmp(requeststr, md5secret)) {
06673             res = 0;
06674             break;
06675          }
06676       }
06677    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06678       if (!strcmp(secret, p->secret))
06679          res = 0;
06680    }
06681    return res;
06682 }

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

Definition at line 3984 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call(), and sip_call().

03985 {
03986 #ifdef SCHED_MULTITHREADED
03987    if (schedule_action(__auto_congest, data))
03988 #endif      
03989       __auto_congest(data);
03990    return 0;
03991 }

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

Definition at line 7694 of file chan_iax2.c.

References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.

Referenced by iax2_dprequest(), and iax2_provision().

07695 {
07696    int callno = (int)(long)(data);
07697    ast_mutex_lock(&iaxsl[callno]);
07698    if (iaxs[callno]) {
07699       iaxs[callno]->autoid = -1;
07700    }
07701    ast_mutex_unlock(&iaxsl[callno]);
07702 #ifdef SCHED_MULTITHREADED
07703    if (schedule_action(__auto_hangup, data))
07704 #endif      
07705       __auto_hangup(data);
07706    return 0;
07707 }

static void build_callno_limits ( struct ast_variable v  )  [static]

Definition at line 2014 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(), callno_limits, addr_range::ha, LOG_ERROR, ast_variable::name, ast_variable::next, and ast_variable::value.

Referenced by set_config().

02015 {
02016    struct addr_range *addr_range = NULL;
02017    struct addr_range tmp;
02018    struct ast_ha *ha;
02019    int limit;
02020    int found;
02021 
02022    for (; v; v = v->next) {
02023       limit = -1;
02024       found = 0;
02025       ha = ast_append_ha("permit", v->name, NULL);
02026 
02027       /* check for valid config information */
02028       if (!ha) {
02029          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02030          continue;
02031       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02032          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02033          ast_free_ha(ha);
02034          continue;
02035       }
02036 
02037       ast_copy_ha(ha, &tmp.ha);
02038       /* find or create the addr_range */
02039       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02040          ao2_lock(addr_range);
02041          found = 1;
02042       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02043          ast_free_ha(ha);
02044          return; /* out of memory */
02045       }
02046 
02047       /* copy over config data into addr_range object */
02048       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02049       ast_free_ha(ha); /* cleanup the tmp ha */
02050       addr_range->limit = limit;
02051       addr_range->delme = 0;
02052 
02053       /* cleanup */
02054       if (found) {
02055          ao2_unlock(addr_range);
02056       } else {
02057          ao2_link(callno_limits, addr_range);
02058       }
02059       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02060    }
02061 }

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

Definition at line 10498 of file chan_iax2.c.

References ast_calloc, and ast_copy_string().

Referenced by build_user().

10499 {
10500    struct iax2_context *con;
10501 
10502    if ((con = ast_calloc(1, sizeof(*con))))
10503       ast_copy_string(con->context, context, sizeof(con->context));
10504    
10505    return con;
10506 }

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

Definition at line 5277 of file chan_iax2.c.

References aes_decrypt_key128(), aes_encrypt_key128(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.

Referenced by build_encryption_keys().

05278 {
05279    /* it is required to hold the corresponding decrypt key to our encrypt key
05280     * in the pvt struct because queued frames occasionally need to be decrypted and
05281     * re-encrypted when updated for a retransmission */
05282    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05283    aes_encrypt_key128(digest, &pvt->ecx);
05284    aes_decrypt_key128(digest, &pvt->mydcx);
05285 }

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

Definition at line 5271 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

05272 {
05273    build_ecx_key(digest, pvt);
05274    aes_decrypt_key128(digest, &pvt->dcx);
05275 }

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

Create peer structure based on configuration.

Definition at line 10645 of file chan_iax2.c.

References ao2_alloc(), ao2_find(), 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_parse_allow_disallow(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, prefs, iax2_peer::regexten, S_OR, sched, secret, unlink_peer(), ast_variable::value, and zonetag.

10646 {
10647    struct iax2_peer *peer = NULL;
10648    struct ast_ha *oldha = NULL;
10649    int maskfound=0;
10650    int found=0;
10651    int firstpass=1;
10652    struct iax2_peer tmp_peer = {
10653       .name = name,
10654    };
10655 
10656    if (!temponly) {
10657       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10658       if (peer && !ast_test_flag(peer, IAX_DELME))
10659          firstpass = 0;
10660    }
10661 
10662    if (peer) {
10663       found++;
10664       if (firstpass) {
10665          oldha = peer->ha;
10666          peer->ha = NULL;
10667       }
10668       unlink_peer(peer);
10669    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10670       peer->expire = -1;
10671       peer->pokeexpire = -1;
10672       peer->sockfd = defaultsockfd;
10673       if (ast_string_field_init(peer, 32))
10674          peer = peer_unref(peer);
10675    }
10676 
10677    if (peer) {
10678       if (firstpass) {
10679          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10680          peer->encmethods = iax2_encryption;
10681          peer->adsi = adsi;
10682          ast_string_field_set(peer,secret,"");
10683          if (!found) {
10684             ast_string_field_set(peer, name, name);
10685             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10686             peer->expiry = min_reg_expire;
10687          }
10688          peer->prefs = prefs;
10689          peer->capability = iax2_capability;
10690          peer->smoothing = 0;
10691          peer->pokefreqok = DEFAULT_FREQ_OK;
10692          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10693          peer->maxcallno = 0;
10694          peercnt_modify(0, 0, &peer->addr);
10695          peer->calltoken_required = CALLTOKEN_DEFAULT;
10696          ast_string_field_set(peer,context,"");
10697          ast_string_field_set(peer,peercontext,"");
10698          ast_clear_flag(peer, IAX_HASCALLERID);
10699          ast_string_field_set(peer, cid_name, "");
10700          ast_string_field_set(peer, cid_num, "");
10701          ast_string_field_set(peer, mohinterpret, mohinterpret);
10702          ast_string_field_set(peer, mohsuggest, mohsuggest);
10703       }
10704 
10705       if (!v) {
10706          v = alt;
10707          alt = NULL;
10708       }
10709       while(v) {
10710          if (!strcasecmp(v->name, "secret")) {
10711             ast_string_field_set(peer, secret, v->value);
10712          } else if (!strcasecmp(v->name, "mailbox")) {
10713             ast_string_field_set(peer, mailbox, v->value);
10714          } else if (!strcasecmp(v->name, "hasvoicemail")) {
10715             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10716                ast_string_field_set(peer, mailbox, name);
10717             }
10718          } else if (!strcasecmp(v->name, "mohinterpret")) {
10719             ast_string_field_set(peer, mohinterpret, v->value);
10720          } else if (!strcasecmp(v->name, "mohsuggest")) {
10721             ast_string_field_set(peer, mohsuggest, v->value);
10722          } else if (!strcasecmp(v->name, "dbsecret")) {
10723             ast_string_field_set(peer, dbsecret, v->value);
10724          } else if (!strcasecmp(v->name, "trunk")) {
10725             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
10726             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
10727                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
10728                ast_clear_flag(peer, IAX_TRUNK);
10729             }
10730          } else if (!strcasecmp(v->name, "auth")) {
10731             peer->authmethods = get_auth_methods(v->value);
10732          } else if (!strcasecmp(v->name, "encryption")) {
10733             peer->encmethods = get_encrypt_methods(v->value);
10734          } else if (!strcasecmp(v->name, "notransfer")) {
10735             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10736             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
10737             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
10738          } else if (!strcasecmp(v->name, "transfer")) {
10739             if (!strcasecmp(v->value, "mediaonly")) {
10740                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10741             } else if (ast_true(v->value)) {
10742                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10743             } else 
10744                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10745          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10746             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
10747          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10748             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
10749          } else if (!strcasecmp(v->name, "host")) {
10750             if (!strcasecmp(v->value, "dynamic")) {
10751                /* They'll register with us */
10752                ast_set_flag(peer, IAX_DYNAMIC); 
10753                if (!found) {
10754                   /* Initialize stuff iff we're not found, otherwise
10755                      we keep going with what we had */
10756                   memset(&peer->addr.sin_addr, 0, 4);
10757                   if (peer->addr.sin_port) {
10758                      /* If we've already got a port, make it the default rather than absolute */
10759                      peer->defaddr.sin_port = peer->addr.sin_port;
10760                      peer->addr.sin_port = 0;
10761                   }
10762                }
10763             } else {
10764                /* Non-dynamic.  Make sure we become that way if we're not */
10765                AST_SCHED_DEL(sched, peer->expire);
10766                ast_clear_flag(peer, IAX_DYNAMIC);
10767                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
10768                   return peer_unref(peer);
10769                if (!peer->addr.sin_port)
10770                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10771             }
10772             if (!maskfound)
10773                inet_aton("255.255.255.255", &peer->mask);
10774          } else if (!strcasecmp(v->name, "defaultip")) {
10775             if (ast_get_ip(&peer->defaddr, v->value))
10776                return peer_unref(peer);
10777          } else if (!strcasecmp(v->name, "sourceaddress")) {
10778             peer_set_srcaddr(peer, v->value);
10779          } else if (!strcasecmp(v->name, "permit") ||
10780                   !strcasecmp(v->name, "deny")) {
10781             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
10782          } else if (!strcasecmp(v->name, "mask")) {
10783             maskfound++;
10784             inet_aton(v->value, &peer->mask);
10785          } else if (!strcasecmp(v->name, "context")) {
10786             ast_string_field_set(peer, context, v->value);
10787          } else if (!strcasecmp(v->name, "regexten")) {
10788             ast_string_field_set(peer, regexten, v->value);
10789          } else if (!strcasecmp(v->name, "peercontext")) {
10790             ast_string_field_set(peer, peercontext, v->value);
10791          } else if (!strcasecmp(v->name, "port")) {
10792             if (ast_test_flag(peer, IAX_DYNAMIC))
10793                peer->defaddr.sin_port = htons(atoi(v->value));
10794             else
10795                peer->addr.sin_port = htons(atoi(v->value));
10796          } else if (!strcasecmp(v->name, "username")) {
10797             ast_string_field_set(peer, username, v->value);
10798          } else if (!strcasecmp(v->name, "allow")) {
10799             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10800          } else if (!strcasecmp(v->name, "disallow")) {
10801             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10802          } else if (!strcasecmp(v->name, "callerid")) {
10803             if (!ast_strlen_zero(v->value)) {
10804                char name2[80];
10805                char num2[80];
10806                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10807                ast_string_field_set(peer, cid_name, name2);
10808                ast_string_field_set(peer, cid_num, num2);
10809             } else {
10810                ast_string_field_set(peer, cid_name, "");
10811                ast_string_field_set(peer, cid_num, "");
10812             }
10813             ast_set_flag(peer, IAX_HASCALLERID);
10814          } else if (!strcasecmp(v->name, "fullname")) {
10815             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10816             ast_set_flag(peer, IAX_HASCALLERID);
10817          } else if (!strcasecmp(v->name, "cid_number")) {
10818             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10819             ast_set_flag(peer, IAX_HASCALLERID);
10820          } else if (!strcasecmp(v->name, "sendani")) {
10821             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
10822          } else if (!strcasecmp(v->name, "inkeys")) {
10823             ast_string_field_set(peer, inkeys, v->value);
10824          } else if (!strcasecmp(v->name, "outkey")) {
10825             ast_string_field_set(peer, outkey, v->value);
10826          } else if (!strcasecmp(v->name, "qualify")) {
10827             if (!strcasecmp(v->value, "no")) {
10828                peer->maxms = 0;
10829             } else if (!strcasecmp(v->value, "yes")) {
10830                peer->maxms = DEFAULT_MAXMS;
10831             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
10832                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);
10833                peer->maxms = 0;
10834             }
10835          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10836             peer->smoothing = ast_true(v->value);
10837          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10838             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
10839                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);
10840             }
10841          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10842             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
10843                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);
10844             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10845          } else if (!strcasecmp(v->name, "timezone")) {
10846             ast_string_field_set(peer, zonetag, v->value);
10847          } else if (!strcasecmp(v->name, "adsi")) {
10848             peer->adsi = ast_true(v->value);
10849          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
10850             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
10851                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
10852             } else {
10853                peercnt_modify(1, peer->maxcallno, &peer->addr);
10854             }
10855          } else if (!strcasecmp(v->name, "requirecalltoken")) {
10856             /* default is required unless in optional ip list */
10857             if (ast_false(v->value)) {
10858                peer->calltoken_required = CALLTOKEN_NO;
10859             } else if (!strcasecmp(v->value, "auto")) {
10860                peer->calltoken_required = CALLTOKEN_AUTO;
10861             } else if (ast_true(v->value)) {
10862                peer->calltoken_required = CALLTOKEN_YES;
10863             } else {
10864                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
10865             }
10866          } /* else if (strcasecmp(v->name,"type")) */
10867          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10868          v = v->next;
10869          if (!v) {
10870             v = alt;
10871             alt = NULL;
10872          }
10873       }
10874       if (!peer->authmethods)
10875          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10876       ast_clear_flag(peer, IAX_DELME); 
10877       /* Make sure these are IPv4 addresses */
10878       peer->addr.sin_family = AF_INET;
10879    }
10880    if (oldha)
10881       ast_free_ha(oldha);
10882    return peer;
10883 }

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

Definition at line 5261 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

05262 {
05263    long tmp;
05264    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05265       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05266       buf += sizeof(tmp);
05267       len -= sizeof(tmp);
05268    }
05269 }

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

Create in-memory user structure from configuration.

Definition at line 10899 of file chan_iax2.c.

References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, 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, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, 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_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::prefs, prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.

10900 {
10901    struct iax2_user *user = NULL;
10902    struct iax2_context *con, *conl = NULL;
10903    struct ast_ha *oldha = NULL;
10904    struct iax2_context *oldcon = NULL;
10905    int format;
10906    int firstpass=1;
10907    int oldcurauthreq = 0;
10908    char *varname = NULL, *varval = NULL;
10909    struct ast_variable *tmpvar = NULL;
10910    struct iax2_user tmp_user = {
10911       .name = name,
10912    };
10913 
10914    if (!temponly) {
10915       user = ao2_find(users, &tmp_user, OBJ_POINTER);
10916       if (user && !ast_test_flag(user, IAX_DELME))
10917          firstpass = 0;
10918    }
10919 
10920    if (user) {
10921       if (firstpass) {
10922          oldcurauthreq = user->curauthreq;
10923          oldha = user->ha;
10924          oldcon = user->contexts;
10925          user->ha = NULL;
10926          user->contexts = NULL;
10927       }
10928       /* Already in the list, remove it and it will be added back (or FREE'd) */
10929       ao2_unlink(users, user);
10930    } else {
10931       user = ao2_alloc(sizeof(*user), user_destructor);
10932    }
10933    
10934    if (user) {
10935       if (firstpass) {
10936          ast_string_field_free_memory(user);
10937          memset(user, 0, sizeof(struct iax2_user));
10938          if (ast_string_field_init(user, 32)) {
10939             user = user_unref(user);
10940             goto cleanup;
10941          }
10942          user->maxauthreq = maxauthreq;
10943          user->curauthreq = oldcurauthreq;
10944          user->prefs = prefs;
10945          user->capability = iax2_capability;
10946          user->encmethods = iax2_encryption;
10947          user->adsi = adsi;
10948          user->calltoken_required = CALLTOKEN_DEFAULT;
10949          ast_string_field_set(user, name, name);
10950          ast_string_field_set(user, language, language);
10951          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
10952          ast_clear_flag(user, IAX_HASCALLERID);
10953          ast_string_field_set(user, cid_name, "");
10954          ast_string_field_set(user, cid_num, "");
10955          ast_string_field_set(user, accountcode, accountcode);
10956          ast_string_field_set(user, mohinterpret, mohinterpret);
10957          ast_string_field_set(user, mohsuggest, mohsuggest);
10958       }
10959       if (!v) {
10960          v = alt;
10961          alt = NULL;
10962       }
10963       while(v) {
10964          if (!strcasecmp(v->name, "context")) {
10965             con = build_context(v->value);
10966             if (con) {
10967                if (conl)
10968                   conl->next = con;
10969                else
10970                   user->contexts = con;
10971                conl = con;
10972             }
10973          } else if (!strcasecmp(v->name, "permit") ||
10974                   !strcasecmp(v->name, "deny")) {
10975             user->ha = ast_append_ha(v->name, v->value, user->ha);
10976          } else if (!strcasecmp(v->name, "setvar")) {
10977             varname = ast_strdupa(v->value);
10978             if (varname && (varval = strchr(varname,'='))) {
10979                *varval = '\0';
10980                varval++;
10981                if((tmpvar = ast_variable_new(varname, varval))) {
10982                   tmpvar->next = user->vars; 
10983                   user->vars = tmpvar;
10984                }
10985             }
10986          } else if (!strcasecmp(v->name, "allow")) {
10987             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
10988          } else if (!strcasecmp(v->name, "disallow")) {
10989             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
10990          } else if (!strcasecmp(v->name, "trunk")) {
10991             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
10992             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
10993                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
10994                ast_clear_flag(user, IAX_TRUNK);
10995             }
10996          } else if (!strcasecmp(v->name, "auth")) {
10997             user->authmethods = get_auth_methods(v->value);
10998          } else if (!strcasecmp(v->name, "encryption")) {
10999             user->encmethods = get_encrypt_methods(v->value);
11000          } else if (!strcasecmp(v->name, "notransfer")) {
11001             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
11002             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
11003             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
11004          } else if (!strcasecmp(v->name, "transfer")) {
11005             if (!strcasecmp(v->value, "mediaonly")) {
11006                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
11007             } else if (ast_true(v->value)) {
11008                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11009             } else 
11010                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11011          } else if (!strcasecmp(v->name, "codecpriority")) {
11012             if(!strcasecmp(v->value, "caller"))
11013                ast_set_flag(user, IAX_CODEC_USER_FIRST);
11014             else if(!strcasecmp(v->value, "disabled"))
11015                ast_set_flag(user, IAX_CODEC_NOPREFS);
11016             else if(!strcasecmp(v->value, "reqonly")) {
11017                ast_set_flag(user, IAX_CODEC_NOCAP);
11018                ast_set_flag(user, IAX_CODEC_NOPREFS);
11019             }
11020          } else if (!strcasecmp(v->name, "jitterbuffer")) {
11021             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
11022          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11023             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
11024          } else if (!strcasecmp(v->name, "dbsecret")) {
11025             ast_string_field_set(user, dbsecret, v->value);
11026          } else if (!strcasecmp(v->name, "secret")) {
11027             if (!ast_strlen_zero(user->secret)) {
11028                char *old = ast_strdupa(user->secret);
11029 
11030                ast_string_field_build(user, secret, "%s;%s", old, v->value);
11031             } else
11032                ast_string_field_set(user, secret, v->value);
11033          } else if (!strcasecmp(v->name, "callerid")) {
11034             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
11035                char name2[80];
11036                char num2[80];
11037                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11038                ast_string_field_set(user, cid_name, name2);
11039                ast_string_field_set(user, cid_num, num2);
11040                ast_set_flag(user, IAX_HASCALLERID);
11041             } else {
11042                ast_clear_flag(user, IAX_HASCALLERID);
11043                ast_string_field_set(user, cid_name, "");
11044                ast_string_field_set(user, cid_num, "");
11045             }
11046          } else if (!strcasecmp(v->name, "fullname")) {
11047             if (!ast_strlen_zero(v->value)) {
11048                ast_string_field_set(user, cid_name, v->value);
11049                ast_set_flag(user, IAX_HASCALLERID);
11050             } else {
11051                ast_string_field_set(user, cid_name, "");
11052                if (ast_strlen_zero(user->cid_num))
11053                   ast_clear_flag(user, IAX_HASCALLERID);
11054             }
11055          } else if (!strcasecmp(v->name, "cid_number")) {
11056             if (!ast_strlen_zero(v->value)) {
11057                ast_string_field_set(user, cid_num, v->value);
11058                ast_set_flag(user, IAX_HASCALLERID);
11059             } else {
11060                ast_string_field_set(user, cid_num, "");
11061                if (ast_strlen_zero(user->cid_name))
11062                   ast_clear_flag(user, IAX_HASCALLERID);
11063             }
11064          } else if (!strcasecmp(v->name, "accountcode")) {
11065             ast_string_field_set(user, accountcode, v->value);
11066          } else if (!strcasecmp(v->name, "mohinterpret")) {
11067             ast_string_field_set(user, mohinterpret, v->value);
11068          } else if (!strcasecmp(v->name, "mohsuggest")) {
11069             ast_string_field_set(user, mohsuggest, v->value);
11070          } else if (!strcasecmp(v->name, "language")) {
11071             ast_string_field_set(user, language, v->value);
11072          } else if (!strcasecmp(v->name, "amaflags")) {
11073             format = ast_cdr_amaflags2int(v->value);
11074             if (format < 0) {
11075                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11076             } else {
11077                user->amaflags = format;
11078             }
11079          } else if (!strcasecmp(v->name, "inkeys")) {
11080             ast_string_field_set(user, inkeys, v->value);
11081          } else if (!strcasecmp(v->name, "maxauthreq")) {
11082             user->maxauthreq = atoi(v->value);
11083             if (user->maxauthreq < 0)
11084                user->maxauthreq = 0;
11085          } else if (!strcasecmp(v->name, "adsi")) {
11086             user->adsi = ast_true(v->value);
11087          } else if (!strcasecmp(v->name, "requirecalltoken")) {
11088             /* default is required unless in optional ip list */
11089             if (ast_false(v->value)) {
11090                user->calltoken_required = CALLTOKEN_NO;
11091             } else if (!strcasecmp(v->value, "auto")) {
11092                user->calltoken_required = CALLTOKEN_AUTO;
11093             } else if (ast_true(v->value)) {
11094                user->calltoken_required = CALLTOKEN_YES;
11095             } else {
11096                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11097             }
11098          } /* else if (strcasecmp(v->name,"type")) */
11099          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11100          v = v->next;
11101          if (!v) {
11102             v = alt;
11103             alt = NULL;
11104          }
11105       }
11106       if (!user->authmethods) {
11107          if (!ast_strlen_zero(user->secret)) {
11108             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11109             if (!ast_strlen_zero(user->inkeys))
11110                user->authmethods |= IAX_AUTH_RSA;
11111          } else if (!ast_strlen_zero(user->inkeys)) {
11112             user->authmethods = IAX_AUTH_RSA;
11113          } else {
11114             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11115          }
11116       }
11117       ast_clear_flag(user, IAX_DELME);
11118    }
11119 cleanup:
11120    if (oldha)
11121       ast_free_ha(oldha);
11122    if (oldcon)
11123       free_context(oldcon);
11124    return user;
11125 }

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

Definition at line 11654 of file chan_iax2.c.

References add_empty_calltoken_ie(), ARRAY_LEN, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), secret, and send_command().

Referenced by find_cache().

11655 {
11656    struct sockaddr_in sin;
11657    int x;
11658    int callno;
11659    struct iax_ie_data ied;
11660    struct create_addr_info cai;
11661    struct parsed_dial_string pds;
11662    char *tmpstr;
11663 
11664    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11665       /* Look for an *exact match* call.  Once a call is negotiated, it can only
11666          look up entries for a single context */
11667       if (!ast_mutex_trylock(&iaxsl[x])) {
11668          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11669             return x;
11670          ast_mutex_unlock(&iaxsl[x]);
11671       }
11672    }
11673 
11674    /* No match found, we need to create a new one */
11675 
11676    memset(&cai, 0, sizeof(cai));
11677    memset(&ied, 0, sizeof(ied));
11678    memset(&pds, 0, sizeof(pds));
11679 
11680    tmpstr = ast_strdupa(data);
11681    parse_dial_string(tmpstr, &pds);
11682 
11683    if (ast_strlen_zero(pds.peer)) {
11684       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11685       return -1;
11686    }
11687 
11688    /* Populate our address from the given */
11689    if (create_addr(pds.peer, NULL, &sin, &cai))
11690       return -1;
11691 
11692    if (option_debug)
11693       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
11694          pds.peer, pds.username, pds.password, pds.context);
11695 
11696    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11697    if (callno < 1) {
11698       ast_log(LOG_WARNING, "Unable to create call\n");
11699       return -1;
11700    }
11701 
11702    ast_string_field_set(iaxs[callno], dproot, data);
11703    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11704 
11705    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11706    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11707    /* the string format is slightly different from a standard dial string,
11708       because the context appears in the 'exten' position
11709    */
11710    if (pds.exten)
11711       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11712    if (pds.username)
11713       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11714    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11715    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11716    /* Keep password handy */
11717    if (pds.password)
11718       ast_string_field_set(iaxs[callno], secret, pds.password);
11719    if (pds.key)
11720       ast_string_field_set(iaxs[callno], outkey, pds.key);
11721    /* Start the call going */
11722    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
11723    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11724 
11725    return callno;
11726 }

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

Definition at line 5127 of file chan_iax2.c.

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

05128 {
05129    /* Returns where in "receive time" we are.  That is, how many ms
05130       since we received (or would have received) the frame with timestamp 0 */
05131    int ms;
05132 #ifdef IAXTESTS
05133    int jit;
05134 #endif /* IAXTESTS */
05135    /* Setup rxcore if necessary */
05136    if (ast_tvzero(p->rxcore)) {
05137       p->rxcore = ast_tvnow();
05138       if (option_debug && iaxdebug)
05139          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05140                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05141       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05142 #if 1
05143       if (option_debug && iaxdebug)
05144          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05145                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05146 #endif
05147    }
05148 
05149    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05150 #ifdef IAXTESTS
05151    if (test_jit) {
05152       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05153          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05154          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05155             jit = -jit;
05156          ms += jit;
05157       }
05158    }
05159    if (test_late) {
05160       ms += test_late;
05161       test_late = 0;
05162    }
05163 #endif /* IAXTESTS */
05164    return ms;
05165 }

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

Definition at line 4994 of file chan_iax2.c.

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

Referenced by iax2_send(), and socket_process().

04995 {
04996    int ms;
04997    int voice = 0;
04998    int genuine = 0;
04999    int adjust;
05000    int rate = ast_format_rate(f->subclass) / 1000;
05001    struct timeval *delivery = NULL;
05002 
05003 
05004    /* What sort of frame do we have?: voice is self-explanatory
05005       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
05006       non-genuine frames are CONTROL frames [ringing etc], DTMF
05007       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
05008       the others need a timestamp slaved to the voice frames so that they go in sequence
05009    */
05010    if (f) {
05011       if (f->frametype == AST_FRAME_VOICE) {
05012          voice = 1;
05013          delivery = &f->delivery;
05014       } else if (f->frametype == AST_FRAME_IAX) {
05015          genuine = 1;
05016       } else if (f->frametype == AST_FRAME_CNG) {
05017          p->notsilenttx = 0;  
05018       }
05019    }
05020    if (ast_tvzero(p->offset)) {
05021       gettimeofday(&p->offset, NULL);
05022       /* Round to nearest 20ms for nice looking traces */
05023       p->offset.tv_usec -= p->offset.tv_usec % 20000;
05024    }
05025    /* If the timestamp is specified, just send it as is */
05026    if (ts)
05027       return ts;
05028    /* If we have a time that the frame arrived, always use it to make our timestamp */
05029    if (delivery && !ast_tvzero(*delivery)) {
05030       ms = ast_tvdiff_ms(*delivery, p->offset);
05031       if (ms < 0) {
05032          ms = 0;
05033       }
05034       if (option_debug > 2 && iaxdebug)
05035          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05036    } else {
05037       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05038       if (ms < 0)
05039          ms = 0;
05040       if (voice) {
05041          /* On a voice frame, use predicted values if appropriate */
05042          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05043             /* Adjust our txcore, keeping voice and non-voice synchronized */
05044             /* AN EXPLANATION:
05045                When we send voice, we usually send "calculated" timestamps worked out
05046                on the basis of the number of samples sent. When we send other frames,
05047                we usually send timestamps worked out from the real clock.
05048                The problem is that they can tend to drift out of step because the 
05049                   source channel's clock and our clock may not be exactly at the same rate.
05050                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
05051                for this call.  Moving it adjusts timestamps for non-voice frames.
05052                We make the adjustment in the style of a moving average.  Each time we
05053                adjust p->offset by 10% of the difference between our clock-derived
05054                timestamp and the predicted timestamp.  That's why you see "10000"
05055                below even though IAX2 timestamps are in milliseconds.
05056                The use of a moving average avoids offset moving too radically.
05057                Generally, "adjust" roams back and forth around 0, with offset hardly
05058                changing at all.  But if a consistent different starts to develop it
05059                will be eliminated over the course of 10 frames (200-300msecs) 
05060             */
05061             adjust = (ms - p->nextpred);
05062             if (adjust < 0)
05063                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05064             else if (adjust > 0)
05065                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05066 
05067             if (!p->nextpred) {
05068                p->nextpred = ms; /*f->samples / rate;*/
05069                if (p->nextpred <= p->lastsent)
05070                   p->nextpred = p->lastsent + 3;
05071             }
05072             ms = p->nextpred;
05073          } else {
05074                 /* in this case, just use the actual
05075             * time, since we're either way off
05076             * (shouldn't happen), or we're  ending a
05077             * silent period -- and seed the next
05078             * predicted time.  Also, round ms to the
05079             * next multiple of frame size (so our
05080             * silent periods are multiples of
05081             * frame size too) */
05082 
05083             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05084                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05085                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05086 
05087             if (f->samples >= rate) /* check to make sure we dont core dump */
05088             {
05089                int diff = ms % (f->samples / rate);
05090                if (diff)
05091                    ms += f->samples/rate - diff;
05092             }
05093 
05094             p->nextpred = ms;
05095             p->notsilenttx = 1;
05096          }
05097       } else if ( f->frametype == AST_FRAME_VIDEO ) {
05098          /*
05099          * IAX2 draft 03 says that timestamps MUST be in order.
05100          * It does not say anything about several frames having the same timestamp
05101          * When transporting video, we can have a frame that spans multiple iax packets
05102          * (so called slices), so it would make sense to use the same timestamp for all of
05103          * them
05104          * We do want to make sure that frames don't go backwards though
05105          */
05106          if ( (unsigned int)ms < p->lastsent )
05107             ms = p->lastsent;
05108       } else {
05109          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
05110             it's a genuine frame */
05111          if (genuine) {
05112             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
05113             if (ms <= p->lastsent)
05114                ms = p->lastsent + 3;
05115          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05116             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
05117             ms = p->lastsent + 3;
05118          }
05119       }
05120    }
05121    p->lastsent = ms;
05122    if (voice)
05123       p->nextpred = p->nextpred + f->samples / rate;
05124    return ms;
05125 }

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

Definition at line 4950 of file chan_iax2.c.

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

Referenced by send_trunk().

04951 {
04952    unsigned long int mssincetx; /* unsigned to handle overflows */
04953    long int ms, pred;
04954 
04955    tpeer->trunkact = *tv;
04956    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
04957    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04958       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
04959       tpeer->txtrunktime = *tv;
04960       tpeer->lastsent = 999999;
04961    }
04962    /* Update last transmit time now */
04963    tpeer->lasttxtime = *tv;
04964    
04965    /* Calculate ms offset */
04966    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
04967    /* Predict from last value */
04968    pred = tpeer->lastsent + sampms;
04969    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04970       ms = pred;
04971    
04972    /* We never send the same timestamp twice, so fudge a little if we must */
04973    if (ms == tpeer->lastsent)
04974       ms = tpeer->lastsent + 1;
04975    tpeer->lastsent = ms;
04976    return ms;
04977 }

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

Definition at line 2200 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02201 {
02202    return abs(ast_random());
02203 }

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

Definition at line 1761 of file chan_iax2.c.

References addr_range_match_address_cb(), ao2_callback(), ao2_ref(), ast_inet_ntoa(), ast_log(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, calltoken_ignores, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, LOG_DEBUG, option_debug, peer_unref(), S_OR, and user_unref().

Referenced by handle_call_token().

01762 {
01763    struct addr_range *addr_range;
01764    struct iax2_peer *peer = NULL;
01765    struct iax2_user *user = NULL;
01766    /* if no username is given, check for guest accounts */
01767    const char *find = S_OR(name, "guest");
01768    int res = 1;  /* required by default */
01769    int optional = 0;
01770    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01771    /* There are only two cases in which calltoken validation is not required.
01772     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
01773     *         the peer definition has not set the requirecalltoken option.
01774     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
01775     */
01776 
01777    /* ----- Case 1 ----- */
01778    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01779       ao2_ref(addr_range, -1);
01780       optional = 1;
01781    }
01782 
01783    /* ----- Case 2 ----- */
01784    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01785       calltoken_required = user->calltoken_required;
01786    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 1))) {
01787       calltoken_required = peer->calltoken_required;
01788    }
01789 
01790    if (peer) {
01791       peer_unref(peer);
01792    }
01793    if (user) {
01794       user_unref(user);
01795    }
01796    if (option_debug) {
01797    ast_log(LOG_DEBUG, "Determining if address %s with username %s requires calltoken validation.  Optional = %d  calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
01798    }
01799    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01800       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01801       res = 0;
01802    }
01803 
01804    return res;
01805 }

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

Definition at line 6296 of file chan_iax2.c.

References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), 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_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax2_context::context, chan_iax2_pvt::context, iax2_user::contexts, iax2_user::dbsecret, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, 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_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, ies, iax2_user::inkeys, iax2_user::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), secret, iax2_user::secret, user_unref(), ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.

Referenced by socket_process().

06297 {
06298    /* Start pessimistic */
06299    int res = -1;
06300    int version = 2;
06301    struct iax2_user *user = NULL, *best = NULL;
06302    int bestscore = 0;
06303    int gotcapability = 0;
06304    struct ast_variable *v = NULL, *tmpvar = NULL;
06305    struct ao2_iterator i;
06306 
06307    if (!iaxs[callno])
06308       return res;
06309    if (ies->called_number)
06310       ast_string_field_set(iaxs[callno], exten, ies->called_number);
06311    if (ies->calling_number) {
06312       ast_shrink_phone_number(ies->calling_number);
06313       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06314    }
06315    if (ies->calling_name)
06316       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06317    if (ies->calling_ani)
06318       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06319    if (ies->dnid)
06320       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06321    if (ies->rdnis)
06322       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06323    if (ies->called_context)
06324       ast_string_field_set(iaxs[callno], context, ies->called_context);
06325    if (ies->language)
06326       ast_string_field_set(iaxs[callno], language, ies->language);
06327    if (ies->username)
06328       ast_string_field_set(iaxs[callno], username, ies->username);
06329    if (ies->calling_ton > -1)
06330       iaxs[callno]->calling_ton = ies->calling_ton;
06331    if (ies->calling_tns > -1)
06332       iaxs[callno]->calling_tns = ies->calling_tns;
06333    if (ies->calling_pres > -1)
06334       iaxs[callno]->calling_pres = ies->calling_pres;
06335    if (ies->format)
06336       iaxs[callno]->peerformat = ies->format;
06337    if (ies->adsicpe)
06338       iaxs[callno]->peeradsicpe = ies->adsicpe;
06339    if (ies->capability) {
06340       gotcapability = 1;
06341       iaxs[callno]->peercapability = ies->capability;
06342    } 
06343    if (ies->version)
06344       version = ies->version;
06345 
06346    /* Use provided preferences until told otherwise for actual preferences */
06347    if(ies->codec_prefs) {
06348       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06349       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06350    }
06351 
06352    if (!gotcapability) 
06353       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06354    if (version > IAX_PROTO_VERSION) {
06355       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
06356          ast_inet_ntoa(sin->sin_addr), version);
06357       return res;
06358    }
06359    /* Search the userlist for a compatible entry, and fill in the rest */
06360    i = ao2_iterator_init(users, 0);
06361    while ((user = ao2_iterator_next(&i))) {
06362       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
06363          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
06364          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
06365          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
06366               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
06367          if (!ast_strlen_zero(iaxs[callno]->username)) {
06368             /* Exact match, stop right now. */
06369             if (best)
06370                user_unref(best);
06371             best = user;
06372             break;
06373          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06374             /* No required authentication */
06375             if (user->ha) {
06376                /* There was host authentication and we passed, bonus! */
06377                if (bestscore < 4) {
06378                   bestscore = 4;
06379                   if (best)
06380                      user_unref(best);
06381                   best = user;
06382                   continue;
06383                }
06384             } else {
06385                /* No host access, but no secret, either, not bad */
06386                if (bestscore < 3) {
06387                   bestscore = 3;
06388                   if (best)
06389                      user_unref(best);
06390                   best = user;
06391                   continue;
06392                }
06393             }
06394          } else {
06395             if (user->ha) {
06396                /* Authentication, but host access too, eh, it's something.. */
06397                if (bestscore < 2) {
06398                   bestscore = 2;
06399                   if (best)
06400                      user_unref(best);
06401                   best = user;
06402                   continue;
06403                }
06404             } else {
06405                /* Authentication and no host access...  This is our baseline */
06406                if (bestscore < 1) {
06407                   bestscore = 1;
06408                   if (best)
06409                      user_unref(best);
06410                   best = user;
06411                   continue;
06412                }
06413             }
06414          }
06415       }
06416       user_unref(user);
06417    }
06418    user = best;
06419    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06420       user = realtime_user(iaxs[callno]->username, sin);
06421       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
06422           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
06423          user = user_unref(user);
06424       }
06425    }
06426    if (user) {
06427       /* We found our match (use the first) */
06428       /* copy vars */
06429       for (v = user->vars ; v ; v = v->next) {
06430          if((tmpvar = ast_variable_new(v->name, v->value))) {
06431             tmpvar->next = iaxs[callno]->vars; 
06432             iaxs[callno]->vars = tmpvar;
06433          }
06434       }
06435       /* If a max AUTHREQ restriction is in place, activate it */
06436       if (user->maxauthreq > 0)
06437          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06438       iaxs[callno]->prefs = user->prefs;
06439       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06440       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06441       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06442       iaxs[callno]->encmethods = user->encmethods;
06443       /* Store the requested username if not specified */
06444       if (ast_strlen_zero(iaxs[callno]->username))
06445          ast_string_field_set(iaxs[callno], username, user->name);
06446       /* Store whether this is a trunked call, too, of course, and move if appropriate */
06447       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06448       iaxs[callno]->capability = user->capability;
06449       /* And use the default context */
06450       if (ast_strlen_zero(iaxs[callno]->context)) {
06451          if (user->contexts)
06452             ast_string_field_set(iaxs[callno], context, user->contexts->context);
06453          else
06454             ast_string_field_set(iaxs[callno], context, context);
06455       }
06456       /* And any input keys */
06457       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06458       /* And the permitted authentication methods */
06459       iaxs[callno]->authmethods = user->authmethods;
06460       iaxs[callno]->adsi = user->adsi;
06461       /* If the user has callerid, override the remote caller id. */
06462       if (ast_test_flag(user, IAX_HASCALLERID)) {
06463          iaxs[callno]->calling_tns = 0;
06464          iaxs[callno]->calling_ton = 0;
06465          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06466          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06467          ast_string_field_set(iaxs[callno], ani, user->cid_num);
06468          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06469       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06470          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06471       } /* else user is allowed to set their own CID settings */
06472       if (!ast_strlen_zero(user->accountcode))
06473          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06474       if (!ast_strlen_zero(user->mohinterpret))
06475          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06476       if (!ast_strlen_zero(user->mohsuggest))
06477          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06478       if (user->amaflags)
06479          iaxs[callno]->amaflags = user->amaflags;
06480       if (!ast_strlen_zero(user->language))
06481          ast_string_field_set(iaxs[callno], language, user->language);
06482       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
06483       /* Keep this check last */
06484       if (!ast_strlen_zero(user->dbsecret)) {
06485          char *family, *key=NULL;
06486          char buf[80];
06487          family = ast_strdupa(user->dbsecret);
06488          key = strchr(family, '/');
06489          if (key) {
06490             *key = '\0';
06491             key++;
06492          }
06493          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06494             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06495          else
06496             ast_string_field_set(iaxs[callno], secret, buf);
06497       } else
06498          ast_string_field_set(iaxs[callno], secret, user->secret);
06499       res = 0;
06500       user = user_unref(user);
06501    } else {
06502        /* user was not found, but we should still fake an AUTHREQ.
06503         * Set authmethods to the last known authmethod used by the system
06504         * Set a fake secret, it's not looked at, just required to attempt authentication.
06505         * Set authrej so the AUTHREP is rejected without even looking at its contents */
06506       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06507       ast_string_field_set(iaxs[callno], secret, "badsecret");
06508       iaxs[callno]->authrej = 1;
06509       if (!ast_strlen_zero(iaxs[callno]->username)) {
06510          /* only send the AUTHREQ if a username was specified. */
06511          res = 0;
06512       }
06513    }
06514    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
06515    return res;
06516 }

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

Definition at line 8052 of file chan_iax2.c.

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

Referenced by socket_process().

08053 {
08054    unsigned int ourver;
08055    char rsi[80];
08056    snprintf(rsi, sizeof(rsi), "si-%s", si);
08057    if (iax_provision_version(&ourver, rsi, 1))
08058       return 0;
08059    if (option_debug)
08060       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08061    if (ourver != ver) 
08062       iax2_provision(sin, sockfd, NULL, rsi, 1);
08063    return 0;
08064 }

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

Check if address can be used as packet source.

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

Definition at line 10524 of file chan_iax2.c.

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

Referenced by peer_set_srcaddr().

10525 {
10526    int sd;
10527    int res;
10528    
10529    sd = socket(AF_INET, SOCK_DGRAM, 0);
10530    if (sd < 0) {
10531       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10532       return -1;
10533    }
10534 
10535    res = bind(sd, sa, salen);
10536    if (res < 0) {
10537       if (option_debug)
10538          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
10539       close(sd);
10540       return 1;
10541    }
10542 
10543    close(sd);
10544    return 0;
10545 }

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

Definition at line 7023 of file chan_iax2.c.

References ARRAY_LEN, ast_copy_string(), 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, iax2_dpcache::callno, dpcache_lock, chan_iax2_pvt::dpentries, errno, 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, ies, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.

Referenced by socket_process().

07024 {
07025    char exten[256] = "";
07026    int status = CACHE_FLAG_UNKNOWN;
07027    int expiry = iaxdefaultdpcache;
07028    int x;
07029    int matchmore = 0;
07030    struct iax2_dpcache *dp, *prev;
07031    
07032    if (ies->called_number)
07033       ast_copy_string(exten, ies->called_number, sizeof(exten));
07034 
07035    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07036       status = CACHE_FLAG_EXISTS;
07037    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07038       status = CACHE_FLAG_CANEXIST;
07039    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07040       status = CACHE_FLAG_NONEXISTENT;
07041 
07042    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
07043       /* Don't really do anything with this */
07044    }
07045    if (ies->refresh)
07046       expiry = ies->refresh;
07047    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07048       matchmore = CACHE_FLAG_MATCHMORE;
07049    ast_mutex_lock(&dpcache_lock);
07050    prev = NULL;
07051    dp = pvt->dpentries;
07052    while(dp) {
07053       if (!strcmp(dp->exten, exten)) {
07054          /* Let them go */
07055          if (prev)
07056             prev->peer = dp->peer;
07057          else
07058             pvt->dpentries = dp->peer;
07059          dp->peer = NULL;
07060          dp->callno = 0;
07061          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07062          if (dp->flags & CACHE_FLAG_PENDING) {
07063             dp->flags &= ~CACHE_FLAG_PENDING;
07064             dp->flags |= status;
07065             dp->flags |= matchmore;
07066          }
07067          /* Wake up waiters */
07068          for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07069             if (dp->waiters[x] > -1) {
07070                if (write(dp->waiters[x], "asdf", 4) < 0) {
07071                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
07072                }
07073             }
07074          }
07075       }
07076       prev = dp;
07077       dp = dp->peer;
07078    }
07079    ast_mutex_unlock(&dpcache_lock);
07080    return 0;
07081 }

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

Definition at line 3253 of file chan_iax2.c.

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

03254 {
03255    int which = 0;
03256    struct iax2_peer *peer;
03257    char *res = NULL;
03258    int wordlen = strlen(word);
03259    struct ao2_iterator i;
03260 
03261    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
03262    if (pos != 3)
03263       return NULL;
03264 
03265    i = ao2_iterator_init(peers, 0);
03266    while ((peer = ao2_iterator_next(&i))) {
03267       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03268          res = ast_strdup(peer->name);
03269          peer_unref(peer);
03270          break;
03271       }
03272       peer_unref(peer);
03273    }
03274 
03275    return res;
03276 }

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

Definition at line 7083 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, iax_frame::list, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, ast_iax2_queue::queue, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.

Referenced by socket_process().

07084 {
07085    int peercallno = 0;
07086    struct chan_iax2_pvt *pvt = iaxs[callno];
07087    struct iax_frame *cur;
07088    jb_frame frame;
07089 
07090    if (ies->callno)
07091       peercallno = ies->callno;
07092 
07093    if (peercallno < 1) {
07094       ast_log(LOG_WARNING, "Invalid transfer request\n");
07095       return -1;
07096    }
07097    remove_by_transfercallno(pvt);
07098    /* since a transfer has taken place, the address will change.
07099     * This must be accounted for in the peercnts table.  Remove
07100     * the old address and add the new one */
07101    peercnt_remove_by_addr(&pvt->addr);
07102    peercnt_add(&pvt->transfer);
07103    /* now copy over the new address */
07104    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07105    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07106    /* Reset sequence numbers */
07107    pvt->oseqno = 0;
07108    pvt->rseqno = 0;
07109    pvt->iseqno = 0;
07110    pvt->aseqno = 0;
07111 
07112    if (pvt->peercallno) {
07113       remove_by_peercallno(pvt);
07114    }
07115    pvt->peercallno = peercallno;
07116    /*this is where the transfering call swiches hash tables */
07117    store_by_peercallno(pvt);
07118    pvt->transferring = TRANSFER_NONE;
07119    pvt->svoiceformat = -1;
07120    pvt->voiceformat = 0;
07121    pvt->svideoformat = -1;
07122    pvt->videoformat = 0;
07123    pvt->transfercallno = -1;
07124    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07125    memset(&pvt->offset, 0, sizeof(pvt->offset));
07126    /* reset jitterbuffer */
07127    while(jb_getall(pvt->jb,&frame) == JB_OK)
07128       iax2_frame_free(frame.data);
07129    jb_reset(pvt->jb);
07130    pvt->lag = 0;
07131    pvt->last = 0;
07132    pvt->lastsent = 0;
07133    pvt->nextpred = 0;
07134    pvt->pingtime = DEFAULT_RETRY_TIME;
07135    AST_LIST_LOCK(&iaxq.queue);
07136    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07137       /* We must cancel any packets that would have been transmitted
07138          because now we're talking to someone new.  It's okay, they
07139          were transmitted to someone that didn't care anyway. */
07140       if (callno == cur->callno) 
07141          cur->retries = -1;
07142    }
07143    AST_LIST_UNLOCK(&iaxq.queue);
07144    return 0; 
07145 }

static unsigned char compress_subclass ( int  subclass  )  [static]

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

01184 {
01185    int x;
01186    int power=-1;
01187    /* If it's 128 or smaller, just return it */
01188    if (subclass < IAX_FLAG_SC_LOG)
01189       return subclass;
01190    /* Otherwise find its power */
01191    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01192       if (subclass & (1 << x)) {
01193          if (power > -1) {
01194             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01195             return 0;
01196          } else
01197             power = x;
01198       }
01199    }
01200    return power | IAX_FLAG_SC_LOG;
01201 }

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

Definition at line 8066 of file chan_iax2.c.

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

Referenced by socket_process().

08067 {
08068    jb_info stats;
08069    jb_getinfo(pvt->jb, &stats);
08070    
08071    memset(iep, 0, sizeof(*iep));
08072 
08073    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08074    if(stats.frames_in == 0) stats.frames_in = 1;
08075    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08076    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08077    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08078    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08079    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08080 }

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

Definition at line 3876 of file chan_iax2.c.

References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

03877 {
03878    struct ast_hostent ahp;
03879    struct hostent *hp;
03880    struct iax2_peer *peer;
03881    int res = -1;
03882    struct ast_codec_pref ourprefs;
03883 
03884    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03885    cai->sockfd = defaultsockfd;
03886    cai->maxtime = 0;
03887    sin->sin_family = AF_INET;
03888 
03889    if (!(peer = find_peer(peername, 1))) {
03890       cai->found = 0;
03891 
03892       hp = ast_gethostbyname(peername, &ahp);
03893       if (hp) {
03894          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03895          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03896          /* use global iax prefs for unknown peer/user */
03897          /* But move the calling channel's native codec to the top of the preference list */
03898          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03899          if (c)
03900             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03901          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03902          return 0;
03903       } else {
03904          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03905          return -1;
03906       }
03907    }
03908 
03909    cai->found = 1;
03910    
03911    /* if the peer has no address (current or default), return failure */
03912    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03913       goto return_unref;
03914 
03915    /* if the peer is being monitored and is currently unreachable, return failure */
03916    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03917       goto return_unref;
03918 
03919    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03920    cai->maxtime = peer->maxms;
03921    cai->capability = peer->capability;
03922    cai->encmethods = peer->encmethods;
03923    cai->sockfd = peer->sockfd;
03924    cai->adsi = peer->adsi;
03925    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03926    /* Move the calling channel's native codec to the top of the preference list */
03927    if (c) {
03928       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03929       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03930    }
03931    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03932    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03933    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03934    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03935    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03936    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03937    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03938    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03939    if (ast_strlen_zero(peer->dbsecret)) {
03940       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03941    } else {
03942       char *family;
03943       char *key = NULL;
03944 
03945       family = ast_strdupa(peer->dbsecret);
03946       key = strchr(family, '/');
03947       if (key)
03948          *key++ = '\0';
03949       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03950          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03951          goto return_unref;
03952       }
03953    }
03954 
03955    if (peer->addr.sin_addr.s_addr) {
03956       sin->sin_addr = peer->addr.sin_addr;
03957       sin->sin_port = peer->addr.sin_port;
03958    } else {
03959       sin->sin_addr = peer->defaddr.sin_addr;
03960       sin->sin_port = peer->defaddr.sin_port;
03961    }
03962 
03963    res = 0;
03964 
03965 return_unref:
03966    peer_unref(peer);
03967 
03968    return res;
03969 }

static int create_callno_pools ( void   )  [static]

Definition at line 2205 of file chan_iax2.c.

References ao2_alloc(), ao2_container_alloc(), ao2_ref(), callno_hash(), callno_pool, CALLNO_POOL_BUCKETS, callno_pool_trunk, IAX_MAX_CALLS, and TRUNK_CALL_START.

Referenced by load_objects().

02206 {
02207    uint16_t i;
02208 
02209    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02210       return -1;
02211    }
02212 
02213    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02214       return -1;
02215    }
02216 
02217    /* start at 2, 0 and 1 are reserved */
02218    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02219       struct callno_entry *callno_entry;
02220 
02221       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02222          return -1;
02223       }
02224 
02225       callno_entry->callno = i;
02226 
02227       if (i < TRUNK_CALL_START) {
02228          ao2_link(callno_pool, callno_entry);
02229       } else {
02230          ao2_link(callno_pool_trunk, callno_entry);
02231       }
02232 
02233       ao2_ref(callno_entry, -1);
02234    }
02235 
02236    return 0;
02237 }

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

Definition at line 5335 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, f, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame(), and update_packet().

05336 {
05337    int padding;
05338    unsigned char *workspace;
05339 
05340    workspace = alloca(*datalen);
05341    memset(f, 0, sizeof(*f));
05342    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05343       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05344       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05345          return -1;
05346       /* Decrypt */
05347       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05348 
05349       padding = 16 + (workspace[15] & 0x0f);
05350       if (option_debug && iaxdebug)
05351          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05352       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05353          return -1;
05354 
05355       *datalen -= padding;
05356       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05357       f->frametype = fh->type;
05358       if (f->frametype == AST_FRAME_VIDEO) {
05359          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05360       } else {
05361          f->subclass = uncompress_subclass(fh->csub);
05362       }
05363    } else {
05364       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05365       if (option_debug && iaxdebug)
05366          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
05367       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05368          return -1;
05369       /* Decrypt */
05370       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05371       padding = 16 + (workspace[15] & 0x0f);
05372       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05373          return -1;
05374       *datalen -= padding;
05375       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05376    }
05377    return 0;
05378 }

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

Definition at line 5421 of file chan_iax2.c.

References ast_set_flag, ast_strdupa, ast_test_flag, build_encryption_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), and secret.

Referenced by socket_process().

05422 {
05423    int res=-1;
05424    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05425       /* Search for possible keys, given secrets */
05426       struct MD5Context md5;
05427       unsigned char digest[16];
05428       char *tmppw, *stringp;
05429       
05430       tmppw = ast_strdupa(iaxs[callno]->secret);
05431       stringp = tmppw;
05432       while ((tmppw = strsep(&stringp, ";"))) {
05433          MD5Init(&md5);
05434          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05435          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05436          MD5Final(digest, &md5);
05437          build_encryption_keys(digest, iaxs[callno]);
05438          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05439          if (!res) {
05440             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05441             break;
05442          }
05443       }
05444    } else 
05445       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05446    return res;
05447 }

static void defer_full_frame ( struct iax2_thread from_here,
struct iax2_thread to_here 
) [static]

Queue the last read full frame for processing by a certain thread.

If there are already any full frames queued, they are sorted by sequence number.

Definition at line 8128 of file chan_iax2.c.

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

Referenced by socket_read().

08129 {
08130    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08131    struct ast_iax2_full_hdr *fh, *cur_fh;
08132 
08133    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08134       return;
08135 
08136    pkt_buf->len = from_here->buf_len;
08137    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08138 
08139    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
08140    ast_mutex_lock(&to_here->lock);
08141    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
08142       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
08143       if (fh->oseqno < cur_fh->oseqno) {
08144          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
08145          break;
08146       }
08147    }
08148    AST_LIST_TRAVERSE_SAFE_END
08149 
08150    if (!cur_pkt_buf)
08151       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
08152    
08153    ast_mutex_unlock(&to_here->lock);
08154 }

static void delete_users ( void   )  [static]

Definition at line 11145 of file chan_iax2.c.

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

11146 {
11147    struct iax2_registry *reg;
11148 
11149    ao2_callback(users, 0, user_delme_cb, NULL);
11150 
11151    AST_LIST_LOCK(&registrations);
11152    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
11153       ast_sched_del(sched, reg->expire);
11154       if (reg->callno) {
11155          int callno = reg->callno;
11156          ast_mutex_lock(&iaxsl[callno]);
11157          if (iaxs[callno]) {
11158             iaxs[callno]->reg = NULL;
11159             iax2_destroy(callno);
11160          }
11161          ast_mutex_unlock(&iaxsl[callno]);
11162       }
11163       if (reg->dnsmgr)
11164          ast_dnsmgr_release(reg->dnsmgr);
11165       free(reg);
11166    }
11167    AST_LIST_UNLOCK(&registrations);
11168 
11169    ao2_callback(peers, 0, peer_delme_cb, NULL);
11170 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2567 of file chan_iax2.c.

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

Referenced by reload_firmware().

02568 {
02569    /* Close firmware */
02570    if (cur->fwh) {
02571       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02572    }
02573    close(cur->fd);
02574    free(cur);
02575 }

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

Definition at line 7900 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_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, and send_command().

Referenced by dp_lookup_thread(), and socket_process().

07901 {
07902    unsigned short dpstatus = 0;
07903    struct iax_ie_data ied1;
07904    int mm;
07905 
07906    memset(&ied1, 0, sizeof(ied1));
07907    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07908    /* Must be started */
07909    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07910       dpstatus = IAX_DPSTATUS_EXISTS;
07911    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07912       dpstatus = IAX_DPSTATUS_CANEXIST;
07913    } else {
07914       dpstatus = IAX_DPSTATUS_NONEXISTENT;
07915    }
07916    if (ast_ignore_pattern(context, callednum))
07917       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07918    if (mm)
07919       dpstatus |= IAX_DPSTATUS_MATCHMORE;
07920    if (!skiplock)
07921       ast_mutex_lock(&iaxsl[callno]);
07922    if (iaxs[callno]) {
07923       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
07924       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
07925       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
07926       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
07927    }
07928    if (!skiplock)
07929       ast_mutex_unlock(&iaxsl[callno]);
07930 }

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

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

07933 {
07934    /* Look up for dpreq */
07935    struct dpreq_data *dpr = data;
07936    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
07937    if (dpr->callerid)
07938       free(dpr->callerid);
07939    free(dpr);
07940    return NULL;
07941 }

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

Definition at line 5380 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, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.

Referenced by iax2_send(), and update_packet().

05381 {
05382    int padding;
05383    unsigned char *workspace;
05384    workspace = alloca(*datalen + 32);
05385    if (!workspace)
05386       return -1;
05387    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05388       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05389       if (option_debug && iaxdebug)
05390          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05391       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05392       padding = 16 + (padding & 0xf);
05393       memcpy(workspace, poo, padding);
05394       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05395       workspace[15] &= 0xf0;
05396       workspace[15] |= (padding & 0xf);
05397       if (option_debug && iaxdebug)
05398          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]);
05399       *datalen += padding;
05400       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05401       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05402          memcpy(poo, workspace + *datalen - 32, 32);
05403    } else {
05404       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05405       if (option_debug && iaxdebug)
05406          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
05407       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05408       padding = 16 + (padding & 0xf);
05409       memcpy(workspace, poo, padding);
05410       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05411       workspace[15] &= 0xf0;
05412       workspace[15] |= (padding & 0x0f);
05413       *datalen += padding;
05414       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05415       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05416          memcpy(poo, workspace + *datalen - 32, 32);
05417    }
05418    return 0;
05419 }

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

Definition at line 7329 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

07330 {
07331 #ifdef SCHED_MULTITHREADED
07332    if (schedule_action(__expire_registry, data))
07333 #endif      
07334       __expire_registry(data);
07335    return 0;
07336 }

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

Definition at line 11728 of file chan_iax2.c.

References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_tvcmp(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, dpcache_lock, chan_iax2_pvt::dpentries, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, 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().

11729 {
11730    struct iax2_dpcache *dp, *prev = NULL, *next;
11731    struct timeval tv;
11732    int x;
11733    int com[2];
11734    int timeout;
11735    int old=0;
11736    int outfd;
11737    int abort;
11738    int callno;
11739    struct ast_channel *c;
11740    struct ast_frame *f;
11741    gettimeofday(&tv, NULL);
11742    dp = dpcache;
11743    while(dp) {
11744       next = dp->next;
11745       /* Expire old caches */
11746       if (ast_tvcmp(tv, dp->expiry) > 0) {
11747             /* It's expired, let it disappear */
11748             if (prev)
11749                prev->next = dp->next;
11750             else
11751                dpcache = dp->next;
11752             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
11753                /* Free memory and go again */
11754                free(dp);
11755             } else {
11756                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);
11757             }
11758             dp = next;
11759             continue;
11760       }
11761       /* We found an entry that matches us! */
11762       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
11763          break;
11764       prev = dp;
11765       dp = next;
11766    }
11767    if (!dp) {
11768       /* No matching entry.  Create a new one. */
11769       /* First, can we make a callno? */
11770       callno = cache_get_callno_locked(data);
11771       if (callno < 0) {
11772          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11773          return NULL;
11774       }
11775       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11776          ast_mutex_unlock(&iaxsl[callno]);
11777          return NULL;
11778       }
11779       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11780       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11781       gettimeofday(&dp->expiry, NULL);
11782       dp->orig = dp->expiry;
11783       /* Expires in 30 mins by default */
11784       dp->expiry.tv_sec += iaxdefaultdpcache;
11785       dp->next = dpcache;
11786       dp->flags = CACHE_FLAG_PENDING;
11787       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
11788          dp->waiters[x] = -1;
11789       dpcache = dp;
11790       dp->peer = iaxs[callno]->dpentries;
11791       iaxs[callno]->dpentries = dp;
11792       /* Send the request if we're already up */
11793       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11794          iax2_dprequest(dp, callno);
11795       ast_mutex_unlock(&iaxsl[callno]);
11796    }
11797    /* By here we must have a dp */
11798    if (dp->flags & CACHE_FLAG_PENDING) {
11799       /* Okay, here it starts to get nasty.  We need a pipe now to wait
11800          for a reply to come back so long as it's pending */
11801       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
11802          /* Find an empty slot */
11803          if (dp->waiters[x] < 0)
11804             break;
11805       }
11806       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
11807          ast_log(LOG_WARNING, "No more waiter positions available\n");
11808          return NULL;
11809       }
11810       if (pipe(com)) {
11811          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11812          return NULL;
11813       }
11814       dp->waiters[x] = com[1];
11815       /* Okay, now we wait */
11816       timeout = iaxdefaulttimeout * 1000;
11817       /* Temporarily unlock */
11818       ast_mutex_unlock(&dpcache_lock);
11819       /* Defer any dtmf */
11820       if (chan)
11821          old = ast_channel_defer_dtmf(chan);
11822       abort = 0;
11823       while(timeout) {
11824          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11825          if (outfd > -1) {
11826             break;
11827          }
11828          if (c) {
11829             f = ast_read(c);
11830             if (f)
11831                ast_frfree(f);
11832             else {
11833                /* Got hung up on, abort! */
11834                break;
11835                abort = 1;
11836             }
11837          }
11838       }
11839       if (!timeout) {
11840          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11841       }
11842       ast_mutex_lock(&dpcache_lock);
11843       dp->waiters[x] = -1;
11844       close(com[1]);
11845       close(com[0]);
11846       if (abort) {
11847          /* Don't interpret anything, just abort.  Not sure what th epoint
11848            of undeferring dtmf on a hung up channel is but hey whatever */
11849          if (!old && chan)
11850             ast_channel_undefer_dtmf(chan);
11851          return NULL;
11852       }
11853       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11854          /* Now to do non-independent analysis the results of our wait */
11855          if (dp->flags & CACHE_FLAG_PENDING) {
11856             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
11857                pending.  Don't let it take as long to timeout. */
11858             dp->flags &= ~CACHE_FLAG_PENDING;
11859             dp->flags |= CACHE_FLAG_TIMEOUT;
11860             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
11861                systems without leaving it unavailable once the server comes back online */
11862             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11863             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11864                if (dp->waiters[x] > -1) {
11865                   if (write(dp->waiters[x], "asdf", 4) < 0) {
11866                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11867                   }
11868                }
11869             }
11870          }
11871       }
11872       /* Our caller will obtain the rest */
11873       if (!old && chan)
11874          ast_channel_undefer_dtmf(chan);
11875    }
11876    return dp;  
11877 }

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

Definition at line 2467 of file chan_iax2.c.

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02467                                                                                                                                     {
02468 
02469    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02470 }

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

Definition at line 2472 of file chan_iax2.c.

References __find_callno().

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

02472                                                                                                                                            {
02473 
02474    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02475 }

static struct iax2_thread* find_idle_thread ( void   )  [static]

Definition at line 1016 of file chan_iax2.c.

References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::list, and thread.

Referenced by __schedule_action(), and socket_read().

01017 {
01018    pthread_attr_t attr;
01019    struct iax2_thread *thread = NULL;
01020 
01021    /* Pop the head of the list off */
01022    AST_LIST_LOCK(&idle_list);
01023    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01024    AST_LIST_UNLOCK(&idle_list);
01025 
01026    /* If no idle thread is available from the regular list, try dynamic */
01027    if (thread == NULL) {
01028       AST_LIST_LOCK(&dynamic_list);
01029       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01030       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
01031       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
01032          /* We need to MAKE a thread! */
01033          if ((thread = ast_calloc(1, sizeof(*thread)))) {
01034             thread->threadnum = iaxdynamicthreadnum++;
01035             thread->type = IAX_TYPE_DYNAMIC;
01036             ast_mutex_init(&thread->lock);
01037             ast_cond_init(&thread->cond, NULL);
01038             pthread_attr_init(&attr);
01039             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
01040             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
01041                free(thread);
01042                thread = NULL;
01043             } else {
01044                /* All went well and the thread is up, so increment our count */
01045                iaxdynamicthreadcount++;
01046                
01047                /* Wait for the thread to be ready before returning it to the caller */
01048                while (!thread->ready_for_signal)
01049                   usleep(1);
01050             }
01051          }
01052       }
01053       AST_LIST_UNLOCK(&dynamic_list);
01054    }
01055 
01056    /* this thread is not processing a full frame (since it is idle),
01057       so ensure that the field for the full frame call number is empty */
01058    if (thread)
01059       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01060 
01061    return thread;
01062 }

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

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

Definition at line 1261 of file chan_iax2.c.

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

01262 {
01263    struct iax2_peer *peer = NULL;
01264    struct iax2_peer tmp_peer = {
01265       .name = name,
01266    };
01267 
01268    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01269 
01270    /* Now go for realtime if applicable */
01271    if(!peer && realtime)
01272       peer = realtime_peer(name, NULL);
01273 
01274    return peer;
01275 }

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

Definition at line 5167 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, tpeerlock, and tpeers.

Referenced by iax2_trunk_queue(), and socket_process().

05168 {
05169    struct iax2_trunk_peer *tpeer;
05170    
05171    /* Finds and locks trunk peer */
05172    ast_mutex_lock(&tpeerlock);
05173    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
05174       /* We don't lock here because tpeer->addr *never* changes */
05175       if (!inaddrcmp(&tpeer->addr, sin)) {
05176          ast_mutex_lock(&tpeer->lock);
05177          break;
05178       }
05179    }
05180    if (!tpeer) {
05181       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05182          ast_mutex_init(&tpeer->lock);
05183          tpeer->lastsent = 9999;
05184          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05185          tpeer->trunkact = ast_tvnow();
05186          ast_mutex_lock(&tpeer->lock);
05187          tpeer->next = tpeers;
05188          tpeer->sockfd = fd;
05189          tpeers = tpeer;
05190 #ifdef SO_NO_CHECK
05191          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05192 #endif
05193          if (option_debug)
05194             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05195       }
05196    }
05197    ast_mutex_unlock(&tpeerlock);
05198    return tpeer;
05199 }

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

Definition at line 1289 of file chan_iax2.c.

References ao2_find(), and iax2_user::name.

01290 {
01291    struct iax2_user tmp_user = {
01292       .name = name,
01293    };
01294 
01295    return ao2_find(users, &tmp_user, OBJ_POINTER);
01296 }

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

Definition at line 4979 of file chan_iax2.c.

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

Referenced by socket_process().

04980 {
04981    long ms; /* NOT unsigned */
04982    if (ast_tvzero(iaxs[callno]->rxcore)) {
04983       /* Initialize rxcore time if appropriate */
04984       gettimeofday(&iaxs[callno]->rxcore, NULL);
04985       /* Round to nearest 20ms so traces look pretty */
04986       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04987    }
04988    /* Calculate difference between trunk and channel */
04989    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
04990    /* Return as the sum of trunk time and the difference between trunk and real time */
04991    return ms + ts;
04992 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 10276 of file chan_iax2.c.

References free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

10277 {
10278    struct iax2_context *conl;
10279    while(con) {
10280       conl = con;
10281       con = con->next;
10282       free(conl);
10283    }
10284 }

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

Definition at line 12001 of file chan_iax2.c.

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

12002 {
12003    struct iax2_peer *peer;
12004    char *peername, *colname;
12005 
12006    peername = ast_strdupa(data);
12007 
12008    /* if our channel, return the IP address of the endpoint of current channel */
12009    if (!strcmp(peername,"CURRENTCHANNEL")) {
12010            unsigned short callno;
12011       if (chan->tech != &iax2_tech)
12012          return -1;
12013       callno = PTR_TO_CALLNO(chan->tech_pvt);   
12014       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
12015       return 0;
12016    }
12017 
12018    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
12019       *colname++ = '\0';
12020    else if ((colname = strchr(peername, '|')))
12021       *colname++ = '\0';
12022    else
12023       colname = "ip";
12024 
12025    if (!(peer = find_peer(peername, 1)))
12026       return -1;
12027 
12028    if (!strcasecmp(colname, "ip")) {
12029       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
12030    } else  if (!strcasecmp(colname, "status")) {
12031       peer_status(peer, buf, len); 
12032    } else  if (!strcasecmp(colname, "mailbox")) {
12033       ast_copy_string(buf, peer->mailbox, len);
12034    } else  if (!strcasecmp(colname, "context")) {
12035       ast_copy_string(buf, peer->context, len);
12036    } else  if (!strcasecmp(colname, "expire")) {
12037       snprintf(buf, len, "%d", peer->expire);
12038    } else  if (!strcasecmp(colname, "dynamic")) {
12039       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
12040    } else  if (!strcasecmp(colname, "callerid_name")) {
12041       ast_copy_string(buf, peer->cid_name, len);
12042    } else  if (!strcasecmp(colname, "callerid_num")) {
12043       ast_copy_string(buf, peer->cid_num, len);
12044    } else  if (!strcasecmp(colname, "codecs")) {
12045       ast_getformatname_multiple(buf, len -1, peer->capability);
12046    } else  if (!strncasecmp(colname, "codec[", 6)) {
12047       char *codecnum, *ptr;
12048       int index = 0, codec = 0;
12049       
12050       codecnum = strchr(colname, '[');
12051       *codecnum = '\0';
12052       codecnum++;
12053       if ((ptr = strchr(codecnum, ']'))) {
12054          *ptr = '\0';
12055       }
12056       index = atoi(codecnum);
12057       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
12058          ast_copy_string(buf, ast_getformatname(codec), len);
12059       } else {
12060          buf[0] = '\0';
12061       }
12062    } else {
12063       buf[0] = '\0';
12064    }
12065 
12066    peer_unref(peer);
12067 
12068    return 0;
12069 }

static int get_auth_methods ( char *  value  )  [static]

Definition at line 10508 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

10509 {
10510    int methods = 0;
10511    if (strstr(value, "rsa"))
10512       methods |= IAX_AUTH_RSA;
10513    if (strstr(value, "md5"))
10514       methods |= IAX_AUTH_MD5;
10515    if (strstr(value, "plaintext"))
10516       methods |= IAX_AUTH_PLAINTEXT;
10517    return methods;
10518 }

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

Definition at line 1138 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

01139 {
01140    int e;
01141    if (!strcasecmp(s, "aes128"))
01142       e = IAX_ENCRYPT_AES128;
01143    else if (ast_true(s))
01144       e = IAX_ENCRYPT_AES128;
01145    else
01146       e = 0;
01147    return e;
01148 }

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

Definition at line 3490 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

03491 {
03492 #ifdef SCHED_MULTITHREADED
03493    if (schedule_action(__get_from_jb, data))
03494 #endif      
03495       __get_from_jb(data);
03496    return 0;
03497 }

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

Definition at line 2138 of file chan_iax2.c.

References ao2_container_count(), ao2_find(), ao2_lock(), ao2_unlock(), ast_log(), callno_pool, callno_pool_trunk, global_maxcallno_nonval, LOG_WARNING, total_nonval_callno_used, and callno_entry::validated.

Referenced by __find_callno(), and make_trunk().

02139 {
02140    struct callno_entry *callno_entry = NULL;
02141    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02142       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02143       /* Minor optimization for the extreme case. */
02144       return NULL;
02145    }
02146 
02147    /* the callno_pool container is locked here primarily to ensure thread
02148     * safety of the total_nonval_callno_used check and increment */
02149    ao2_lock(callno_pool);
02150 
02151    /* only a certain number of nonvalidated call numbers should be allocated.
02152     * If there ever is an attack, this separates the calltoken validating
02153     * users from the non calltoken validating users. */
02154    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02155       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02156       ao2_unlock(callno_pool);
02157       return NULL;
02158    }
02159 
02160    /* unlink the object from the container, taking over ownership
02161     * of the reference the container had to the object */
02162    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02163 
02164    if (callno_entry) {
02165       callno_entry->validated = validated;
02166       if (!validated) {
02167          total_nonval_callno_used++;
02168       }
02169    }
02170 
02171    ao2_unlock(callno_pool);
02172    return callno_entry;
02173 }

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

References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), iax_ie_data::buf, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), 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, ies, 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, and uncompress_subclass().

Referenced by socket_process().

04185 {
04186 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04187 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04188    char buf[256] = { 0 };
04189    time_t t = time(NULL);
04190    char hash[41]; /* 40 char sha1 hash */
04191    int subclass = uncompress_subclass(fh->csub);
04192 
04193    /* ----- Case 1 ----- */
04194    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04195       struct iax_ie_data ied = {
04196          .buf = { 0 },
04197          .pos = 0,
04198       };
04199 
04200       /* create the hash with their address data and our timestamp */
04201       snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04202       ast_sha1_hash(hash, buf);
04203 
04204       snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04205       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf);
04206       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04207 
04208       return 1;
04209 
04210    /* ----- Case 2 ----- */
04211    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04212       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04213       char *rec_ts = NULL;      /* received timestamp */
04214       unsigned int rec_time;  /* received time_t */
04215 
04216       /* split the timestamp from the hash data */
04217       rec_hash = strchr((char *) ies->calltokendata, '?');
04218       if (rec_hash) {
04219          *rec_hash++ = '\0';
04220          rec_ts = (char *) ies->calltokendata;
04221       }
04222 
04223       /* check that we have valid data before we do any comparisons */
04224       if (!rec_hash || !rec_ts) {
04225          goto reject;
04226       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04227          goto reject;
04228       }
04229 
04230       /* create a hash with their address and the _TOKEN'S_ timestamp */
04231       snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04232       ast_sha1_hash(hash, buf);
04233 
04234       /* compare hashes and then check timestamp delay */
04235       if (strcmp(hash, rec_hash)) {
04236          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04237          goto reject; /* received hash does not match ours, reject */
04238       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04239          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04240          goto reject; /* too much delay, reject */
04241       }
04242 
04243       /* at this point the call token is valid, returning 0 
04244        * will allow socket_process to continue as usual */
04245       requirecalltoken_mark_auto(ies->username, subclass);
04246       return 0;
04247 
04248    /* ----- Case 3 ----- */
04249    } else { /* calltokens are not supported for this client, how do we respond? */
04250       if (calltoken_required(sin, ies->username, subclass)) {
04251          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(sin->sin_addr), ies->username);
04252          goto reject;
04253       }
04254       return 0; /* calltoken is not required for this addr, so permit it. */
04255    }
04256 
04257 reject:
04258    /* received frame has failed calltoken inspection, send apathetic reject messages */
04259    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04260       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04261    } else {
04262       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04263    }
04264 
04265    return 1;
04266 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

Definition at line 8098 of file chan_iax2.c.

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

08099 {
08100    struct iax2_pkt_buf *pkt_buf;
08101 
08102    ast_mutex_lock(&thread->lock);
08103 
08104    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08105       ast_mutex_unlock(&thread->lock);
08106 
08107       thread->buf = pkt_buf->buf;
08108       thread->buf_len = pkt_buf->len;
08109       thread->buf_size = pkt_buf->len + 1;
08110       
08111       socket_process(thread);
08112 
08113       thread->buf = NULL;
08114       ast_free(pkt_buf);
08115 
08116       ast_mutex_lock(&thread->lock);
08117    }
08118 
08119    ast_mutex_unlock(&thread->lock);
08120 }

static int handle_error ( void   )  [static]

Definition at line 2855 of file chan_iax2.c.

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

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

02856 {
02857    /* XXX Ideally we should figure out why an error occured and then abort those
02858       rather than continuing to try.  Unfortunately, the published interface does
02859       not seem to work XXX */
02860 #if 0
02861    struct sockaddr_in *sin;
02862    int res;
02863    struct msghdr m;
02864    struct sock_extended_err e;
02865    m.msg_name = NULL;
02866    m.msg_namelen = 0;
02867    m.msg_iov = NULL;
02868    m.msg_control = &e;
02869    m.msg_controllen = sizeof(e);
02870    m.msg_flags = 0;
02871    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02872    if (res < 0)
02873       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02874    else {
02875       if (m.msg_controllen) {
02876          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02877          if (sin) 
02878             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02879          else
02880             ast_log(LOG_WARNING, "No address detected??\n");
02881       } else {
02882          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02883       }
02884    }
02885 #endif
02886    return 0;
02887 }

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

Acknowledgment received for OUR registration.

Definition at line 7148 of file chan_iax2.c.

References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.

Referenced by socket_process().

07149 {
07150    struct iax2_registry *reg;
07151    /* Start pessimistic */
07152    char peer[256] = "";
07153    char msgstatus[60];
07154    int refresh = 60;
07155    char ourip[256] = "<Unspecified>";
07156    struct sockaddr_in oldus;
07157    struct sockaddr_in us;
07158    int oldmsgs;
07159 
07160    memset(&us, 0, sizeof(us));
07161    if (ies->apparent_addr)
07162       bcopy(ies->apparent_addr, &us, sizeof(us));
07163    if (ies->username)
07164       ast_copy_string(peer, ies->username, sizeof(peer));
07165    if (ies->refresh)
07166       refresh = ies->refresh;
07167    if (ies->calling_number) {
07168       /* We don't do anything with it really, but maybe we should */
07169    }
07170    reg = iaxs[callno]->reg;
07171    if (!reg) {
07172       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07173       return -1;
07174    }
07175    memcpy(&oldus, &reg->us, sizeof(oldus));
07176    oldmsgs = reg->messages;
07177    if (inaddrcmp(&reg->addr, sin)) {
07178       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07179       return -1;
07180    }
07181    memcpy(&reg->us, &us, sizeof(reg->us));
07182    if (ies->msgcount >= 0)
07183       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
07184    /* always refresh the registration at the interval requested by the server
07185       we are registering to
07186    */
07187    reg->refresh = refresh;
07188    AST_SCHED_DEL(sched, reg->expire);
07189    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07190    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
07191       if (option_verbose > 2) {
07192          if (reg->messages > 255)
07193             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07194          else if (reg->messages > 1)
07195             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07196          else if (reg->messages > 0)
07197             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
07198          else
07199             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
07200          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07201          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07202       }
07203       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07204    }
07205    reg->regstate = REG_STATE_REGISTERED;
07206    return 0;
07207 }

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

Definition at line 2276 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.

Referenced by resend_with_token(), and socket_process().

02277 {
02278    if (frametype != AST_FRAME_IAX) {
02279       return 0;
02280    }
02281    switch (subclass) {
02282    case IAX_COMMAND_NEW:
02283    case IAX_COMMAND_REGREQ:
02284    case IAX_COMMAND_FWDOWNL:
02285    case IAX_COMMAND_REGREL:
02286       return 1;
02287    case IAX_COMMAND_POKE:
02288       if (!inbound) {
02289          return 1;
02290       }
02291       break;
02292    }
02293    return 0;
02294 }

static int iax2_answer ( struct ast_channel c  )  [static]

Definition at line 4785 of file chan_iax2.c.

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

04786 {
04787    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04788    if (option_debug)
04789       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
04790    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04791 }

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

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

04631 {
04632    struct ast_channel *cs[3];
04633    struct ast_channel *who, *other;
04634    int to = -1;
04635    int res = -1;
04636    int transferstarted=0;
04637    struct ast_frame *f;
04638    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
04639    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
04640    struct timeval waittimer = {0, 0}, tv;
04641 
04642    lock_both(callno0, callno1);
04643    if (!iaxs[callno0] || !iaxs[callno1]) {
04644       unlock_both(callno0, callno1);
04645       return AST_BRIDGE_FAILED;
04646    }
04647    /* Put them in native bridge mode */
04648    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
04649       iaxs[callno0]->bridgecallno = callno1;
04650       iaxs[callno1]->bridgecallno = callno0;
04651    }
04652    /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */
04653    if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
04654       transferstarted = 1;
04655    }
04656    unlock_both(callno0, callno1);
04657 
04658    /* If not, try to bridge until we can execute a transfer, if we can */
04659    cs[0] = c0;
04660    cs[1] = c1;
04661    for (/* ever */;;) {
04662       /* Check in case we got masqueraded into */
04663       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04664          if (option_verbose > 2)
04665             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
04666          /* Remove from native mode */
04667          if (c0->tech == &iax2_tech) {
04668             ast_mutex_lock(&iaxsl[callno0]);
04669             iaxs[callno0]->bridgecallno = 0;
04670             ast_mutex_unlock(&iaxsl[callno0]);
04671          }
04672          if (c1->tech == &iax2_tech) {
04673             ast_mutex_lock(&iaxsl[callno1]);
04674             iaxs[callno1]->bridgecallno = 0;
04675             ast_mutex_unlock(&iaxsl[callno1]);
04676          }
04677          return AST_BRIDGE_FAILED_NOWARN;
04678       }
04679       if (c0->nativeformats != c1->nativeformats) {
04680          if (option_verbose > 2) {
04681             char buf0[255];
04682             char buf1[255];
04683             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04684             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04685             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04686          }
04687          /* Remove from native mode */
04688          lock_both(callno0, callno1);
04689          if (iaxs[callno0])
04690             iaxs[callno0]->bridgecallno = 0;
04691          if (iaxs[callno1])
04692             iaxs[callno1]->bridgecallno = 0;
04693          unlock_both(callno0, callno1);
04694          return AST_BRIDGE_FAILED_NOWARN;
04695       }
04696       /* check if transfered and if we really want native bridging */
04697       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04698          /* Try the transfer */
04699          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04700                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04701             ast_log(LOG_WARNING, "Unable to start the transfer\n");
04702          transferstarted = 1;
04703       }
04704       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04705          /* Call has been transferred.  We're no longer involved */
04706          gettimeofday(&tv, NULL);
04707          if (ast_tvzero(waittimer)) {
04708             waittimer = tv;
04709          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04710             c0->_softhangup |= AST_SOFTHANGUP_DEV;
04711             c1->_softhangup |= AST_SOFTHANGUP_DEV;
04712             *fo = NULL;
04713             *rc = c0;
04714             res = AST_BRIDGE_COMPLETE;
04715             break;
04716          }
04717       }
04718       to = 1000;
04719       who = ast_waitfor_n(cs, 2, &to);
04720       if (timeoutms > -1) {
04721          timeoutms -= (1000 - to);
04722          if (timeoutms < 0)
04723             timeoutms = 0;
04724       }
04725       if (!who) {
04726          if (!timeoutms) {
04727             res = AST_BRIDGE_RETRY;
04728             break;
04729          }
04730          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04731             res = AST_BRIDGE_FAILED;
04732             break;
04733          }
04734          continue;
04735       }
04736       f = ast_read(who);
04737       if (!f) {
04738          *fo = NULL;
04739          *rc = who;
04740          res = AST_BRIDGE_COMPLETE;
04741          break;
04742       }
04743       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04744          *fo = f;
04745          *rc = who;
04746          res =  AST_BRIDGE_COMPLETE;
04747          break;
04748       }
04749       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
04750       if ((f->frametype == AST_FRAME_VOICE) ||
04751          (f->frametype == AST_FRAME_TEXT) ||
04752          (f->frametype == AST_FRAME_VIDEO) || 
04753          (f->frametype == AST_FRAME_IMAGE) ||
04754          (f->frametype == AST_FRAME_DTMF) ||
04755          (f->frametype == AST_FRAME_CONTROL)) {
04756          /* monitored dtmf take out of the bridge.
04757           * check if we monitor the specific source.
04758           */
04759          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04760          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04761             *rc = who;
04762             *fo = f;
04763             res = AST_BRIDGE_COMPLETE;
04764             /* Remove from native mode */
04765             break;
04766          }
04767          /* everything else goes to the other side */
04768          ast_write(other, f);
04769       }
04770       ast_frfree(f);
04771       /* Swap who gets priority */
04772       cs[2] = cs[0];
04773       cs[0] = cs[1];
04774       cs[1] = cs[2];
04775    }
04776    lock_both(callno0, callno1);
04777    if(iaxs[callno0])
04778       iaxs[callno0]->bridgecallno = 0;
04779    if(iaxs[callno1])
04780       iaxs[callno1]->bridgecallno = 0;
04781    unlock_both(callno0, callno1);
04782    return res;
04783 }

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

Definition at line 4326 of file chan_iax2.c.

References ast_channel::_state, add_empty_calltoken_ie(), chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_copy_string(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), 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_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), 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_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, and chan_iax2_pvt::username.

04327 {
04328    struct sockaddr_in sin;
04329    char *l=NULL, *n=NULL, *tmpstr;
04330    struct iax_ie_data ied;
04331    char *defaultrdest = "s";
04332    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04333    struct parsed_dial_string pds;
04334    struct create_addr_info cai;
04335 
04336    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04337       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04338       return -1;
04339    }
04340 
04341    memset(&cai, 0, sizeof(cai));
04342    cai.encmethods = iax2_encryption;
04343 
04344    memset(&pds, 0, sizeof(pds));
04345    tmpstr = ast_strdupa(dest);
04346    parse_dial_string(tmpstr, &pds);
04347 
04348    if (ast_strlen_zero(pds.peer)) {
04349       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04350       return -1;
04351    }
04352 
04353    if (!pds.exten) {
04354       pds.exten = defaultrdest;
04355    }
04356 
04357    if (create_addr(pds.peer, c, &sin, &cai)) {
04358       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04359       return -1;
04360    }
04361 
04362    if (!pds.username && !ast_strlen_zero(cai.username))
04363       pds.username = cai.username;
04364    if (!pds.password && !ast_strlen_zero(cai.secret))
04365       pds.password = cai.secret;
04366    if (!pds.key && !ast_strlen_zero(cai.outkey))
04367       pds.key = cai.outkey;
04368    if (!pds.context && !ast_strlen_zero(cai.peercontext))
04369       pds.context = cai.peercontext;
04370 
04371    /* Keep track of the context for outgoing calls too */
04372    ast_copy_string(c->context, cai.context, sizeof(c->context));
04373 
04374    if (pds.port)
04375       sin.sin_port = htons(atoi(pds.port));
04376 
04377    l = c->cid.cid_num;
04378    n = c->cid.cid_name;
04379 
04380    /* Now build request */ 
04381    memset(&ied, 0, sizeof(ied));
04382 
04383    /* On new call, first IE MUST be IAX version of caller */
04384    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04385    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04386    if (pds.options && strchr(pds.options, 'a')) {
04387       /* Request auto answer */
04388       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04389    }
04390 
04391    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04392 
04393    if (l) {
04394       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04395       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04396    } else {
04397       if (n)
04398          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04399       else
04400          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04401    }
04402 
04403    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04404    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04405 
04406    if (n)
04407       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04408    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04409       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04410 
04411    if (!ast_strlen_zero(c->language))
04412       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04413    if (!ast_strlen_zero(c->cid.cid_dnid))
04414       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04415    if (!ast_strlen_zero(c->cid.cid_rdnis))
04416       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04417 
04418    if (pds.context)
04419       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04420 
04421    if (pds.username)
04422       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04423 
04424    if (cai.encmethods)
04425       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04426 
04427    ast_mutex_lock(&iaxsl[callno]);
04428 
04429    if (!ast_strlen_zero(c->context))
04430       ast_string_field_set(iaxs[callno], context, c->context);
04431 
04432    if (pds.username)
04433       ast_string_field_set(iaxs[callno], username, pds.username);
04434 
04435    iaxs[callno]->encmethods = cai.encmethods;
04436 
04437    iaxs[callno]->adsi = cai.adsi;
04438    
04439    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04440    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04441 
04442    if (pds.key)
04443       ast_string_field_set(iaxs[callno], outkey, pds.key);
04444    if (pds.password)
04445       ast_string_field_set(iaxs[callno], secret, pds.password);
04446 
04447    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04448    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04449    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04450    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04451 
04452    if (iaxs[callno]->maxtime) {
04453       /* Initialize pingtime and auto-congest time */
04454       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04455       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04456    } else if (autokill) {
04457       iaxs[callno]->pingtime = autokill / 2;
04458       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04459    }
04460 
04461    /* send the command using the appropriate socket for this peer */
04462    iaxs[callno]->sockfd = cai.sockfd;
04463 
04464    /* Transmit the string in a "NEW" request */
04465    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
04466    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04467 
04468    ast_mutex_unlock(&iaxsl[callno]);
04469    ast_setstate(c, AST_STATE_RINGING);
04470    
04471    return 0;
04472 }

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

part of the IAX2 dial plan switch interface

Definition at line 11903 of file chan_iax2.c.

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

11904 {
11905    int res = 0;
11906    struct iax2_dpcache *dp;
11907 #if 0
11908    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11909 #endif
11910    if ((priority != 1) && (priority != 2))
11911       return 0;
11912    ast_mutex_lock(&dpcache_lock);
11913    dp = find_cache(chan, data, context, exten, priority);
11914    if (dp) {
11915       if (dp->flags & CACHE_FLAG_CANEXIST)
11916          res= 1;
11917    }
11918    ast_mutex_unlock(&dpcache_lock);
11919    if (!dp) {
11920       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11921    }
11922    return res;
11923 }

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

Definition at line 3993 of file chan_iax2.c.

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

Referenced by iax2_call(), and update_registry().

03994 {
03995    time_t t;
03996    struct tm tm;
03997    unsigned int tmp;
03998    time(&t);
03999    if (!ast_strlen_zero(tz))
04000       ast_localtime(&t, &tm, tz);
04001    else
04002       ast_localtime(&t, &tm, NULL);
04003    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04004    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04005    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04006    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04007    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04008    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04009    return tmp;
04010 }

static void iax2_destroy ( int  callno  )  [static]

Definition at line 1429 of file chan_iax2.c.

References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), AST_SCHED_DEL_SPINLOCK, DEADLOCK_AVOIDANCE, iaxs, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), sched, chan_iax2_pvt::transfercallno, and update_max_trunk().

Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().

01430 {
01431    struct chan_iax2_pvt *pvt;
01432    struct ast_channel *owner;
01433 
01434 retry:
01435    pvt = iaxs[callno];
01436 
01437    owner = pvt ? pvt->owner : NULL;
01438 
01439    if (owner) {
01440       if (ast_mutex_trylock(&owner->lock)) {
01441          if (option_debug > 2)
01442             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01443          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01444          goto retry;
01445       }
01446    }
01447 
01448    /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we
01449     * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee
01450     * the pvt stays around, a ref count is added to it. */
01451    if (!owner && pvt) {
01452       ao2_ref(pvt, +1);
01453       AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01454       AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01455       ao2_ref(pvt, -1);
01456       if (iaxs[callno]) {
01457          iaxs[callno] = NULL;
01458       } else {
01459          pvt = NULL;
01460       }
01461    }
01462 
01463    if (pvt) {
01464       if (!owner) {
01465          pvt->owner = NULL;
01466       } else {
01467          /* If there's an owner, prod it to give up */
01468          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01469           * because we already hold the owner channel lock. */
01470          ast_queue_hangup(owner);
01471       }
01472 
01473       if (pvt->peercallno) {
01474          remove_by_peercallno(pvt);
01475       }
01476 
01477       if (pvt->transfercallno) {
01478          remove_by_transfercallno(pvt);
01479       }
01480 
01481       if (!owner) {
01482          ao2_ref(pvt, -1);
01483          pvt = NULL;
01484       }
01485    }
01486 
01487    if (owner) {
01488       ast_mutex_unlock(&owner->lock);
01489    }
01490 
01491    if (callno & 0x4000) {
01492       update_max_trunk();
01493    }
01494 }

static void iax2_destroy_helper ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1340 of file chan_iax2.c.

References ao2_find(), ast_atomic_fetchadd_int(), ast_clear_flag, 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, iax2_user::name, chan_iax2_pvt::pingid, sched, user_unref(), and chan_iax2_pvt::username.

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

01341 {
01342    /* Decrement AUTHREQ count if needed */
01343    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01344       struct iax2_user *user;
01345       struct iax2_user tmp_user = {
01346          .name = pvt->username,
01347       };
01348 
01349       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01350       if (user) {
01351          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01352          user = user_unref(user);       
01353       }
01354 
01355       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01356    }
01357 
01358    /* No more pings or lagrq's */
01359    AST_SCHED_DEL(sched, pvt->pingid);
01360    AST_SCHED_DEL(sched, pvt->lagid);
01361    AST_SCHED_DEL(sched, pvt->autoid);
01362    AST_SCHED_DEL(sched, pvt->authid);
01363    AST_SCHED_DEL(sched, pvt->initid);
01364    AST_SCHED_DEL(sched, pvt->jbid);
01365 }

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

Definition at line 12094 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(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, option_debug, parse_dial_string(), and peer_unref().

12095 {
12096    struct parsed_dial_string pds;
12097    char *tmp = ast_strdupa(data);
12098    struct iax2_peer *p;
12099    int res = AST_DEVICE_INVALID;
12100 
12101    memset(&pds, 0, sizeof(pds));
12102    parse_dial_string(tmp, &pds);
12103 
12104    if (ast_strlen_zero(pds.peer)) {
12105       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12106       return res;
12107    }
12108    
12109    if (option_debug > 2)
12110       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
12111 
12112    /* SLD: FIXME: second call to find_peer during registration */
12113    if (!(p = find_peer(pds.peer, 1)))
12114       return res;
12115 
12116    res = AST_DEVICE_UNAVAILABLE;
12117    if (option_debug > 2) 
12118       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12119          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12120    
12121    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12122        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12123       /* Peer is registered, or have default IP address
12124          and a valid registration */
12125       if (p->historicms == 0 || p->historicms <= p->maxms)
12126          /* let the core figure out whether it is in use or not */
12127          res = AST_DEVICE_UNKNOWN;  
12128    }
12129 
12130    peer_unref(p);
12131 
12132    return res;
12133 }

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

Definition at line 3609 of file chan_iax2.c.

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

03610 {
03611    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03612 }

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

Definition at line 3614 of file chan_iax2.c.

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

03615 {
03616    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03617 }

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

Definition at line 6147 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06148 {
06149    if (argc < 2 || argc > 3)
06150       return RESULT_SHOWUSAGE;
06151    iaxdebug = 1;
06152    ast_cli(fd, "IAX2 Debugging Enabled\n");
06153    return RESULT_SUCCESS;
06154 }

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

Definition at line 6165 of file chan_iax2.c.

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

06166 {
06167    if (argc < 3 || argc > 4)
06168       return RESULT_SHOWUSAGE;
06169    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06170    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06171    return RESULT_SUCCESS;
06172 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

Definition at line 9988 of file chan_iax2.c.

References add_empty_calltoken_ie(), iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.

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

09989 {
09990    struct iax_ie_data ied;
09991    if (option_debug && iaxdebug)
09992       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
09993 
09994    if (reg->dnsmgr && 
09995        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09996       /* Maybe the IP has changed, force DNS refresh */
09997       ast_dnsmgr_refresh(reg->dnsmgr);
09998    }
09999    
10000    /*
10001     * if IP has Changed, free allocated call to create a new one with new IP
10002     * call has the pointer to IP and must be updated to the new one
10003     */
10004    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
10005       int callno = reg->callno;
10006       ast_mutex_lock(&iaxsl[callno]);
10007       iax2_destroy(callno);
10008       ast_mutex_unlock(&iaxsl[callno]);
10009       reg->callno = 0;
10010    }
10011    if (!reg->addr.sin_addr.s_addr) {
10012       if (option_debug && iaxdebug)
10013          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
10014       /* Setup the next registration attempt */
10015       AST_SCHED_DEL(sched, reg->expire);
10016       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10017       return -1;
10018    }
10019 
10020    if (!reg->callno) {
10021       if (option_debug)
10022          ast_log(LOG_DEBUG, "Allocate call number\n");
10023       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
10024       if (reg->callno < 1) {
10025          ast_log(LOG_WARNING, "Unable to create call for registration\n");
10026          return -1;
10027       } else if (option_debug)
10028          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
10029       iaxs[reg->callno]->reg = reg;
10030       ast_mutex_unlock(&iaxsl[reg->callno]);
10031    }
10032    /* Schedule the next registration attempt */
10033    AST_SCHED_DEL(sched, reg->expire);
10034    /* Setup the next registration a little early */
10035    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10036    /* Send the request */
10037    memset(&ied, 0, sizeof(ied));
10038    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10039    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10040    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
10041    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10042    reg->regstate = REG_STATE_REGSENT;
10043    return 0;
10044 }

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

Definition at line 6984 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

06985 {
06986 #ifdef SCHED_MULTITHREADED
06987    if (schedule_action(__iax2_do_register_s, data))
06988 #endif      
06989       __iax2_do_register_s(data);
06990    return 0;
06991 }

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

Definition at line 6156 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06157 {
06158    if (argc < 3 || argc > 4)
06159       return RESULT_SHOWUSAGE;
06160    iaxtrunkdebug = 1;
06161    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
06162    return RESULT_SUCCESS;
06163 }

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

Definition at line 7709 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_process().

07710 {
07711    struct iax_ie_data ied;
07712    /* Auto-hangup with 30 seconds of inactivity */
07713    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
07714    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
07715    memset(&ied, 0, sizeof(ied));
07716    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07717    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07718    dp->flags |= CACHE_FLAG_TRANSMITTED;
07719 }

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

Execute IAX2 dialplan switch.

Definition at line 11949 of file chan_iax2.c.

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

11950 {
11951    char odata[256];
11952    char req[256];
11953    char *ncontext;
11954    struct iax2_dpcache *dp;
11955    struct ast_app *dial;
11956 #if 0
11957    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);
11958 #endif
11959    if (priority == 2) {
11960       /* Indicate status, can be overridden in dialplan */
11961       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
11962       if (dialstatus) {
11963          dial = pbx_findapp(dialstatus);
11964          if (dial) 
11965             pbx_exec(chan, dial, "");
11966       }
11967       return -1;
11968    } else if (priority != 1)
11969       return -1;
11970    ast_mutex_lock(&dpcache_lock);
11971    dp = find_cache(chan, data, context, exten, priority);
11972    if (dp) {
11973       if (dp->flags & CACHE_FLAG_EXISTS) {
11974          ast_copy_string(odata, data, sizeof(odata));
11975          ncontext = strchr(odata, '/');
11976          if (ncontext) {
11977             *ncontext = '\0';
11978             ncontext++;
11979             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
11980          } else {
11981             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
11982          }
11983          if (option_verbose > 2)
11984             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
11985       } else {
11986          ast_mutex_unlock(&dpcache_lock);
11987          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
11988          return -1;
11989       }
11990    }
11991    ast_mutex_unlock(&dpcache_lock);
11992    dial = pbx_findapp("Dial");
11993    if (dial) {
11994       return pbx_exec(chan, dial, req);
11995    } else {
11996       ast_log(LOG_WARNING, "No dial application registered\n");
11997    }
11998    return -1;
11999 }

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

Part of the IAX2 switch interface.

Definition at line 11880 of file chan_iax2.c.

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

11881 {
11882    struct iax2_dpcache *dp;
11883    int res = 0;
11884 #if 0
11885    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11886 #endif
11887    if ((priority != 1) && (priority != 2))
11888       return 0;
11889    ast_mutex_lock(&dpcache_lock);
11890    dp = find_cache(chan, data, context, exten, priority);
11891    if (dp) {
11892       if (dp->flags & CACHE_FLAG_EXISTS)
11893          res= 1;
11894    }
11895    ast_mutex_unlock(&dpcache_lock);
11896    if (!dp) {
11897       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11898    }
11899    return res;
11900 }

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

Definition at line 3636 of file chan_iax2.c.

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

03637 {
03638    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03639    ast_mutex_lock(&iaxsl[callno]);
03640    if (iaxs[callno])
03641       iaxs[callno]->owner = newchan;
03642    else
03643       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03644    ast_mutex_unlock(&iaxsl[callno]);
03645    return 0;
03646 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]

Definition at line 1423 of file chan_iax2.c.

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

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

01424 {
01425    AST_SCHED_DEL(sched, fr->retrans);
01426    iax_frame_free(fr);
01427 }

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

Definition at line 1310 of file chan_iax2.c.

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

Referenced by __find_callno().

01311 {
01312    struct iax2_peer *peer = NULL;
01313    int res = 0;
01314    struct ao2_iterator i;
01315 
01316    i = ao2_iterator_init(peers, 0);
01317    while ((peer = ao2_iterator_next(&i))) {
01318       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01319           (peer->addr.sin_port == sin.sin_port)) {
01320          ast_copy_string(host, peer->name, len);
01321          peer_unref(peer);
01322          res = 1;
01323          break;
01324       }
01325       peer_unref(peer);
01326    }
01327 
01328    if (!peer) {
01329       peer = realtime_peer(NULL, &sin);
01330       if (peer) {
01331          ast_copy_string(host, peer->name, len);
01332          peer_unref(peer);
01333          res = 1;
01334       }
01335    }
01336 
01337    return res;
01338 }

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 4852 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, and peer_unref().

Referenced by check_access().

04853 {
04854    struct iax2_peer *peer;
04855    int res = 0;
04856    struct ao2_iterator i;
04857 
04858    i = ao2_iterator_init(peers, 0);
04859    while ((peer = ao2_iterator_next(&i))) {
04860       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04861           (peer->addr.sin_port == sin.sin_port)) {
04862          res = ast_test_flag(peer, IAX_TRUNK);
04863          peer_unref(peer);
04864          break;
04865       }
04866       peer_unref(peer);
04867    }
04868 
04869    return res;
04870 }

static int iax2_hangup ( struct ast_channel c  )  [static]

Definition at line 4474 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), iax2_sched_add(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_WARNING, ast_channel::name, option_debug, option_verbose, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.

04475 {
04476    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04477    struct iax_ie_data ied;
04478    int alreadygone;
04479    memset(&ied, 0, sizeof(ied));
04480    ast_mutex_lock(&iaxsl[callno]);
04481    if (callno && iaxs[callno]) {
04482       if (option_debug)
04483          ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
04484       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04485       /* Send the hangup unless we have had a transmission error or are already gone */
04486       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04487       if (!iaxs[callno]->error && !alreadygone) {
04488          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04489             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04490          }
04491          if (!iaxs[callno]) {
04492             ast_mutex_unlock(&iaxsl[callno]);
04493             return 0;
04494          }
04495       }
04496       /* Explicitly predestroy it */
04497       iax2_predestroy(callno);
04498       /* If we were already gone to begin with, destroy us now */
04499       if (iaxs[callno] && alreadygone) {
04500          if (option_debug)
04501             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
04502          iax2_destroy(callno);
04503       } else if (iaxs[callno]) {
04504          iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
04505       }
04506    } else if (c->tech_pvt) {
04507       /* If this call no longer exists, but the channel still
04508        * references it we need to set the channel's tech_pvt to null
04509        * to avoid ast_channel_free() trying to free it.
04510        */
04511       c->tech_pvt = NULL;
04512    }
04513    ast_mutex_unlock(&iaxsl[callno]);
04514    if (option_verbose > 2) 
04515       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
04516    return 0;
04517 }

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

Definition at line 4793 of file chan_iax2.c.

References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, chan_iax2_pvt::mohinterpret, option_debug, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().

04794 {
04795    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04796    struct chan_iax2_pvt *pvt;
04797    int res = 0;
04798 
04799    if (option_debug && iaxdebug)
04800       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
04801 
04802    ast_mutex_lock(&iaxsl[callno]);
04803    pvt = iaxs[callno];
04804 
04805    if (wait_for_peercallno(pvt)) {
04806       res = -1;
04807       goto done;
04808    }
04809 
04810    switch (condition) {
04811    case AST_CONTROL_HOLD:
04812       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04813          ast_moh_start(c, data, pvt->mohinterpret);
04814          goto done;
04815       }
04816       break;
04817    case AST_CONTROL_UNHOLD:
04818       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04819          ast_moh_stop(c);
04820          goto done;
04821       }
04822    }
04823 
04824    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04825 
04826 done:
04827    ast_mutex_unlock(&iaxsl[callno]);
04828 
04829    return res;
04830 }

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

Part of the IAX2 Switch interface.

Definition at line 11926 of file chan_iax2.c.

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

11927 {
11928    int res = 0;
11929    struct iax2_dpcache *dp;
11930 #if 0
11931    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11932 #endif
11933    if ((priority != 1) && (priority != 2))
11934       return 0;
11935    ast_mutex_lock(&dpcache_lock);
11936    dp = find_cache(chan, data, context, exten, priority);
11937    if (dp) {
11938       if (dp->flags & CACHE_FLAG_MATCHMORE)
11939          res= 1;
11940    }
11941    ast_mutex_unlock(&dpcache_lock);
11942    if (!dp) {
11943       ast_log(LOG_WARNING, "Unable to make DP cache\n");
11944    }
11945    return res;
11946 }

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

Definition at line 6174 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06175 {
06176    if (argc < 3 || argc > 4)
06177       return RESULT_SHOWUSAGE;
06178    iaxdebug = 0;
06179    ast_cli(fd, "IAX2 Debugging Disabled\n");
06180    return RESULT_SUCCESS;
06181 }

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

Definition at line 6192 of file chan_iax2.c.

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

06193 {
06194    if (argc < 4 || argc > 5)
06195       return RESULT_SHOWUSAGE;
06196    jb_setoutput(jb_error_output, jb_warning_output, NULL);
06197    jb_debug_output("\n");
06198    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06199    return RESULT_SUCCESS;
06200 }

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

Definition at line 6183 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06184 {
06185    if (argc < 4 || argc > 5)
06186       return RESULT_SHOWUSAGE;
06187    iaxtrunkdebug = 0;
06188    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
06189    return RESULT_SUCCESS;
06190 }

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

Definition at line 10188 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

10189 {
10190    struct iax2_peer *peer = (struct iax2_peer *)data;
10191    peer->pokeexpire = -1;
10192 #ifdef SCHED_MULTITHREADED
10193    if (schedule_action(__iax2_poke_noanswer, data))
10194 #endif      
10195       __iax2_poke_noanswer(data);
10196    peer_unref(peer);
10197    return 0;
10198 }

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

Definition at line 10209 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_del(), iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, send_command(), and iax2_peer::sockfd.

Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().

10210 {
10211    int callno;
10212    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10213       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
10214         immediately after clearing things out */
10215       peer->lastms = 0;
10216       peer->historicms = 0;
10217       peer->pokeexpire = -1;
10218       peer->callno = 0;
10219       return 0;
10220    }
10221 
10222    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
10223    if ((callno = peer->callno) > 0) {
10224       ast_log(LOG_NOTICE, "Still have a callno...\n");
10225       ast_mutex_lock(&iaxsl[callno]);
10226       iax2_destroy(callno);
10227       ast_mutex_unlock(&iaxsl[callno]);
10228    }
10229    if (heldcall)
10230       ast_mutex_unlock(&iaxsl[heldcall]);
10231    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10232    if (heldcall)
10233       ast_mutex_lock(&iaxsl[heldcall]);
10234    if (peer->callno < 1) {
10235       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10236       return -1;
10237    }
10238 
10239    /* Speed up retransmission times for this qualify call */
10240    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10241    iaxs[peer->callno]->peerpoke = peer;
10242    
10243    /* Remove any pending pokeexpire task */
10244    if (peer->pokeexpire > -1) {
10245       if (!ast_sched_del(sched, peer->pokeexpire)) {
10246          peer->pokeexpire = -1;
10247          peer_unref(peer);
10248       }
10249    }
10250 
10251    /* Queue up a new task to handle no reply */
10252    /* If the host is already unreachable then use the unreachable interval instead */
10253    if (peer->lastms < 0) {
10254       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10255    } else
10256       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10257 
10258    if (peer->pokeexpire == -1)
10259       peer_unref(peer);
10260 
10261    /* And send the poke */
10262    ast_mutex_lock(&iaxsl[callno]);
10263    if (iaxs[callno]) {
10264       struct iax_ie_data ied = {
10265          .buf = { 0 },
10266          .pos = 0,
10267       };
10268       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
10269       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
10270    }
10271    ast_mutex_unlock(&iaxsl[callno]);
10272 
10273    return 0;
10274 }

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

Definition at line 10200 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

10201 {
10202    struct iax2_peer *peer = obj;
10203 
10204    iax2_poke_peer(peer, 0);
10205 
10206    return 0;
10207 }

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

Definition at line 7749 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

07750 {
07751    struct iax2_peer *peer = (struct iax2_peer *)data;
07752    peer->pokeexpire = -1;
07753 #ifdef SCHED_MULTITHREADED
07754    if (schedule_action(__iax2_poke_peer_s, data))
07755 #endif      
07756       __iax2_poke_peer_s(data);
07757    return 0;
07758 }

static int iax2_predestroy ( int  callno  )  [static]

Note:
Since this function calls iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 2939 of file chan_iax2.c.

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

Referenced by iax2_hangup(), and send_command_final().

02940 {
02941    struct ast_channel *c;
02942    struct chan_iax2_pvt *pvt = iaxs[callno];
02943 
02944    if (!pvt)
02945       return -1;
02946    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02947       iax2_destroy_helper(pvt);
02948       ast_set_flag(pvt, IAX_ALREADYGONE); 
02949    }
02950    c = pvt->owner;
02951    if (c) {
02952       c->tech_pvt = NULL;
02953       iax2_queue_hangup(callno);
02954       pvt->owner = NULL;
02955       ast_module_unref(ast_module_info->self);
02956    }
02957    return 0;
02958 }

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

Definition at line 9863 of file chan_iax2.c.

References ast_atomic_fetchadd_int(), ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.

Referenced by find_idle_thread(), and start_network_thread().

09864 {
09865    struct iax2_thread *thread = data;
09866    struct timeval tv;
09867    struct timespec ts;
09868    int put_into_idle = 0;
09869 
09870    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09871    pthread_cleanup_push(iax2_process_thread_cleanup, data);
09872    for(;;) {
09873       /* Wait for something to signal us to be awake */
09874       ast_mutex_lock(&thread->lock);
09875 
09876       /* Flag that we're ready to accept signals */
09877       thread->ready_for_signal = 1;
09878       
09879       /* Put into idle list if applicable */
09880       if (put_into_idle)
09881          insert_idle_thread(thread);
09882 
09883       if (thread->type == IAX_TYPE_DYNAMIC) {
09884          struct iax2_thread *t = NULL;
09885          /* Wait to be signalled or time out */
09886          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09887          ts.tv_sec = tv.tv_sec;
09888          ts.tv_nsec = tv.tv_usec * 1000;
09889          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09890             /* This thread was never put back into the available dynamic
09891              * thread list, so just go away. */
09892             if (!put_into_idle) {
09893                ast_mutex_unlock(&thread->lock);
09894                break;
09895             }
09896             AST_LIST_LOCK(&dynamic_list);
09897             /* Account for the case where this thread is acquired *right* after a timeout */
09898             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
09899                iaxdynamicthreadcount--;
09900             AST_LIST_UNLOCK(&dynamic_list);
09901             if (t) {
09902                /* This dynamic thread timed out waiting for a task and was
09903                 * not acquired immediately after the timeout, 
09904                 * so it's time to go away. */
09905                ast_mutex_unlock(&thread->lock);
09906                break;
09907             }
09908             /* Someone grabbed our thread *right* after we timed out.
09909              * Wait for them to set us up with something to do and signal
09910              * us to continue. */
09911             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09912             ts.tv_sec = tv.tv_sec;
09913             ts.tv_nsec = tv.tv_usec * 1000;
09914             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
09915             {
09916                ast_mutex_unlock(&thread->lock);
09917                break;
09918             }
09919          }
09920       } else {
09921          ast_cond_wait(&thread->cond, &thread->lock);
09922       }
09923 
09924       /* Go back into our respective list */
09925       put_into_idle = 1;
09926 
09927       ast_mutex_unlock(&thread->lock);
09928 
09929       if (thread->iostate == IAX_IOSTATE_IDLE)
09930          continue;
09931 
09932       /* Add ourselves to the active list now */
09933       AST_LIST_LOCK(&active_list);
09934       AST_LIST_INSERT_HEAD(&active_list, thread, list);
09935       AST_LIST_UNLOCK(&active_list);
09936 
09937       /* See what we need to do */
09938       switch(thread->iostate) {
09939       case IAX_IOSTATE_READY:
09940          thread->actions++;
09941          thread->iostate = IAX_IOSTATE_PROCESSING;
09942          socket_process(thread);
09943          handle_deferred_full_frames(thread);
09944          break;
09945       case IAX_IOSTATE_SCHEDREADY:
09946          thread->actions++;
09947          thread->iostate = IAX_IOSTATE_PROCESSING;
09948 #ifdef SCHED_MULTITHREADED
09949          thread->schedfunc(thread->scheddata);
09950 #endif      
09951          break;
09952       }
09953       time(&thread->checktime);
09954       thread->iostate = IAX_IOSTATE_IDLE;
09955 #ifdef DEBUG_SCHED_MULTITHREAD
09956       thread->curfunc[0]='\0';
09957 #endif      
09958 
09959       /* Now... remove ourselves from the active list, and return to the idle list */
09960       AST_LIST_LOCK(&active_list);
09961       AST_LIST_REMOVE(&active_list, thread, list);
09962       AST_LIST_UNLOCK(&active_list);
09963 
09964       /* Make sure another frame didn't sneak in there after we thought we were done. */
09965       handle_deferred_full_frames(thread);
09966    }
09967 
09968    /*!\note For some reason, idle threads are exiting without being removed
09969     * from an idle list, which is causing memory corruption.  Forcibly remove
09970     * it from the list, if it's there.
09971     */
09972    AST_LIST_LOCK(&idle_list);
09973    AST_LIST_REMOVE(&idle_list, thread, list);
09974    AST_LIST_UNLOCK(&idle_list);
09975 
09976    AST_LIST_LOCK(&dynamic_list);
09977    AST_LIST_REMOVE(&dynamic_list, thread, list);
09978    AST_LIST_UNLOCK(&dynamic_list);
09979 
09980    /* I am exiting here on my own volition, I need to clean up my own data structures
09981    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
09982    */
09983    pthread_cleanup_pop(1);
09984 
09985    return NULL;
09986 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

Definition at line 9854 of file chan_iax2.c.

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

Referenced by iax2_process_thread().

09855 {
09856    struct iax2_thread *thread = data;
09857    ast_mutex_destroy(&thread->lock);
09858    ast_cond_destroy(&thread->cond);
09859    free(thread);
09860    ast_atomic_dec_and_test(&iaxactivethreadcount);
09861 }

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

Definition at line 10143 of file chan_iax2.c.

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

10144 {
10145    int force = 0;
10146    int res;
10147    if (argc < 4)
10148       return RESULT_SHOWUSAGE;
10149    if ((argc > 4)) {
10150       if (!strcasecmp(argv[4], "forced"))
10151          force = 1;
10152       else
10153          return RESULT_SHOWUSAGE;
10154    }
10155    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
10156    if (res < 0)
10157       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
10158    else if (res < 1)
10159       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
10160    else
10161       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
10162    return RESULT_SUCCESS;
10163 }

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

Definition at line 10046 of file chan_iax2.c.

References iax_prov_complete_template().

10047 {
10048    if (pos != 3)
10049       return NULL;
10050    return iax_prov_complete_template(line, word, pos, state);
10051 }

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

Definition at line 10053 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().

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

10054 {
10055    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
10056       is found for template */
10057    struct iax_ie_data provdata;
10058    struct iax_ie_data ied;
10059    unsigned int sig;
10060    struct sockaddr_in sin;
10061    int callno;
10062    struct create_addr_info cai;
10063 
10064    memset(&cai, 0, sizeof(cai));
10065 
10066    if (option_debug)
10067       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
10068 
10069    if (iax_provision_build(&provdata, &sig, template, force)) {
10070       if (option_debug)
10071          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
10072       return 0;
10073    }
10074 
10075    if (end) {
10076       memcpy(&sin, end, sizeof(sin));
10077       cai.sockfd = sockfd;
10078    } else if (create_addr(dest, NULL, &sin, &cai))
10079       return -1;
10080 
10081    /* Build the rest of the message */
10082    memset(&ied, 0, sizeof(ied));
10083    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10084 
10085    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10086    if (!callno)
10087       return -1;
10088 
10089    if (iaxs[callno]) {
10090       /* Schedule autodestruct in case they don't ever give us anything back */
10091       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
10092       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
10093       ast_set_flag(iaxs[callno], IAX_PROVISION);
10094       /* Got a call number now, so go ahead and send the provisioning information */
10095       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10096    }
10097    ast_mutex_unlock(&iaxsl[callno]);
10098 
10099    return 1;
10100 }

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

Definition at line 3077 of file chan_iax2.c.

References ao2_unlink(), ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), prune_peers(), prune_users(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and user_unref().

03078 {
03079    struct iax2_peer *peer = NULL;
03080    struct iax2_user *user = NULL;
03081 
03082    if (argc != 4)
03083         return RESULT_SHOWUSAGE;
03084    if (!strcmp(argv[3],"all")) {
03085       prune_users();
03086       prune_peers();
03087       ast_cli(fd, "OK cache is flushed.\n");
03088       return RESULT_SUCCESS;
03089    }
03090    peer = find_peer(argv[3], 0);
03091    user = find_user(argv[3]);
03092    if (peer || user) {
03093       if (peer) {
03094          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03095             ast_set_flag(peer, IAX_RTAUTOCLEAR);
03096             expire_registry(peer_ref(peer));
03097             ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]);
03098          } else {
03099             ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]);
03100          }
03101          peer_unref(peer);
03102       }
03103       if (user) {
03104          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03105             ast_set_flag(user, IAX_RTAUTOCLEAR);
03106             ast_cli(fd, "User %s was removed from the cache.\n", argv[3]);
03107          } else {
03108             ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]);
03109          }
03110          ao2_unlink(users,user);
03111          user_unref(user);
03112       }
03113    } else {
03114       ast_cli(fd, "%s was not found in the cache.\n", argv[3]);
03115    }
03116 
03117    return RESULT_SUCCESS;
03118 }

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

Queue a control frame on the ast_channel owner.

This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.

Precondition:
Assumes lock for callno is already held.
Note:
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 2549 of file chan_iax2.c.

References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, iaxs, ast_channel::lock, and chan_iax2_pvt::owner.

Referenced by socket_process().

02551 {
02552    for (;;) {
02553       if (iaxs[callno] && iaxs[callno]->owner) {
02554          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02555             /* Avoid deadlock by pausing and trying again */
02556             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02557          } else {
02558             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02559             ast_mutex_unlock(&iaxs[callno]->owner->lock);
02560             break;
02561          }
02562       } else
02563          break;
02564    }
02565    return 0;
02566 }

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

Queue a frame to a call's owning asterisk channel.

Precondition:
This function assumes that iaxsl[callno] is locked when called.
Note:
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 2487 of file chan_iax2.c.

References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, iaxs, ast_channel::lock, and chan_iax2_pvt::owner.

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

02488 {
02489    for (;;) {
02490       if (iaxs[callno] && iaxs[callno]->owner) {
02491          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02492             /* Avoid deadlock by pausing and trying again */
02493             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02494          } else {
02495             ast_queue_frame(iaxs[callno]->owner, f);
02496             ast_mutex_unlock(&iaxs[callno]->owner->lock);
02497             break;
02498          }
02499       } else
02500          break;
02501    }
02502    return 0;
02503 }

static int iax2_queue_hangup ( int  callno  )  [static]

Queue a hangup frame on the ast_channel owner.

This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.

Precondition:
Assumes lock for callno is already held.
Note:
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.

Definition at line 2518 of file chan_iax2.c.

References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, iaxs, ast_channel::lock, and chan_iax2_pvt::owner.

Referenced by iax2_predestroy().

02519 {
02520    for (;;) {
02521       if (iaxs[callno] && iaxs[callno]->owner) {
02522          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02523             /* Avoid deadlock by pausing and trying again */
02524             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02525          } else {
02526             ast_queue_hangup(iaxs[callno]->owner);
02527             ast_mutex_unlock(&iaxs[callno]->owner->lock);
02528             break;
02529          }
02530       } else
02531          break;
02532    }
02533    return 0;
02534 }

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

Definition at line 4583 of file chan_iax2.c.

References ast_log(), and LOG_NOTICE.

04584 {
04585    ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
04586    return NULL;
04587 }

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

Definition at line 7209 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::entry, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, and secret.

Referenced by set_config().

07210 {
07211    struct iax2_registry *reg;
07212    char copy[256];
07213    char *username, *hostname, *secret;
07214    char *porta;
07215    char *stringp=NULL;
07216    
07217    if (!value)
07218       return -1;
07219    ast_copy_string(copy, value, sizeof(copy));
07220    stringp=copy;
07221    username = strsep(&stringp, "@");
07222    hostname = strsep(&stringp, "@");
07223    if (!hostname) {
07224       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
07225       return -1;
07226    }
07227    stringp=username;
07228    username = strsep(&stringp, ":");
07229    secret = strsep(&stringp, ":");
07230    stringp=hostname;
07231    hostname = strsep(&stringp, ":");
07232    porta = strsep(&stringp, ":");
07233    
07234    if (porta && !atoi(porta)) {
07235       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07236       return -1;
07237    }
07238    if (!(reg = ast_calloc(1, sizeof(*reg))))
07239       return -1;
07240    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
07241       free(reg);
07242       return -1;
07243    }
07244    ast_copy_string(reg->username, username, sizeof(reg->username));
07245    if (secret)
07246       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
07247    reg->expire = -1;
07248    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
07249    reg->addr.sin_family = AF_INET;
07250    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
07251    AST_LIST_LOCK(&registrations);
07252    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
07253    AST_LIST_UNLOCK(&registrations);
07254    
07255    return 0;
07256 }

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

Definition at line 11644 of file chan_iax2.c.

References reload_config().

11645 {
11646    return reload_config();
11647 }

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

Definition at line 10286 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_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.

10287 {
10288    int callno;
10289    int res;
10290    int fmt, native;
10291    struct sockaddr_in sin;
10292    struct ast_channel *c;
10293    struct parsed_dial_string pds;
10294    struct create_addr_info cai;
10295    char *tmpstr;
10296 
10297    memset(&pds, 0, sizeof(pds));
10298    tmpstr = ast_strdupa(data);
10299    parse_dial_string(tmpstr, &pds);
10300 
10301    if (ast_strlen_zero(pds.peer)) {
10302       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10303       return NULL;
10304    }
10305           
10306    memset(&cai, 0, sizeof(cai));
10307    cai.capability = iax2_capability;
10308 
10309    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10310    
10311    /* Populate our address from the given */
10312    if (create_addr(pds.peer, NULL, &sin, &cai)) {
10313       *cause = AST_CAUSE_UNREGISTERED;
10314       return NULL;
10315    }
10316 
10317    if (pds.port)
10318       sin.sin_port = htons(atoi(pds.port));
10319 
10320    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10321    if (callno < 1) {
10322       ast_log(LOG_WARNING, "Unable to create call\n");
10323       *cause = AST_CAUSE_CONGESTION;
10324       return NULL;
10325    }
10326 
10327    /* If this is a trunk, update it now */
10328    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
10329    if (ast_test_flag(&cai, IAX_TRUNK)) {
10330       int new_callno;
10331       if ((new_callno = make_trunk(callno, 1)) != -1)
10332          callno = new_callno;
10333    }
10334    iaxs[callno]->maxtime = cai.maxtime;
10335    if (cai.found)
10336       ast_string_field_set(iaxs[callno], host, pds.peer);
10337 
10338    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10339 
10340    ast_mutex_unlock(&iaxsl[callno]);
10341 
10342    if (c) {
10343       /* Choose a format we can live with */
10344       if (c->nativeformats & format) 
10345          c->nativeformats &= format;
10346       else {
10347          native = c->nativeformats;
10348          fmt = format;
10349          res = ast_translator_best_choice(&fmt, &native);
10350          if (res < 0) {
10351             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10352                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10353             ast_hangup(c);
10354             return NULL;
10355          }
10356          c->nativeformats = native;
10357       }
10358       c->readformat = ast_best_codec(c->nativeformats);
10359       c->writeformat = c->readformat;
10360    }
10361 
10362    return c;
10363 }

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

Definition at line 1093 of file chan_iax2.c.

References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), and sched_lock.

Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_hangup(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), sched_delay_remove(), socket_process(), update_jbsched(), and update_registry().

01094 {
01095    int res;
01096 
01097    ast_mutex_lock(&sched_lock);
01098    res = ast_sched_add(con, when, callback, data);
01099    ast_cond_signal(&sched_cond);
01100    ast_mutex_unlock(&sched_lock);
01101 
01102    return res;
01103 }

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

References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_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, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, 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::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, iax_frame::mydcx, 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, iax_frame::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.

Referenced by __send_command(), iax2_write(), and socket_process().

05450 {
05451    /* Queue a packet for delivery on a given private structure.  Use "ts" for
05452       timestamp, or calculate if ts is 0.  Send immediately without retransmission
05453       or delayed, with retransmission */
05454    struct ast_iax2_full_hdr *fh;
05455    struct ast_iax2_mini_hdr *mh;
05456    struct ast_iax2_video_hdr *vh;
05457    struct {
05458       struct iax_frame fr2;
05459       unsigned char buffer[4096];
05460    } frb;
05461    struct iax_frame *fr;
05462    int res;
05463    int sendmini=0;
05464    unsigned int lastsent;
05465    unsigned int fts;
05466 
05467    frb.fr2.afdatalen = sizeof(frb.buffer);
05468 
05469    if (!pvt) {
05470       ast_log(LOG_WARNING, "No private structure for packet?\n");
05471       return -1;
05472    }
05473    
05474    lastsent = pvt->lastsent;
05475 
05476    /* Calculate actual timestamp */
05477    fts = calc_timestamp(pvt, ts, f);
05478 
05479    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
05480     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
05481     * increment the "predicted timestamps" for voice, if we're predecting */
05482    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05483        return 0;
05484 
05485 
05486    if ((ast_test_flag(pvt, IAX_TRUNK) || 
05487          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05488          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05489       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
05490        (f->frametype == AST_FRAME_VOICE) 
05491       /* is a voice frame */ &&
05492       (f->subclass == pvt->svoiceformat) 
05493       /* is the same type */ ) {
05494          /* Force immediate rather than delayed transmission */
05495          now = 1;
05496          /* Mark that mini-style frame is appropriate */
05497          sendmini = 1;
05498    }
05499    if ( f->frametype == AST_FRAME_VIDEO ) {
05500       /*
05501        * If the lower 15 bits of the timestamp roll over, or if
05502        * the video format changed then send a full frame.
05503        * Otherwise send a mini video frame
05504        */
05505       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
05506           ((f->subclass & ~0x1) == pvt->svideoformat)
05507          ) {
05508          now = 1;
05509          sendmini = 1;
05510       } else {
05511          now = 0;
05512          sendmini = 0;
05513       }
05514       pvt->lastvsent = fts;
05515    }
05516    if (f->frametype == AST_FRAME_IAX) {
05517       /* 0x8000 marks this message as TX:, this bit will be stripped later */
05518       pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
05519       if (!pvt->first_iax_message) {
05520          pvt->first_iax_message = pvt->last_iax_message;
05521       }
05522    }
05523    /* Allocate an iax_frame */
05524    if (now) {
05525       fr = &frb.fr2;
05526    } else
05527       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
05528    if (!fr) {
05529       ast_log(LOG_WARNING, "Out of memory\n");
05530       return -1;
05531    }
05532    /* Copy our prospective frame into our immediate or retransmitted wrapper */
05533    iax_frame_wrap(fr, f);
05534 
05535    fr->ts = fts;
05536    fr->callno = pvt->callno;
05537    fr->transfer = transfer;
05538    fr->final = final;
05539    fr->encmethods = 0;
05540    if (!sendmini) {
05541       /* We need a full frame */
05542       if (seqno > -1)
05543          fr->oseqno = seqno;
05544       else
05545          fr->oseqno = pvt->oseqno++;
05546       fr->iseqno = pvt->iseqno;
05547       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
05548       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
05549       fh->ts = htonl(fr->ts);
05550       fh->oseqno = fr->oseqno;
05551       if (transfer) {
05552          fh->iseqno = 0;
05553       } else
05554          fh->iseqno = fr->iseqno;
05555       /* Keep track of the last thing we've acknowledged */
05556       if (!transfer)
05557          pvt->aseqno = fr->iseqno;
05558       fh->type = fr->af.frametype & 0xFF;
05559       if (fr->af.frametype == AST_FRAME_VIDEO)
05560          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
05561       else
05562          fh->csub = compress_subclass(fr->af.subclass);
05563       if (transfer) {
05564          fr->dcallno = pvt->transfercallno;
05565       } else
05566          fr->dcallno = pvt->peercallno;
05567       fh->dcallno = htons(fr->dcallno);
05568       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
05569       fr->data = fh;
05570       fr->retries = 0;
05571       /* Retry after 2x the ping time has passed */
05572       fr->retrytime = pvt->pingtime * 2;
05573       if (fr->retrytime < MIN_RETRY_TIME)
05574          fr->retrytime = MIN_RETRY_TIME;
05575       if (fr->retrytime > MAX_RETRY_TIME)
05576          fr->retrytime = MAX_RETRY_TIME;
05577       /* Acks' don't get retried */
05578       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
05579          fr->retries = -1;
05580       else if (f->frametype == AST_FRAME_VOICE)
05581          pvt->svoiceformat = f->subclass;
05582       else if (f->frametype == AST_FRAME_VIDEO)
05583          pvt->svideoformat = f->subclass & ~0x1;
05584       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05585          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05586             if (iaxdebug) {
05587                if (fr->transfer)
05588                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05589                else
05590                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05591             }
05592             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05593             fr->encmethods = pvt->encmethods;
05594             fr->ecx = pvt->ecx;
05595             fr->mydcx = pvt->mydcx;
05596             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05597          } else
05598             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05599       }
05600 
05601       if (now) {
05602          res = send_packet(fr);
05603       } else
05604          res = iax2_transmit(fr);
05605    } else {
05606       if (ast_test_flag(pvt, IAX_TRUNK)) {
05607          iax2_trunk_queue(pvt, fr);
05608          res = 0;
05609       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05610          /* Video frame have no sequence number */
05611          fr->oseqno = -1;
05612          fr->iseqno = -1;
05613          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
05614          vh->zeros = 0;
05615          vh->callno = htons(0x8000 | fr->callno);
05616          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05617          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05618          fr->data = vh;
05619          fr->retries = -1;
05620          res = send_packet(fr);        
05621       } else {
05622          /* Mini-frames have no sequence number */
05623          fr->oseqno = -1;
05624          fr->iseqno = -1;
05625          /* Mini frame will do */
05626          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
05627          mh->callno = htons(fr->callno);
05628          mh->ts = htons(fr->ts & 0xFFFF);
05629          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05630          fr->data = mh;
05631          fr->retries = -1;
05632          if (pvt->transferring == TRANSFER_MEDIAPASS)
05633             fr->transfer = 1;
05634          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05635             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05636                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05637             } else
05638                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05639          }
05640          res = send_packet(fr);
05641       }
05642    }
05643    return res;
05644 }

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

Definition at line 3631 of file chan_iax2.c.

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

03632 {
03633    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03634 }

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

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

03627 {
03628    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
03629 }

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

Definition at line 3619 of file chan_iax2.c.

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

03620 {
03621    
03622    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03623       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03624 }

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

Definition at line 4541 of file chan_iax2.c.

References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().

04542 {
04543    struct ast_option_header *h;
04544    int res;
04545 
04546    switch (option) {
04547    case AST_OPTION_TXGAIN:
04548    case AST_OPTION_RXGAIN:
04549       /* these two cannot be sent, because they require a result */
04550       errno = ENOSYS;
04551       return -1;
04552    default:
04553    {
04554       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04555       struct chan_iax2_pvt *pvt;
04556 
04557       ast_mutex_lock(&iaxsl[callno]);
04558       pvt = iaxs[callno];
04559 
04560       if (wait_for_peercallno(pvt)) {
04561          ast_mutex_unlock(&iaxsl[callno]);
04562          return -1;
04563       }
04564 
04565       ast_mutex_unlock(&iaxsl[callno]);
04566 
04567       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04568          return -1;
04569       }
04570 
04571       h->flag = AST_OPTION_FLAG_REQUEST;
04572       h->option = htons(option);
04573       memcpy(h->data, data, datalen);
04574       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04575                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
04576                  datalen + sizeof(*h), -1);
04577       free(h);
04578       return res;
04579    }
04580    }
04581 }

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

Definition at line 3304 of file chan_iax2.c.

References ast_cli(), ast_copy_string(), 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, dpcache_lock, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.

03305 {
03306    struct iax2_dpcache *dp;
03307    char tmp[1024], *pc;
03308    int s;
03309    int x,y;
03310    struct timeval tv;
03311    gettimeofday(&tv, NULL);
03312    ast_mutex_lock(&dpcache_lock);
03313    dp = dpcache;
03314    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03315    while(dp) {
03316       s = dp->expiry.tv_sec - tv.tv_sec;
03317       tmp[0] = '\0';
03318       if (dp->flags & CACHE_FLAG_EXISTS)
03319          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03320       if (dp->flags & CACHE_FLAG_NONEXISTENT)
03321          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03322       if (dp->flags & CACHE_FLAG_CANEXIST)
03323          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03324       if (dp->flags & CACHE_FLAG_PENDING)
03325          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03326       if (dp->flags & CACHE_FLAG_TIMEOUT)
03327          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03328       if (dp->flags & CACHE_FLAG_TRANSMITTED)
03329          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03330       if (dp->flags & CACHE_FLAG_MATCHMORE)
03331          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03332       if (dp->flags & CACHE_FLAG_UNKNOWN)
03333          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03334       /* Trim trailing pipe */
03335       if (!ast_strlen_zero(tmp))
03336          tmp[strlen(tmp) - 1] = '\0';
03337       else
03338          ast_copy_string(tmp, "(none)", sizeof(tmp));
03339       y=0;
03340       pc = strchr(dp->peercontext, '@');
03341       if (!pc)
03342          pc = dp->peercontext;
03343       else
03344          pc++;
03345       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
03346          if (dp->waiters[x] > -1)
03347             y++;
03348       if (s > 0)
03349          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03350       else
03351          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03352       dp = dp->next;
03353    }
03354    ast_mutex_unlock(&dpcache_lock);
03355    return RESULT_SUCCESS;
03356 }

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

Definition at line 2107 of file chan_iax2.c.

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

02108 {
02109    struct ao2_iterator i;
02110    struct peercnt *peercnt;
02111    struct sockaddr_in sin;
02112    int found = 0;
02113 
02114    if (argc < 4 || argc > 5)
02115       return RESULT_SHOWUSAGE;
02116 
02117    ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02118    i = ao2_iterator_init(peercnts, 0);
02119    while ((peercnt = ao2_iterator_next(&i))) {
02120       sin.sin_addr.s_addr = peercnt->addr;
02121       if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02122             ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02123             found = 1;
02124             break;
02125       } else {
02126          ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02127       }
02128       ao2_ref(peercnt, -1);
02129    }
02130    if (argc == 4) {
02131       ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02132    } else if (argc == 5 && !found) {
02133       ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] );
02134    }
02135    return RESULT_SUCCESS;
02136 }

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

Definition at line 5988 of file chan_iax2.c.

References ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.

05989 {
05990 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
05991 #define FORMAT  "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  %-5.5dms  %-4.4dms  %-4.4dms  %-6.6s  %s%s  %3s%s\n"
05992 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
05993    int x;
05994    int numchans = 0;
05995    int usedchans = 0;
05996    char first_message[10] = { 0, };
05997    char last_message[10] = { 0, };
05998 
05999    if (argc != 3)
06000       return RESULT_SHOWUSAGE;
06001    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06002    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06003       ast_mutex_lock(&iaxsl[x]);
06004       if (iaxs[x]) {
06005          int lag, jitter, localdelay;
06006          jb_info jbinfo;
06007          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06008             jb_getinfo(iaxs[x]->jb, &jbinfo);
06009             jitter = jbinfo.jitter;
06010             localdelay = jbinfo.current - jbinfo.min;
06011          } else {
06012             jitter = -1;
06013             localdelay = 0;
06014          }
06015 
06016          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06017          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06018          lag = iaxs[x]->remote_rr.delay;
06019          ast_cli(fd, FORMAT,
06020             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06021             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06022             S_OR(iaxs[x]->username, "(None)"),
06023             iaxs[x]->callno, iaxs[x]->peercallno,
06024             iaxs[x]->oseqno, iaxs[x]->iseqno,
06025             lag,
06026             jitter,
06027             localdelay,
06028             ast_getformatname(iaxs[x]->voiceformat),
06029             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06030             first_message,
06031             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06032             last_message);
06033          numchans++;
06034          if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */
06035             usedchans++;
06036          }  
06037       }
06038       ast_mutex_unlock(&iaxsl[x]);
06039    }
06040    ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : "");
06041    ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
06042    return RESULT_SUCCESS;
06043 #undef FORMAT
06044 #undef FORMAT2
06045 #undef FORMATB
06046 }

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

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

05900 {
05901 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
05902 #if !defined(__FreeBSD__)
05903 #define FORMAT "%-15.15s  %-15d %-15d\n"
05904 #else /* __FreeBSD__ */
05905 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
05906 #endif /* __FreeBSD__ */
05907    struct iax_firmware *cur;
05908    if ((argc != 3) && (argc != 4))
05909       return RESULT_SHOWUSAGE;
05910    ast_mutex_lock(&waresl.lock);
05911    
05912    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
05913    for (cur = waresl.wares;cur;cur = cur->next) {
05914       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
05915          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
05916             (int)ntohl(cur->fwh->datalen));
05917    }
05918    ast_mutex_unlock(&waresl.lock);
05919    return RESULT_SUCCESS;
05920 #undef FORMAT
05921 #undef FORMAT2
05922 }

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

Definition at line 6135 of file chan_iax2.c.

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

06136 {
06137    int numchans = 0;
06138    if (argc != 3)
06139       return RESULT_SHOWUSAGE;
06140    ast_cli(fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
06141    ast_cli(fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
06142    numchans = ast_cli_netstats(NULL, fd, 1);
06143    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06144    return RESULT_SUCCESS;
06145 }

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

Show one peer in detail.

Definition at line 3189 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, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mailbox, iax2_peer::maxcallno, iax2_peer::name, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.

03190 {
03191    char status[30];
03192    char cbuf[256];
03193    struct iax2_peer *peer;
03194    char codec_buf[512];
03195    int x = 0, codec = 0, load_realtime = 0;
03196 
03197    if (argc < 4)
03198       return RESULT_SHOWUSAGE;
03199 
03200    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
03201 
03202    peer = find_peer(argv[3], load_realtime);
03203    if (peer) {
03204       ast_cli(fd,"\n\n");
03205       ast_cli(fd, "  * Name       : %s\n", peer->name);
03206       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
03207       ast_cli(fd, "  Context      : %s\n", peer->context);
03208       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
03209       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
03210       ast_cli(fd, "  Callnum limit: %d\n", peer->maxcallno);
03211       ast_cli(fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03212 
03213 
03214       ast_cli(fd, "  Trunk        : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03215       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03216       ast_cli(fd, "  Expire       : %d\n", peer->expire);
03217       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
03218       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
03219       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03220       ast_cli(fd, "  Username     : %s\n", peer->username);
03221       ast_cli(fd, "  Codecs       : ");
03222       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03223       ast_cli(fd, "%s\n", codec_buf);
03224 
03225       ast_cli(fd, "  Codec Order  : (");
03226       for(x = 0; x < 32 ; x++) {
03227          codec = ast_codec_pref_index(&peer->prefs,x);
03228          if(!codec)
03229             break;
03230          ast_cli(fd, "%s", ast_getformatname(codec));
03231          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03232             ast_cli(fd, "|");
03233       }
03234 
03235       if (!x)
03236          ast_cli(fd, "none");
03237       ast_cli(fd, ")\n");
03238 
03239       ast_cli(fd, "  Status       : ");
03240       peer_status(peer, status, sizeof(status));   
03241       ast_cli(fd, "%s\n",status);
03242       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03243       ast_cli(fd,"\n");
03244       peer_unref(peer);
03245    } else {
03246       ast_cli(fd,"Peer %s not found.\n", argv[3]);
03247       ast_cli(fd,"\n");
03248    }
03249 
03250    return RESULT_SUCCESS;
03251 }

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

Definition at line 5888 of file chan_iax2.c.

References __iax2_show_peers().

05889 {
05890    return __iax2_show_peers(0, fd, NULL, argc, argv);
05891 }

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

Definition at line 5960 of file chan_iax2.c.

References iax2_registry::addr, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, iax2_registry::entry, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.

05961 {
05962 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
05963 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
05964    struct iax2_registry *reg = NULL;
05965 
05966    char host[80];
05967    char perceived[80];
05968    if (argc != 3)
05969       return RESULT_SHOWUSAGE;
05970    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05971    AST_LIST_LOCK(&registrations);
05972    AST_LIST_TRAVERSE(&registrations, reg, entry) {
05973       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05974       if (reg->us.sin_addr.s_addr) 
05975          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05976       else
05977          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05978       ast_cli(fd, FORMAT, host, 
05979                (reg->dnsmgr) ? "Y" : "N", 
05980                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05981    }
05982    AST_LIST_UNLOCK(&registrations);
05983    return RESULT_SUCCESS;
05984 #undef FORMAT
05985 #undef FORMAT2
05986 }

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

Definition at line 3278 of file chan_iax2.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, iax_frame::list, ast_iax2_queue::queue, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.

03279 {
03280    struct iax_frame *cur;
03281    int cnt = 0, dead=0, final=0;
03282 
03283    if (argc != 3)
03284       return RESULT_SHOWUSAGE;
03285 
03286    AST_LIST_LOCK(&iaxq.queue);
03287    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
03288       if (cur->retries < 0)
03289          dead++;
03290       if (cur->final)
03291          final++;
03292       cnt++;
03293    }
03294    AST_LIST_UNLOCK(&iaxq.queue);
03295 
03296    ast_cli(fd, "    IAX Statistics\n");
03297    ast_cli(fd, "---------------------\n");
03298    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03299    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03300    
03301    return RESULT_SUCCESS;
03302 }

static int iax2_show_threads ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 5829 of file chan_iax2.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, and thread.

05830 {
05831    struct iax2_thread *thread = NULL;
05832    time_t t;
05833    int threadcount = 0, dynamiccount = 0;
05834    char type;
05835 
05836    if (argc != 3)
05837       return RESULT_SHOWUSAGE;
05838       
05839    ast_cli(fd, "IAX2 Thread Information\n");
05840    time(&t);
05841    ast_cli(fd, "Idle Threads:\n");
05842    AST_LIST_LOCK(&idle_list);
05843    AST_LIST_TRAVERSE(&idle_list, thread, list) {
05844 #ifdef DEBUG_SCHED_MULTITHREAD
05845       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
05846          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05847 #else
05848       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
05849          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05850 #endif
05851       threadcount++;
05852    }
05853    AST_LIST_UNLOCK(&idle_list);
05854    ast_cli(fd, "Active Threads:\n");
05855    AST_LIST_LOCK(&active_list);
05856    AST_LIST_TRAVERSE(&active_list, thread, list) {
05857       if (thread->type == IAX_TYPE_DYNAMIC)
05858          type = 'D';
05859       else
05860          type = 'P';
05861 #ifdef DEBUG_SCHED_MULTITHREAD
05862       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
05863          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05864 #else
05865       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
05866          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05867 #endif
05868       threadcount++;
05869    }
05870    AST_LIST_UNLOCK(&active_list);
05871    ast_cli(fd, "Dynamic Threads:\n");
05872         AST_LIST_LOCK(&dynamic_list);
05873         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05874 #ifdef DEBUG_SCHED_MULTITHREAD
05875                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
05876                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05877 #else
05878                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05879                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05880 #endif
05881       dynamiccount++;
05882         }
05883         AST_LIST_UNLOCK(&dynamic_list);
05884    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05885    return RESULT_SUCCESS;
05886 }

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

Definition at line 5646 of file chan_iax2.c.

References ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), 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, iax2_user::name, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_user::secret, and user_unref().

05647 {
05648    regex_t regexbuf;
05649    int havepattern = 0;
05650 
05651 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
05652 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
05653 
05654    struct iax2_user *user = NULL;
05655    char auth[90];
05656    char *pstr = "";
05657    struct ao2_iterator i;
05658 
05659    switch (argc) {
05660    case 5:
05661       if (!strcasecmp(argv[3], "like")) {
05662          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05663             return RESULT_SHOWUSAGE;
05664          havepattern = 1;
05665       } else
05666          return RESULT_SHOWUSAGE;
05667    case 3:
05668       break;
05669    default:
05670       return RESULT_SHOWUSAGE;
05671    }
05672 
05673    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05674    i = ao2_iterator_init(users, 0);
05675    for (user = ao2_iterator_next(&i); user; 
05676       user_unref(user), user = ao2_iterator_next(&i)) {
05677       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
05678          continue;
05679       
05680       if (!ast_strlen_zero(user->secret)) {
05681          ast_copy_string(auth,user->secret,sizeof(auth));
05682       } else if (!ast_strlen_zero(user->inkeys)) {
05683          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05684       } else
05685          ast_copy_string(auth, "-no secret-", sizeof(auth));
05686       
05687       if(ast_test_flag(user,IAX_CODEC_NOCAP))
05688          pstr = "REQ Only";
05689       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05690          pstr = "Disabled";
05691       else
05692          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05693       
05694       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
05695          user->contexts ? user->contexts->context : context,
05696          user->ha ? "Yes" : "No", pstr);
05697    }
05698 
05699    if (havepattern)
05700       regfree(&regexbuf);
05701 
05702    return RESULT_SUCCESS;
05703 #undef FORMAT
05704 #undef FORMAT2
05705 }

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

Definition at line 4589 of file chan_iax2.c.

References AST_FRAME_IAX, ast_random(), 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, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.

04590 {
04591    int res;
04592    struct iax_ie_data ied0;
04593    struct iax_ie_data ied1;
04594    unsigned int transferid = (unsigned int)ast_random();
04595    memset(&ied0, 0, sizeof(ied0));
04596    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
04597    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
04598    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
04599 
04600    memset(&ied1, 0, sizeof(ied1));
04601    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
04602    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
04603    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
04604    
04605    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
04606    if (res)
04607       return -1;
04608    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
04609    if (res)
04610       return -1;
04611    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04612    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04613    return 0;
04614 }

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

Definition at line 3120 of file chan_iax2.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

03121 {
03122        if (argc != 4)
03123                return RESULT_SHOWUSAGE;
03124 
03125        test_losspct = atoi(argv[3]);
03126 
03127        return RESULT_SUCCESS;
03128 }

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

Definition at line 4832 of file chan_iax2.c.

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

04833 {
04834    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04835    struct iax_ie_data ied;
04836    char tmp[256], *context;
04837    ast_copy_string(tmp, dest, sizeof(tmp));
04838    context = strchr(tmp, '@');
04839    if (context) {
04840       *context = '\0';
04841       context++;
04842    }
04843    memset(&ied, 0, sizeof(ied));
04844    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04845    if (context)
04846       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04847    if (option_debug)
04848       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
04849    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04850 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

Definition at line 3590 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_iax2_queue::count, iaxq, ast_iax2_queue::queue, sched_lock, iax_frame::sentyet, and signal_condition().

Referenced by iax2_send().

03591 {
03592    /* Lock the queue and place this packet at the end */
03593    /* By setting this to 0, the network thread will send it for us, and
03594       queue retransmission if necessary */
03595    fr->sentyet = 0;
03596    AST_LIST_LOCK(&iaxq.queue);
03597    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
03598    iaxq.count++;
03599    AST_LIST_UNLOCK(&iaxq.queue);
03600    /* Wake up the network and scheduler thread */
03601    if (netthreadid != AST_PTHREADT_NULL)
03602       pthread_kill(netthreadid, SIGURG);
03603    signal_condition(&sched_lock, &sched_cond);
03604    return 0;
03605 }

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

Definition at line 7804 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

07805 {
07806    /* Drop when trunk is about 5 seconds idle */
07807    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
07808       return 1;
07809    return 0;
07810 }

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

Definition at line 5201 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_realloc, ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, 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().

05202 {
05203    struct ast_frame *f;
05204    struct iax2_trunk_peer *tpeer;
05205    void *tmp, *ptr;
05206    struct ast_iax2_meta_trunk_entry *met;
05207    struct ast_iax2_meta_trunk_mini *mtm;
05208 
05209    f = &fr->af;
05210    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05211    if (tpeer) {
05212       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05213          /* Need to reallocate space */
05214          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
05215             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05216                ast_mutex_unlock(&tpeer->lock);
05217                return -1;
05218             }
05219             
05220             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05221             tpeer->trunkdata = tmp;
05222             if (option_debug)
05223                ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
05224          } else {
05225             ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05226             ast_mutex_unlock(&tpeer->lock);
05227             return -1;
05228          }
05229       }
05230 
05231       /* Append to meta frame */
05232       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05233       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05234          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05235          mtm->len = htons(f->datalen);
05236          mtm->mini.callno = htons(pvt->callno);
05237          mtm->mini.ts = htons(0xffff & fr->ts);
05238          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05239          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05240       } else {
05241          met = (struct ast_iax2_meta_trunk_entry *)ptr;
05242          /* Store call number and length in meta header */
05243          met->callno = htons(pvt->callno);
05244          met->len = htons(f->datalen);
05245          /* Advance pointers/decrease length past trunk entry header */
05246          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05247          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05248       }
05249       /* Copy actual trunk data */
05250       memcpy(ptr, f->data, f->datalen);
05251       tpeer->trunkdatalen += f->datalen;
05252 
05253       tpeer->calls++;
05254       ast_mutex_unlock(&tpeer->lock);
05255    }
05256    return 0;
05257 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 7721 of file chan_iax2.c.

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

Referenced by socket_process().

07722 {
07723    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07724 }

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

Definition at line 6202 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, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.

06203 {
06204    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06205    int res = -1;
06206    ast_mutex_lock(&iaxsl[callno]);
06207    if (iaxs[callno]) {
06208    /* If there's an outstanding error, return failure now */
06209       if (!iaxs[callno]->error) {
06210          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06211             res = 0;
06212             /* Don't waste bandwidth sending null frames */
06213          else if (f->frametype == AST_FRAME_NULL)
06214             res = 0;
06215          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06216             res = 0;
06217          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06218             res = 0;
06219          else
06220          /* Simple, just queue for transmission */
06221             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06222       } else {
06223          if (option_debug)
06224             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
06225       }
06226    }
06227    /* If it's already gone, just return */
06228    ast_mutex_unlock(&iaxsl[callno]);
06229    return res;
06230 }

static int iax_check_version ( char *  dev  )  [static]

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

02723 {
02724    int res = 0;
02725    struct iax_firmware *cur;
02726    if (!ast_strlen_zero(dev)) {
02727       ast_mutex_lock(&waresl.lock);
02728       cur = waresl.wares;
02729       while(cur) {
02730          if (!strcmp(dev, (char *)cur->fwh->devname)) {
02731             res = ntohs(cur->fwh->version);
02732             break;
02733          }
02734          cur = cur->next;
02735       }
02736       ast_mutex_unlock(&waresl.lock);
02737    }
02738    return res;
02739 }

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

Definition at line 857 of file chan_iax2.c.

References ast_verbose().

Referenced by load_module().

00858 {
00859    if (iaxdebug)
00860       ast_verbose("%s", data);
00861 }

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

Definition at line 863 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

00864 {
00865    ast_log(LOG_WARNING, "%s", data);
00866 }

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

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

02742 {
02743    int res = -1;
02744    unsigned int bs = desc & 0xff;
02745    unsigned int start = (desc >> 8) & 0xffffff;
02746    unsigned int bytes;
02747    struct iax_firmware *cur;
02748    if (!ast_strlen_zero((char *)dev) && bs) {
02749       start *= bs;
02750       ast_mutex_lock(&waresl.lock);
02751       cur = waresl.wares;
02752       while(cur) {
02753          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
02754             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02755             if (start < ntohl(cur->fwh->datalen)) {
02756                bytes = ntohl(cur->fwh->datalen) - start;
02757                if (bytes > bs)
02758                   bytes = bs;
02759                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02760             } else {
02761                bytes = 0;
02762                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02763             }
02764             if (bytes == bs)
02765                res = 0;
02766             else
02767                res = 1;
02768             break;
02769          }
02770          cur = cur->next;
02771       }
02772       ast_mutex_unlock(&waresl.lock);
02773    }
02774    return res;
02775 }

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

Definition at line 7992 of file chan_iax2.c.

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

Referenced by socket_process().

07993 {
07994    struct iax_dual *d;
07995    struct ast_channel *chan1m, *chan2m;
07996    pthread_t th;
07997    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07998    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07999    if (chan2m && chan1m) {
08000       /* Make formats okay */
08001       chan1m->readformat = chan1->readformat;
08002       chan1m->writeformat = chan1->writeformat;
08003       ast_channel_masquerade(chan1m, chan1);
08004       /* Setup the extensions and such */
08005       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08006       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08007       chan1m->priority = chan1->priority;
08008       
08009       /* We make a clone of the peer channel too, so we can play
08010          back the announcement */
08011       /* Make formats okay */
08012       chan2m->readformat = chan2->readformat;
08013       chan2m->writeformat = chan2->writeformat;
08014       ast_channel_masquerade(chan2m, chan2);
08015       /* Setup the extensions and such */
08016       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08017       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08018       chan2m->priority = chan2->priority;
08019       if (ast_do_masquerade(chan2m)) {
08020          ast_log(LOG_WARNING, "Masquerade failed :(\n");
08021          ast_hangup(chan2m);
08022          return -1;
08023       }
08024    } else {
08025       if (chan1m)
08026          ast_hangup(chan1m);
08027       if (chan2m)
08028          ast_hangup(chan2m);
08029       return -1;
08030    }
08031    if ((d = ast_calloc(1, sizeof(*d)))) {
08032       pthread_attr_t attr;
08033 
08034       pthread_attr_init(&attr);
08035       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08036 
08037       d->chan1 = chan1m;
08038       d->chan2 = chan2m;
08039       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
08040          pthread_attr_destroy(&attr);
08041          return 0;
08042       }
08043       pthread_attr_destroy(&attr);
08044       free(d);
08045    }
08046    return -1;
08047 }

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

Definition at line 7972 of file chan_iax2.c.

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

Referenced by iax_park().

07973 {
07974    struct ast_channel *chan1, *chan2;
07975    struct iax_dual *d;
07976    struct ast_frame *f;
07977    int ext;
07978    int res;
07979    d = stuff;
07980    chan1 = d->chan1;
07981    chan2 = d->chan2;
07982    free(d);
07983    f = ast_read(chan1);
07984    if (f)
07985       ast_frfree(f);
07986    res = ast_park_call(chan1, chan2, 0, &ext);
07987    ast_hangup(chan2);
07988    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07989    return NULL;
07990 }

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

Definition at line 1590 of file chan_iax2.c.

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

Referenced by socket_process().

01591 {
01592    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01593    if (new) {
01594       size_t afdatalen = new->afdatalen;
01595       memcpy(new, fr, sizeof(*new));
01596       iax_frame_wrap(new, &fr->af);
01597       new->afdatalen = afdatalen;
01598       new->data = NULL;
01599       new->datalen = 0;
01600       new->direction = DIRECTION_INGRESS;
01601       new->retrans = -1;
01602    }
01603    return new;
01604 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

Definition at line 1001 of file chan_iax2.c.

References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, and thread.

Referenced by iax2_process_thread().

01002 {
01003    if (thread->type == IAX_TYPE_DYNAMIC) {
01004       AST_LIST_LOCK(&dynamic_list);
01005       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01006       AST_LIST_UNLOCK(&dynamic_list);
01007    } else {
01008       AST_LIST_LOCK(&idle_list);
01009       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01010       AST_LIST_UNLOCK(&idle_list);
01011    }
01012 
01013    return;
01014 }

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

Definition at line 892 of file chan_iax2.c.

References ast_verbose().

Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().

00893 {
00894    va_list args;
00895    char buf[1024];
00896 
00897    va_start(args, fmt);
00898    vsnprintf(buf, 1024, fmt, args);
00899    va_end(args);
00900 
00901    ast_verbose("%s", buf);
00902 }

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

Definition at line 868 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

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

00869 {
00870    va_list args;
00871    char buf[1024];
00872 
00873    va_start(args, fmt);
00874    vsnprintf(buf, 1024, fmt, args);
00875    va_end(args);
00876 
00877    ast_log(LOG_ERROR, "%s", buf);
00878 }

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

Definition at line 880 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

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

00881 {
00882    va_list args;
00883    char buf[1024];
00884 
00885    va_start(args, fmt);
00886    vsnprintf(buf, 1024, fmt, args);
00887    va_end(args);
00888 
00889    ast_log(LOG_WARNING, "%s", buf);
00890 }

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 12578 of file chan_iax2.c.

References __unload_module(), ao2_callback(), ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register(), AST_LIST_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_random(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, DAHDI_FILE_PSEUDO, DAHDI_FILE_TIMER, iax2_registry::entry, errno, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), netsock, option_verbose, outsock, peer_set_sock_cb(), ast_iax2_queue::queue, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), VERBOSE_PREFIX_2, and waresl.

12579 {
12580    static const char config[] = "iax.conf";
12581    int res = 0;
12582    int x;
12583    struct iax2_registry *reg = NULL;
12584 
12585    if (load_objects()) {
12586       return AST_MODULE_LOAD_FAILURE;
12587    }
12588 
12589    randomcalltokendata = ast_random();
12590    ast_custom_function_register(&iaxpeer_function);
12591 
12592    iax_set_output(iax_debug_output);
12593    iax_set_error(iax_error_output);
12594    jb_setoutput(jb_error_output, jb_warning_output, NULL);
12595    
12596 #ifdef HAVE_DAHDI
12597 #ifdef DAHDI_TIMERACK
12598    timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
12599    if (timingfd < 0)
12600 #endif
12601       timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
12602    if (timingfd < 0) 
12603       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
12604 #endif
12605 
12606    memset(iaxs, 0, sizeof(iaxs));
12607 
12608    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12609       ast_mutex_init(&iaxsl[x]);
12610    }
12611    
12612    ast_cond_init(&sched_cond, NULL);
12613 
12614    io = io_context_create();
12615    sched = sched_context_create();
12616    
12617    if (!io || !sched) {
12618       ast_log(LOG_ERROR, "Out of memory\n");
12619       return -1;
12620    }
12621 
12622    netsock = ast_netsock_list_alloc();
12623    if (!netsock) {
12624       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
12625       return -1;
12626    }
12627    ast_netsock_init(netsock);
12628 
12629    outsock = ast_netsock_list_alloc();
12630    if (!outsock) {
12631       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12632       return -1;
12633    }
12634    ast_netsock_init(outsock);
12635 
12636    ast_mutex_init(&waresl.lock);
12637 
12638    AST_LIST_HEAD_INIT(&iaxq.queue);
12639    
12640    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12641 
12642    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12643    
12644    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
12645    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
12646 
12647    if(set_config(config, 0) == -1)
12648       return AST_MODULE_LOAD_DECLINE;
12649 
12650    if (ast_channel_register(&iax2_tech)) {
12651       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12652       __unload_module();
12653       return -1;
12654    }
12655 
12656    if (ast_register_switch(&iax2_switch)) 
12657       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12658 
12659    res = start_network_thread();
12660    if (!res) {
12661       if (option_verbose > 1) 
12662          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
12663    } else {
12664       ast_log(LOG_ERROR, "Unable to start network thread\n");
12665       ast_netsock_release(netsock);
12666       ast_netsock_release(outsock);
12667    }
12668 
12669    AST_LIST_LOCK(&registrations);
12670    AST_LIST_TRAVERSE(&registrations, reg, entry)
12671       iax2_do_register(reg);
12672    AST_LIST_UNLOCK(&registrations); 
12673 
12674    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12675    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12676 
12677    reload_firmware(0);
12678    iax_provision_reload();
12679    return res;
12680 }

static int load_objects ( void   )  [static]

Definition at line 12521 of file chan_iax2.c.

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

Referenced by load_module().

12522 {
12523    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
12524    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
12525 
12526    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
12527       goto container_fail;
12528    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
12529       goto container_fail;
12530    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
12531       goto container_fail;
12532    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
12533       goto container_fail;
12534    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
12535       goto container_fail;
12536    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
12537       goto container_fail;
12538    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
12539       goto container_fail;
12540    } else if (create_callno_pools()) {
12541       goto container_fail;
12542    }
12543 
12544    return 0;
12545 
12546 container_fail:
12547    if (peers) {
12548       ao2_ref(peers, -1);
12549    }
12550    if (users) {
12551       ao2_ref(users, -1);
12552    }
12553    if (iax_peercallno_pvts) {
12554       ao2_ref(iax_peercallno_pvts, -1);
12555    }
12556    if (iax_transfercallno_pvts) {
12557       ao2_ref(iax_transfercallno_pvts, -1);
12558    }
12559    if (peercnts) {
12560       ao2_ref(peercnts, -1);
12561    }
12562    if (callno_limits) {
12563       ao2_ref(callno_limits, -1);
12564    }
12565    if (calltoken_ignores) {
12566       ao2_ref(calltoken_ignores, -1);
12567    }
12568    if (callno_pool) {
12569       ao2_ref(callno_pool, -1);
12570    }
12571    if (callno_pool_trunk) {
12572       ao2_ref(callno_pool_trunk, -1);
12573    }
12574    return AST_MODULE_LOAD_FAILURE;
12575 }

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

Definition at line 4616 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.

Referenced by iax2_bridge().

04617 {
04618    ast_mutex_lock(&iaxsl[callno0]);
04619    while (ast_mutex_trylock(&iaxsl[callno1])) {
04620       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
04621    }
04622 }

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

Definition at line 1654 of file chan_iax2.c.

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

Referenced by iax2_request(), and socket_process().

01655 {
01656    int x;
01657    int res= 0;
01658    struct callno_entry *callno_entry;
01659    if (iaxs[callno]->oseqno) {
01660       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01661       return -1;
01662    }
01663    if (callno & TRUNK_CALL_START) {
01664       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01665       return -1;
01666    }
01667    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01668       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01669       return -1;
01670    }
01671 
01672    x = callno_entry->callno;
01673    ast_mutex_lock(&iaxsl[x]);
01674 
01675    /*!
01676     * \note We delete these before switching the slot, because if
01677     * they fire in the meantime, they will generate a warning.
01678     */
01679    AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01680    AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01681    iaxs[x] = iaxs[callno];
01682    iaxs[x]->callno = x;
01683 
01684    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
01685     * before assigning the new one */
01686    if (iaxs[x]->callno_entry) {
01687       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01688    }
01689    iaxs[x]->callno_entry = callno_entry;
01690 
01691    iaxs[callno] = NULL;
01692    /* Update the two timers that should have been started */
01693    iaxs[x]->pingid = iax2_sched_add(sched, 
01694       ping_time * 1000, send_ping, (void *)(long)x);
01695    iaxs[x]->lagid = iax2_sched_add(sched, 
01696       lagrq_time * 1000, send_lagrq, (void *)(long)x);
01697 
01698    if (locked)
01699       ast_mutex_unlock(&iaxsl[callno]);
01700    res = x;
01701    if (!locked)
01702       ast_mutex_unlock(&iaxsl[x]);
01703 
01704    if (option_debug)
01705       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01706    /* We move this call from a non-trunked to a trunked call */
01707    update_max_trunk();
01708    update_max_nontrunk();
01709    return res;
01710 }

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

Definition at line 5892 of file chan_iax2.c.

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

Referenced by load_module().

05893 {
05894    ast_cli_netstats(s, -1, 0);
05895    astman_append(s, "\r\n");
05896    return RESULT_SUCCESS;
05897 }

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

Definition at line 5925 of file chan_iax2.c.

References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.

Referenced by load_module().

05926 {
05927    char *a[] = { "iax2", "show", "users" };
05928    int ret;
05929    const char *id = astman_get_header(m,"ActionID");
05930 
05931    if (!ast_strlen_zero(id))
05932       astman_append(s, "ActionID: %s\r\n",id);
05933    ret = __iax2_show_peers(1, -1, s, 3, a );
05934    astman_append(s, "\r\n\r\n" );
05935    return ret;
05936 } /* /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 1620 of file chan_iax2.c.

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

Referenced by __find_callno(), ao2_callback(), ast_parse_device_state(), check_blacklist(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), softhangup_exec(), and transfercallno_pvt_cmp_cb().

01621 {
01622    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01623       (cur->addr.sin_port == sin->sin_port)) {
01624       /* This is the main host */
01625       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01626           (check_dcallno ? dcallno == cur->callno : 1) ) {
01627          /* That's us.  Be sure we keep track of the peer call number */
01628          return 1;
01629       }
01630    }
01631    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01632        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01633       /* We're transferring */
01634       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01635          return 1;
01636    }
01637    return 0;
01638 }

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

Definition at line 5287 of file chan_iax2.c.

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

Referenced by decode_frame().

05288 {
05289 #if 0
05290    /* Debug with "fake encryption" */
05291    int x;
05292    if (len % 16)
05293       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05294    for (x=0;x<len;x++)
05295       dst[x] = src[x] ^ 0xff;
05296 #else 
05297    unsigned char lastblock[16] = { 0 };
05298    int x;
05299    while(len > 0) {
05300       aes_decrypt(src, dst, dcx);
05301       for (x=0;x<16;x++)
05302          dst[x] ^= lastblock[x];
05303       memcpy(lastblock, src, sizeof(lastblock));
05304       dst += 16;
05305       src += 16;
05306       len -= 16;
05307    }
05308 #endif
05309 }

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

Definition at line 5311 of file chan_iax2.c.

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

Referenced by encrypt_frame().

05312 {
05313 #if 0
05314    /* Debug with "fake encryption" */
05315    int x;
05316    if (len % 16)
05317       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05318    for (x=0;x<len;x++)
05319       dst[x] = src[x] ^ 0xff;
05320 #else
05321    unsigned char curblock[16] = { 0 };
05322    int x;
05323    while(len > 0) {
05324       for (x=0;x<16;x++)
05325          curblock[x] ^= src[x];
05326       aes_encrypt(curblock, dst, ecx);
05327       memcpy(curblock, dst, sizeof(curblock)); 
05328       dst += 16;
05329       src += 16;
05330       len -= 16;
05331    }
05332 #endif
05333 }

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

Definition at line 6536 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.

Referenced by authenticate_reply(), and socket_process().

06537 {
06538    /* Select exactly one common encryption if there are any */
06539    p->encmethods &= enc;
06540    if (p->encmethods) {
06541       if (p->encmethods & IAX_ENCRYPT_AES128)
06542          p->encmethods = IAX_ENCRYPT_AES128;
06543       else
06544          p->encmethods = 0;
06545    }
06546 }

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

Definition at line 10400 of file chan_iax2.c.

References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), attempt_transmit(), ast_iax2_queue::count, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, iax_frame::list, option_debug, ast_iax2_queue::queue, sched, send_packet(), and timing_read().

Referenced by start_network_thread().

10401 {
10402    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
10403       from the network, and queue them for delivery to the channels */
10404    int res, count, wakeup;
10405    struct iax_frame *f;
10406 
10407    if (timingfd > -1)
10408       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10409    
10410    for(;;) {
10411       pthread_testcancel();
10412 
10413       /* Go through the queue, sending messages which have not yet been
10414          sent, and scheduling retransmissions if appropriate */
10415       AST_LIST_LOCK(&iaxq.queue);
10416       count = 0;
10417       wakeup = -1;
10418       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
10419          if (f->sentyet)
10420             continue;
10421          
10422          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
10423          if (ast_mutex_trylock(&iaxsl[f->callno])) {
10424             wakeup = 1;
10425             continue;
10426          }
10427 
10428          f->sentyet++;
10429 
10430          if (iaxs[f->callno]) {
10431             send_packet(f);
10432             count++;
10433          } 
10434 
10435          ast_mutex_unlock(&iaxsl[f->callno]);
10436 
10437          if (f->retries < 0) {
10438             /* This is not supposed to be retransmitted */
10439             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
10440             iaxq.count--;
10441             /* Free the iax frame */
10442             iax_frame_free(f);
10443          } else {
10444             /* We need reliable delivery.  Schedule a retransmission */
10445             f->retries++;
10446             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10447          }
10448       }
10449       AST_LIST_TRAVERSE_SAFE_END
10450       AST_LIST_UNLOCK(&iaxq.queue);
10451 
10452       pthread_testcancel();
10453 
10454       if (option_debug && count >= 20)
10455          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10456 
10457       /* Now do the IO, and run scheduled tasks */
10458       res = ast_io_wait(io, wakeup);
10459       if (res >= 0) {
10460          if (option_debug && res >= 20)
10461             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10462       }
10463    }
10464    return NULL;
10465 }

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

Definition at line 1551 of file chan_iax2.c.

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

Referenced by __find_callno().

01552 {
01553    struct chan_iax2_pvt *tmp;
01554    jb_conf jbconf;
01555 
01556    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01557       return NULL;
01558    }
01559 
01560    if (ast_string_field_init(tmp, 32)) {
01561       ao2_ref(tmp, -1);
01562       tmp = NULL;
01563       return NULL;
01564    }
01565       
01566    tmp->prefs = prefs;
01567    tmp->callno = 0;
01568    tmp->peercallno = 0;
01569    tmp->transfercallno = 0;
01570    tmp->bridgecallno = 0;
01571    tmp->pingid = -1;
01572    tmp->lagid = -1;
01573    tmp->autoid = -1;
01574    tmp->authid = -1;
01575    tmp->initid = -1;
01576 
01577    ast_string_field_set(tmp,exten, "s");
01578    ast_string_field_set(tmp,host, host);
01579 
01580    tmp->jb = jb_new();
01581    tmp->jbid = -1;
01582    jbconf.max_jitterbuf = maxjitterbuffer;
01583    jbconf.resync_threshold = resyncthreshold;
01584    jbconf.max_contig_interp = maxjitterinterps;
01585    jb_setconf(tmp->jb,&jbconf);
01586 
01587    return tmp;
01588 }

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 4286 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, and parsed_dial_string::username.

Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().

04287 {
04288    if (ast_strlen_zero(data))
04289       return;
04290 
04291    pds->peer = strsep(&data, "/");
04292    pds->exten = strsep(&data, "/");
04293    pds->options = data;
04294 
04295    if (pds->exten) {
04296       data = pds->exten;
04297       pds->exten = strsep(&data, "@");
04298       pds->context = data;
04299    }
04300 
04301    if (strchr(pds->peer, '@')) {
04302       data = pds->peer;
04303       pds->username = strsep(&data, "@");
04304       pds->peer = data;
04305    }
04306 
04307    if (pds->username) {
04308       data = pds->username;
04309       pds->username = strsep(&data, ":");
04310       pds->password = data;
04311    }
04312 
04313    data = pds->peer;
04314    pds->peer = strsep(&data, ":");
04315    pds->port = data;
04316 
04317    /* check for a key name wrapped in [] in the secret position, if found,
04318       move it to the key field instead
04319    */
04320    if (pds->password && (pds->password[0] == '[')) {
04321       pds->key = ast_strip_quoted(pds->password, "[", "]");
04322       pds->password = NULL;
04323    }
04324 }

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

Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1230 of file chan_iax2.c.

References iax2_peer::name.

Referenced by load_objects().

01231 {
01232    struct iax2_peer *peer = obj, *peer2 = arg;
01233 
01234    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01235 }

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

Definition at line 11127 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

11128 {
11129    struct iax2_peer *peer = obj;
11130 
11131    ast_set_flag(peer, IAX_DELME);
11132 
11133    return 0;
11134 }

static void peer_destructor ( void *  obj  )  [static]

Definition at line 10623 of file chan_iax2.c.

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

Referenced by build_peer().

10624 {
10625    struct iax2_peer *peer = obj;
10626    int callno = peer->callno;
10627 
10628    ast_free_ha(peer->ha);
10629 
10630    if (callno > 0) {
10631       ast_mutex_lock(&iaxsl[callno]);
10632       iax2_destroy(callno);
10633       ast_mutex_unlock(&iaxsl[callno]);
10634    }
10635 
10636    register_peer_exten(peer, 0);
10637 
10638    if (peer->dnsmgr)
10639       ast_dnsmgr_release(peer->dnsmgr);
10640 
10641    ast_string_field_free_memory(peer);
10642 }

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

Note:
The only member of the peer passed here guaranteed to be set is the name field

Definition at line 1220 of file chan_iax2.c.

References ast_str_hash(), and iax2_peer::name.

Referenced by load_objects().

01221 {
01222    const struct iax2_peer *peer = obj;
01223 
01224    return ast_str_hash(peer->name);
01225 }

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

Definition at line 1277 of file chan_iax2.c.

References ao2_ref().

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

01278 {
01279    ao2_ref(peer, +1);
01280    return peer;
01281 }

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

Definition at line 12474 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

12475 {
12476    struct iax2_peer *peer = obj;
12477 
12478    if (peer->sockfd < 0)
12479       peer->sockfd = defaultsockfd;
12480 
12481    return 0;
12482 }

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

Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.

Definition at line 10550 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, io, LOG_WARNING, iax2_peer::name, netsock, option_debug, outsock, socket_read(), and iax2_peer::sockfd.

Referenced by build_peer().

10551 {
10552    struct sockaddr_in sin;
10553    int nonlocal = 1;
10554    int port = IAX_DEFAULT_PORTNO;
10555    int sockfd = defaultsockfd;
10556    char *tmp;
10557    char *addr;
10558    char *portstr;
10559 
10560    if (!(tmp = ast_strdupa(srcaddr)))
10561       return -1;
10562 
10563    addr = strsep(&tmp, ":");
10564    portstr = tmp;
10565 
10566    if (portstr) {
10567       port = atoi(portstr);
10568       if (port < 1)
10569          port = IAX_DEFAULT_PORTNO;
10570    }
10571    
10572    if (!ast_get_ip(&sin, addr)) {
10573       struct ast_netsock *sock;
10574       int res;
10575 
10576       sin.sin_port = 0;
10577       sin.sin_family = AF_INET;
10578       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10579       if (res == 0) {
10580          /* ip address valid. */
10581          sin.sin_port = htons(port);
10582          if (!(sock = ast_netsock_find(netsock, &sin)))
10583             sock = ast_netsock_find(outsock, &sin);
10584          if (sock) {
10585             sockfd = ast_netsock_sockfd(sock);
10586             nonlocal = 0;
10587          } else {
10588             unsigned int orig_saddr = sin.sin_addr.s_addr;
10589             /* INADDR_ANY matches anyway! */
10590             sin.sin_addr.s_addr = INADDR_ANY;
10591             if (ast_netsock_find(netsock, &sin)) {
10592                sin.sin_addr.s_addr = orig_saddr;
10593                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
10594                if (sock) {
10595                   sockfd = ast_netsock_sockfd(sock);
10596                   ast_netsock_unref(sock);
10597                   nonlocal = 0;
10598                } else {
10599                   nonlocal = 2;
10600                }
10601             }
10602          }
10603       }
10604    }
10605       
10606    peer->sockfd = sockfd;
10607 
10608    if (nonlocal == 1) {
10609       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10610          srcaddr, peer->name);
10611       return -1;
10612         } else if (nonlocal == 2) {
10613       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10614          srcaddr, peer->name);
10615          return -1;
10616    } else {
10617       if (option_debug)
10618          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10619       return 0;
10620    }
10621 }

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

peer_status: Report Peer status in character string

Definition at line 3166 of file chan_iax2.c.

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

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

03167 {
03168    int res = 0;
03169    if (peer->maxms) {
03170       if (peer->lastms < 0) {
03171          ast_copy_string(status, "UNREACHABLE", statuslen);
03172       } else if (peer->lastms > peer->maxms) {
03173          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03174          res = 1;
03175       } else if (peer->lastms) {
03176          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03177          res = 1;
03178       } else {
03179          ast_copy_string(status, "UNKNOWN", statuslen);
03180       }
03181    } else { 
03182       ast_copy_string(status, "Unmonitored", statuslen);
03183       res = -1;
03184    }
03185    return res;
03186 }

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

Definition at line 1283 of file chan_iax2.c.

References ao2_ref().

Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().

01284 {
01285    ao2_ref(peer, -1);
01286    return NULL;
01287 }

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

Definition at line 1901 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

01902 {
01903    struct peercnt *peercnt;
01904    unsigned long addr = sin->sin_addr.s_addr;
01905    int res = 0;
01906    struct peercnt tmp = {
01907       .addr = addr,
01908    };
01909 
01910    /* Reasoning for peercnts container lock:  Two identical ip addresses
01911     * could be added by different threads at the "same time". Without the container
01912     * lock, both threads could alloc space for the same object and attempt
01913     * to link to table.  With the lock, one would create the object and link
01914     * to table while the other would find the already created peercnt object
01915     * rather than creating a new one. */
01916    ao2_lock(peercnts);
01917    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01918       ao2_lock(peercnt);
01919    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
01920       ao2_lock(peercnt);
01921       /* create and set defaults */
01922       peercnt->addr = addr;
01923       set_peercnt_limit(peercnt);
01924       /* guarantees it does not go away after unlocking table
01925        * ao2_find automatically adds this */
01926       ao2_link(peercnts, peercnt);
01927    } else {
01928       ao2_unlock(peercnts);
01929       return -1;
01930    }
01931 
01932    /* check to see if the address has hit its callno limit.  If not increment cur. */
01933    if (peercnt->limit > peercnt->cur) {
01934       peercnt->cur++;
01935       if (option_debug) {
01936          ast_log(LOG_NOTICE, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
01937       }
01938    } else { /* max num call numbers for this peer has been reached! */
01939       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
01940       res = -1;
01941    }
01942 
01943    /* clean up locks and ref count */
01944    ao2_unlock(peercnt);
01945    ao2_unlock(peercnts);
01946    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
01947 
01948    return res;
01949 }

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

Definition at line 1739 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

01740 {
01741    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01742    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01743 }

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

Definition at line 1733 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

01734 {
01735    const struct peercnt *peercnt = obj;
01736    return abs((int) peercnt->addr);
01737 }

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

Definition at line 1871 of file chan_iax2.c.

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

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

01872 {
01873    /* this function turns off and on custom callno limits set by peer registration */
01874    struct peercnt *peercnt;
01875    struct peercnt tmp = {
01876       .addr = sin->sin_addr.s_addr,
01877    };
01878 
01879    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01880       peercnt->reg = reg;
01881       if (limit) {
01882          peercnt->limit = limit;
01883       } else {
01884          set_peercnt_limit(peercnt);
01885       }
01886       if (option_debug) {
01887          ast_log(LOG_NOTICE, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
01888       }
01889       ao2_ref(peercnt, -1); /* decrement ref from find */
01890    }
01891 }

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 1955 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

01956 {
01957    struct sockaddr_in sin = {
01958       .sin_addr.s_addr = peercnt->addr,
01959    };
01960 
01961    if (peercnt) {
01962       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
01963        * peercnt_add could try and grab this entry from the table and modify it at the
01964        * "same time" this thread attemps to unlink it.*/
01965       ao2_lock(peercnts);
01966       peercnt->cur--;
01967       if (option_debug) {
01968          ast_log(LOG_NOTICE, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
01969       }
01970       /* if this was the last connection from the peer remove it from table */
01971       if (peercnt->cur == 0) {
01972          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
01973       }
01974       ao2_unlock(peercnts);
01975    }
01976 }

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

Definition at line 1996 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

01997 {
01998    struct peercnt *peercnt;
01999    struct peercnt tmp = {
02000       .addr = sin->sin_addr.s_addr,
02001    };
02002 
02003    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02004       peercnt_remove(peercnt);
02005       ao2_ref(peercnt, -1); /* decrement ref from find */
02006    }
02007    return 0;
02008 }

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

Definition at line 1982 of file chan_iax2.c.

References ao2_ref(), and peercnt_remove().

Referenced by sched_delay_remove().

01983 {
01984    struct peercnt *peercnt = (struct peercnt *) obj;
01985 
01986    peercnt_remove(peercnt);
01987    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
01988 
01989    return 0;
01990 }

static void poke_all_peers ( void   )  [static]

Definition at line 11609 of file chan_iax2.c.

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

Referenced by reload_config().

11610 {
11611    struct ao2_iterator i;
11612    struct iax2_peer *peer;
11613 
11614    i = ao2_iterator_init(peers, 0);
11615    while ((peer = ao2_iterator_next(&i))) {
11616       iax2_poke_peer(peer, 0);
11617       peer_unref(peer);
11618    }
11619 }

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

Definition at line 1860 of file chan_iax2.c.

References addr_range::delme.

Referenced by reload_config().

01861 {
01862    struct addr_range *addr_range = obj;
01863 
01864    return addr_range->delme ? CMP_MATCH : 0;
01865 }

static void prune_peers ( void   )  [static]

Definition at line 11187 of file chan_iax2.c.

References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().

11188 {
11189    struct iax2_peer *peer;
11190    struct ao2_iterator i;
11191 
11192    i = ao2_iterator_init(peers, 0);
11193    while ((peer = ao2_iterator_next(&i))) {
11194       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11195          unlink_peer(peer);
11196       }
11197       peer_unref(peer);
11198    }
11199 }

static void prune_users ( void   )  [static]

Definition at line 11172 of file chan_iax2.c.

References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().

Referenced by iax2_prune_realtime(), and reload_config().

11173 {
11174    struct iax2_user *user;
11175    struct ao2_iterator i;
11176 
11177    i = ao2_iterator_init(users, 0);
11178    while ((user = ao2_iterator_next(&i))) {
11179       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11180          ao2_unlink(users, user);
11181       }
11182       user_unref(user);
11183    }
11184 }

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

Definition at line 12491 of file chan_iax2.c.

References chan_iax2_pvt::frames_received, and match().

Referenced by load_objects().

12492 {
12493    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12494 
12495    /* The frames_received field is used to hold whether we're matching
12496     * against a full frame or not ... */
12497 
12498    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
12499       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12500 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1510 of file chan_iax2.c.

References chan_iax2_pvt::addr, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, chan_iax2_pvt::callno_entry, jb_frame::data, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax_frame::list, chan_iax2_pvt::owner, ast_iax2_queue::queue, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), and chan_iax2_pvt::vars.

Referenced by new_iax().

01511 {
01512    struct chan_iax2_pvt *pvt = obj;
01513    struct iax_frame *cur = NULL;
01514 
01515    iax2_destroy_helper(pvt);
01516    sched_delay_remove(&pvt->addr, pvt->callno_entry);
01517    pvt->callno_entry = NULL;
01518 
01519    /* Already gone */
01520    ast_set_flag(pvt, IAX_ALREADYGONE); 
01521 
01522    AST_LIST_LOCK(&iaxq.queue);
01523    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01524       /* Cancel any pending transmissions */
01525       if (cur->callno == pvt->callno) { 
01526          cur->retries = -1;
01527       }
01528    }
01529    AST_LIST_UNLOCK(&iaxq.queue);
01530 
01531    if (pvt->reg) {
01532       pvt->reg->callno = 0;
01533    }
01534 
01535    if (!pvt->owner) {
01536       jb_frame frame;
01537       if (pvt->vars) {
01538           ast_variables_destroy(pvt->vars);
01539           pvt->vars = NULL;
01540       }
01541 
01542       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01543          iax2_frame_free(frame.data);
01544       }
01545 
01546       jb_destroy(pvt->jb);
01547       ast_string_field_free_memory(pvt);
01548    }
01549 }

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

Definition at line 12484 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

12485 {
12486    const struct chan_iax2_pvt *pvt = obj;
12487 
12488    return pvt->peercallno;
12489 }

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

Definition at line 6518 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, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by socket_process().

06519 {
06520    struct ast_iax2_full_hdr fh;
06521    fh.scallno = htons(src | IAX_FLAG_FULL);
06522    fh.dcallno = htons(dst);
06523    fh.ts = 0;
06524    fh.oseqno = 0;
06525    fh.iseqno = 0;
06526    fh.type = AST_FRAME_IAX;
06527    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06528    if (iaxdebug)
06529        iax_showframe(NULL, &fh, 0, sin, 0);
06530    if (option_debug)
06531       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06532          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06533    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06534 }

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

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

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 3652 of file chan_iax2.c.

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

03653 {
03654    struct ast_variable *var = NULL;
03655    struct ast_variable *tmp;
03656    struct iax2_peer *peer=NULL;
03657    time_t regseconds = 0, nowtime;
03658    int dynamic=0;
03659 
03660    if (peername) {
03661       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
03662       if (!var && sin)
03663          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03664    } else if (sin) {
03665       char porta[25];
03666       sprintf(porta, "%d", ntohs(sin->sin_port));
03667       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03668       if (var) {
03669          /* We'll need the peer name in order to build the structure! */
03670          for (tmp = var; tmp; tmp = tmp->next) {
03671             if (!strcasecmp(tmp->name, "name"))
03672                peername = tmp->value;
03673          }
03674       }
03675    }
03676    if (!var && peername) { /* Last ditch effort */
03677       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
03678       /*!\note
03679        * If this one loaded something, then we need to ensure that the host
03680        * field matched.  The only reason why we can't have this as a criteria
03681        * is because we only have the IP address and the host field might be
03682        * set as a name (and the reverse PTR might not match).
03683        */
03684       if (var && sin) {
03685          for (tmp = var; tmp; tmp = tmp->next) {
03686             if (!strcasecmp(tmp->name, "host")) {
03687                struct ast_hostent ahp;
03688                struct hostent *hp;
03689                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03690                   /* No match */
03691                   ast_variables_destroy(var);
03692                   var = NULL;
03693                }
03694                break;
03695             }
03696          }
03697       }
03698    }
03699    if (!var)
03700       return NULL;
03701 
03702    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03703    
03704    if (!peer) {
03705       ast_variables_destroy(var);
03706       return NULL;
03707    }
03708 
03709    for (tmp = var; tmp; tmp = tmp->next) {
03710       /* Make sure it's not a user only... */
03711       if (!strcasecmp(tmp->name, "type")) {
03712          if (strcasecmp(tmp->value, "friend") &&
03713              strcasecmp(tmp->value, "peer")) {
03714             /* Whoops, we weren't supposed to exist! */
03715             peer = peer_unref(peer);
03716             break;
03717          } 
03718       } else if (!strcasecmp(tmp->name, "regseconds")) {
03719          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
03720       } else if (!strcasecmp(tmp->name, "ipaddr")) {
03721          inet_aton(tmp->value, &(peer->addr.sin_addr));
03722       } else if (!strcasecmp(tmp->name, "port")) {
03723          peer->addr.sin_port = htons(atoi(tmp->value));
03724       } else if (!strcasecmp(tmp->name, "host")) {
03725          if (!strcasecmp(tmp->value, "dynamic"))
03726             dynamic = 1;
03727       }
03728    }
03729 
03730    ast_variables_destroy(var);
03731 
03732    if (!peer)
03733       return NULL;
03734 
03735    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03736       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03737       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03738          if (peer->expire > -1) {
03739             if (!ast_sched_del(sched, peer->expire)) {
03740                peer->expire = -1;
03741                peer_unref(peer);
03742             }
03743          }
03744          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03745          if (peer->expire == -1)
03746             peer_unref(peer);
03747       }
03748       ao2_link(peers, peer);
03749       if (ast_test_flag(peer, IAX_DYNAMIC))
03750          reg_source_db(peer);
03751    } else {
03752       ast_set_flag(peer, IAX_TEMPONLY);   
03753    }
03754 
03755    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03756       time(&nowtime);
03757       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03758          memset(&peer->addr, 0, sizeof(peer->addr));
03759          realtime_update_peer(peer->name, &peer->addr, 0);
03760          if (option_debug)
03761             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03762                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03763       }
03764       else {
03765          if (option_debug)
03766             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03767                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03768       }
03769    }
03770 
03771    return peer;
03772 }

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

Definition at line 3845 of file chan_iax2.c.

References ast_inet_ntoa(), and ast_update_realtime().

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

03846 {
03847    char port[10];
03848    char regseconds[20];
03849    
03850    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03851    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03852    ast_update_realtime("iaxpeers", "name", peername, 
03853       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03854       "regseconds", regseconds, NULL);
03855 }

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

Definition at line 3774 of file chan_iax2.c.

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

03775 {
03776    struct ast_variable *var;
03777    struct ast_variable *tmp;
03778    struct iax2_user *user=NULL;
03779 
03780    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03781    if (!var)
03782       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03783    if (!var && sin) {
03784       char porta[6];
03785       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03786       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03787       if (!var)
03788          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03789    }
03790    if (!var) { /* Last ditch effort */
03791       var = ast_load_realtime("iaxusers", "name", username, NULL);
03792       /*!\note
03793        * If this one loaded something, then we need to ensure that the host
03794        * field matched.  The only reason why we can't have this as a criteria
03795        * is because we only have the IP address and the host field might be
03796        * set as a name (and the reverse PTR might not match).
03797        */
03798       if (var) {
03799          for (tmp = var; tmp; tmp = tmp->next) {
03800             if (!strcasecmp(tmp->name, "host")) {
03801                struct ast_hostent ahp;
03802                struct hostent *hp;
03803                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03804                   /* No match */
03805                   ast_variables_destroy(var);
03806                   var = NULL;
03807                }
03808                break;
03809             }
03810          }
03811       }
03812    }
03813    if (!var)
03814       return NULL;
03815 
03816    tmp = var;
03817    while(tmp) {
03818       /* Make sure it's not a peer only... */
03819       if (!strcasecmp(tmp->name, "type")) {
03820          if (strcasecmp(tmp->value, "friend") &&
03821              strcasecmp(tmp->value, "user")) {
03822             return NULL;
03823          } 
03824       }
03825       tmp = tmp->next;
03826    }
03827 
03828    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03829 
03830    ast_variables_destroy(var);
03831 
03832    if (!user)
03833       return NULL;
03834 
03835    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03836       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03837       ao2_link(users, user);
03838    } else {
03839       ast_set_flag(user, IAX_TEMPONLY);   
03840    }
03841 
03842    return user;
03843 }

static void reg_source_db ( struct iax2_peer p  )  [static]

Definition at line 7340 of file chan_iax2.c.

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

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

07341 {
07342    char data[80];
07343    struct in_addr in;
07344    char *c, *d;
07345    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07346       c = strchr(data, ':');
07347       if (c) {
07348          *c = '\0';
07349          c++;
07350          if (inet_aton(data, &in)) {
07351             d = strchr(c, ':');
07352             if (d) {
07353                *d = '\0';
07354                d++;
07355                if (option_verbose > 2)
07356                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
07357                   ast_inet_ntoa(in), atoi(c), atoi(d));
07358                iax2_poke_peer(p, 0);
07359                p->expiry = atoi(d);
07360                memset(&p->addr, 0, sizeof(p->addr));
07361                p->addr.sin_family = AF_INET;
07362                p->addr.sin_addr = in;
07363                p->addr.sin_port = htons(atoi(c));
07364                if (p->expire > -1) {
07365                   if (!ast_sched_del(sched, p->expire)) {
07366                      p->expire = -1;
07367                      peer_unref(p);
07368                   }
07369                }
07370                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07371                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07372                if (p->expire == -1)
07373                   peer_unref(p);
07374                if (iax2_regfunk)
07375                   iax2_regfunk(p->name, 1);
07376                register_peer_exten(p, 1);
07377             }              
07378                
07379          }
07380       }
07381    }
07382 }

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

Definition at line 7258 of file chan_iax2.c.

References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, and S_OR.

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

07259 {
07260    char multi[256];
07261    char *stringp, *ext;
07262    if (!ast_strlen_zero(regcontext)) {
07263       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07264       stringp = multi;
07265       while((ext = strsep(&stringp, "&"))) {
07266          if (onoff) {
07267             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07268                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07269                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07270          } else
07271             ast_context_remove_extension(regcontext, ext, 1, NULL);
07272       }
07273    }
07274 }

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

Verify inbound registration.

Definition at line 6685 of file chan_iax2.c.

References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, ies, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax2_peer::secret, and secret.

Referenced by handle_request_register(), and socket_process().

06686 {
06687    char requeststr[256] = "";
06688    char peer[256] = "";
06689    char md5secret[256] = "";
06690    char rsasecret[256] = "";
06691    char secret[256] = "";
06692    struct iax2_peer *p = NULL;
06693    struct ast_key *key;
06694    char *keyn;
06695    int x;
06696    int expire = 0;
06697    int res = -1;
06698 
06699    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06700    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
06701    if (ies->username)
06702       ast_copy_string(peer, ies->username, sizeof(peer));
06703    if (ies->password)
06704       ast_copy_string(secret, ies->password, sizeof(secret));
06705    if (ies->md5_result)
06706       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06707    if (ies->rsa_result)
06708       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06709    if (ies->refresh)
06710       expire = ies->refresh;
06711 
06712    if (ast_strlen_zero(peer)) {
06713       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06714       return -1;
06715    }
06716 
06717    /* SLD: first call to lookup peer during registration */
06718    ast_mutex_unlock(&iaxsl[callno]);
06719    p = find_peer(peer, 1);
06720    ast_mutex_lock(&iaxsl[callno]);
06721    if (!p || !iaxs[callno]) {
06722       if (iaxs[callno]) {
06723          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06724 
06725          ast_string_field_set(iaxs[callno], secret, "badsecret");
06726 
06727          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
06728           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
06729           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
06730           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
06731           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
06732           *
06733           * If none of these cases exist, res will be returned as 0 without authentication indicating
06734           * an AUTHREQ needs to be sent out. */
06735 
06736          if (ast_strlen_zero(iaxs[callno]->challenge) &&
06737             !(!ast_strlen_zero(secret) && plaintext)) {
06738             /* by setting res to 0, an REGAUTH will be sent */
06739             res = 0;
06740          }
06741       }
06742       if (authdebug && !p)
06743          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06744 
06745       goto return_unref;
06746    }
06747 
06748    if (!ast_test_flag(p, IAX_DYNAMIC)) {
06749       if (authdebug)
06750          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06751       goto return_unref;
06752    }
06753 
06754    if (!ast_apply_ha(p->ha, sin)) {
06755       if (authdebug)
06756          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06757       goto return_unref;
06758    }
06759    ast_string_field_set(iaxs[callno], secret, p->secret);
06760    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06761    /* Check secret against what we have on file */
06762    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06763       if (!ast_strlen_zero(p->inkeys)) {
06764          char tmpkeys[256];
06765          char *stringp=NULL;
06766          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06767          stringp=tmpkeys;
06768          keyn = strsep(&stringp, ":");
06769          while(keyn) {
06770             key = ast_key_get(keyn, AST_KEY_PUBLIC);
06771             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06772                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06773                break;
06774             } else if (!key)
06775                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06776             keyn = strsep(&stringp, ":");
06777          }
06778          if (!keyn) {
06779             if (authdebug)
06780                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06781             goto return_unref;
06782          }
06783       } else {
06784          if (authdebug)
06785             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06786          goto return_unref;
06787       }
06788    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06789       struct MD5Context md5;
06790       unsigned char digest[16];
06791       char *tmppw, *stringp;
06792 
06793       tmppw = ast_strdupa(p->secret);
06794       stringp = tmppw;
06795       while((tmppw = strsep(&stringp, ";"))) {
06796          MD5Init(&md5);
06797          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06798          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06799          MD5Final(digest, &md5);
06800          for (x=0;x<16;x++)
06801             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06802          if (!strcasecmp(requeststr, md5secret))
06803             break;
06804       }
06805       if (tmppw) {
06806          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06807       } else {
06808          if (authdebug)
06809             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06810          goto return_unref;
06811       }
06812    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06813       /* They've provided a plain text password and we support that */
06814       if (strcmp(secret, p->secret)) {
06815          if (authdebug)
06816             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06817          goto return_unref;
06818       } else
06819          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06820    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06821       /* if challenge has been sent, but no challenge response if given, reject. */
06822       goto return_unref;
06823    }
06824    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06825 
06826    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
06827    res = 0;
06828 return_unref:
06829 
06830    if (iaxs[callno]) {
06831       ast_string_field_set(iaxs[callno], peer, peer);
06832 
06833       /* Choose lowest expiry number */
06834       if (expire && (expire < iaxs[callno]->expiry)) {
06835          iaxs[callno]->expiry = expire;
06836       }
06837    }
06838 
06839    if (p) {
06840       peer_unref(p);
06841    }
06842    return res;
06843 }

static int registry_authrequest ( int  callno  )  [static]

Definition at line 7529 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, peer_unref(), and send_command().

Referenced by socket_process().

07530 {
07531    struct iax_ie_data ied;
07532    struct iax2_peer *p;
07533    char challenge[10];
07534    const char *peer_name;
07535    int sentauthmethod;
07536 
07537    peer_name = ast_strdupa(iaxs[callno]->peer);
07538 
07539    /* SLD: third call to find_peer in registration */
07540    ast_mutex_unlock(&iaxsl[callno]);
07541    if ((p = find_peer(peer_name, 1))) {
07542       last_authmethod = p->authmethods;
07543    }
07544 
07545    ast_mutex_lock(&iaxsl[callno]);
07546    if (!iaxs[callno])
07547       goto return_unref;
07548 
07549    memset(&ied, 0, sizeof(ied));
07550    /* The selection of which delayed reject is sent may leak information,
07551     * if it sets a static response.  For example, if a host is known to only
07552     * use MD5 authentication, then an RSA response would indicate that the
07553     * peer does not exist, and vice-versa.
07554     * Therefore, we use whatever the last peer used (which may vary over the
07555     * course of a server, which should leak minimal information). */
07556    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07557    if (!p) {
07558       iaxs[callno]->authmethods = sentauthmethod;
07559    }
07560    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07561    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07562       /* Build the challenge */
07563       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07564       ast_string_field_set(iaxs[callno], challenge, challenge);
07565       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07566    }
07567    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07568 
07569 return_unref:
07570    if (p) {
07571       peer_unref(p);
07572    }
07573 
07574    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07575 }

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

Definition at line 7577 of file chan_iax2.c.

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

Referenced by socket_process().

07578 {
07579    struct iax2_registry *reg;
07580    /* Start pessimistic */
07581    struct iax_ie_data ied;
07582    char peer[256] = "";
07583    char challenge[256] = "";
07584    int res;
07585    int authmethods = 0;
07586    if (ies->authmethods)
07587       authmethods = ies->authmethods;
07588    if (ies->username)
07589       ast_copy_string(peer, ies->username, sizeof(peer));
07590    if (ies->challenge)
07591       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07592    memset(&ied, 0, sizeof(ied));
07593    reg = iaxs[callno]->reg;
07594    if (reg) {
07595          if (inaddrcmp(&reg->addr, sin)) {
07596             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07597             return -1;
07598          }
07599          if (ast_strlen_zero(reg->secret)) {
07600             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07601             reg->regstate = REG_STATE_NOAUTH;
07602             return -1;
07603          }
07604          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07605          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07606          if (reg->secret[0] == '[') {
07607             char tmpkey[256];
07608             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07609             tmpkey[strlen(tmpkey) - 1] = '\0';
07610             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07611          } else
07612             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07613          if (!res) {
07614             reg->regstate = REG_STATE_AUTHSENT;
07615             add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
07616             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07617          } else
07618             return -1;
07619          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07620    } else   
07621       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07622    return -1;
07623 }

static char* regstate2str ( int  regstate  )  [static]

Definition at line 5938 of file chan_iax2.c.

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

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

05939 {
05940    switch(regstate) {
05941    case REG_STATE_UNREGISTERED:
05942       return "Unregistered";
05943    case REG_STATE_REGSENT:
05944       return "Request Sent";
05945    case REG_STATE_AUTHSENT:
05946       return "Auth. Sent";
05947    case REG_STATE_REGISTERED:
05948       return "Registered";
05949    case REG_STATE_REJECTED:
05950       return "Rejected";
05951    case REG_STATE_TIMEOUT:
05952       return "Timeout";
05953    case REG_STATE_NOAUTH:
05954       return "No Authentication";
05955    default:
05956       return "Unknown";
05957    }
05958 }

static int reload ( void   )  [static]

Definition at line 11649 of file chan_iax2.c.

References reload_config().

11650 {
11651    return reload_config();
11652 }

static int reload_config ( void   )  [static]

Definition at line 11620 of file chan_iax2.c.

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

11621 {
11622    static const char config[] = "iax.conf";
11623    struct iax2_registry *reg;
11624 
11625    if (set_config(config, 1) > 0) {
11626       prune_peers();
11627       prune_users();
11628       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
11629       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
11630       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
11631       AST_LIST_LOCK(&registrations);
11632       AST_LIST_TRAVERSE(&registrations, reg, entry)
11633          iax2_do_register(reg);
11634       AST_LIST_UNLOCK(&registrations);
11635       /* Qualify hosts, too */
11636       poke_all_peers();
11637    }
11638    reload_firmware(0);
11639    iax_provision_reload();
11640 
11641    return 0;
11642 }

static void reload_firmware ( int  unload  )  [static]

Definition at line 2778 of file chan_iax2.c.

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

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

02779 {
02780    struct iax_firmware *cur, *curl, *curp;
02781    DIR *fwd;
02782    struct dirent *de;
02783    char dir[256];
02784    char fn[256];
02785    /* Mark all as dead */
02786    ast_mutex_lock(&waresl.lock);
02787    cur = waresl.wares;
02788    while(cur) {
02789       cur->dead = 1;
02790       cur = cur->next;
02791    }
02792 
02793    /* Now that we've freed them, load the new ones */
02794    if (!unload) {
02795       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02796       fwd = opendir(dir);
02797       if (fwd) {
02798          while((de = readdir(fwd))) {
02799             if (de->d_name[0] != '.') {
02800                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02801                if (!try_firmware(fn)) {
02802                   if (option_verbose > 1)
02803                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02804                }
02805             }
02806          }
02807          closedir(fwd);
02808       } else 
02809          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02810    }
02811 
02812    /* Clean up leftovers */
02813    cur = waresl.wares;
02814    curp = NULL;
02815    while(cur) {
02816       curl = cur;
02817       cur = cur->next;
02818       if (curl->dead) {
02819          if (curp) {
02820             curp->next = cur;
02821          } else {
02822             waresl.wares = cur;
02823          }
02824          destroy_firmware(curl);
02825       } else {
02826          curp = cur;
02827       }
02828    }
02829    ast_mutex_unlock(&waresl.lock);
02830 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1396 of file chan_iax2.c.

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

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

01397 {
01398    if (!pvt->peercallno) {
01399       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01400       return;
01401    }
01402 
01403    ao2_unlink(iax_peercallno_pvts, pvt);
01404 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1377 of file chan_iax2.c.

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

Referenced by complete_transfer(), and iax2_destroy().

01378 {
01379    if (!pvt->transfercallno) {
01380       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01381       return;
01382    }
01383 
01384    ao2_unlink(iax_transfercallno_pvts, pvt);
01385 }

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

Definition at line 2175 of file chan_iax2.c.

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

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

02176 {
02177    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02178 
02179    /* the callno_pool container is locked here primarily to ensure thread
02180     * safety of the total_nonval_callno_used check and decrement */
02181    ao2_lock(callno_pool);
02182 
02183    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02184       total_nonval_callno_used--;
02185    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02186       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02187    }
02188 
02189    if (callno_entry->callno < TRUNK_CALL_START) {
02190       ao2_link(callno_pool, callno_entry);
02191    } else {
02192       ao2_link(callno_pool_trunk, callno_entry);
02193    }
02194    ao2_ref(callno_entry, -1); /* only container ref remains */
02195 
02196    ao2_unlock(callno_pool);
02197    return 0;
02198 }

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

Definition at line 4143 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, peer_unref(), and user_unref().

Referenced by handle_call_token().

04144 {
04145    struct iax2_user *user = NULL;
04146    struct iax2_peer *peer = NULL;
04147 
04148    if (ast_strlen_zero(name)) {
04149       return; /* no username given */
04150    }
04151 
04152    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04153       user->calltoken_required = CALLTOKEN_YES;
04154    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04155       peer->calltoken_required = CALLTOKEN_YES;
04156    }
04157 
04158    if (peer) {
04159       peer_unref(peer);
04160    }
04161    if (user) {
04162       user_unref(user);
04163    }
04164 }

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

Definition at line 4059 of file chan_iax2.c.

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

Referenced by socket_process().

04060 {
04061    struct chan_iax2_pvt *pvt = iaxs[callno];
04062    int frametype = f->af.frametype;
04063    int subclass = f->af.subclass;
04064    struct {
04065       struct ast_iax2_full_hdr fh;
04066       struct iax_ie_data ied;
04067    } data = {
04068       .ied.buf = { 0 },
04069       .ied.pos = 0,
04070    };
04071    /* total len - header len gives us the frame's IE len */
04072    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04073 
04074    if (!pvt) {
04075       return;  /* this should not be possible if called from socket_process() */
04076    }
04077 
04078    /* 
04079     * Check to make sure last frame sent is valid for call token resend
04080     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04081     * 2. Frame should _NOT_ already have a destination callno
04082     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04083     * 4. Pvt must have a calltoken_ie_len which represents the number of
04084     *    bytes at the end of the frame used for the previous calltoken ie.
04085     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04086     * 6. Total length of f->data must be _LESS_ than size of our data struct
04087     *    because f->data must be able to fit within data. 
04088     */
04089    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04090       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04091       (f->datalen > sizeof(data))) {
04092 
04093       return;  /* ignore resend, token was not valid for the dialog */
04094    }
04095 
04096    /* token is valid
04097     * 1. Copy frame data over
04098     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04099     *    NOTE: Having the ie always be last is not protocol specified,
04100     *    it is only an implementation choice.  Since we only expect the ie to
04101     *    be last for frames we have sent, this can no way be affected by
04102     *    another end point.
04103     * 3. Remove frame from queue
04104     * 4. Free old frame
04105     * 5. Clear previous seqnos
04106     * 6. Resend with CALLTOKEN ie.
04107     */
04108 
04109    /* ---1.--- */
04110    memcpy(&data, f->data, f->datalen);
04111    data.ied.pos = ie_data_pos;
04112 
04113    /* ---2.--- */
04114    /* move to the beginning of the calltoken ie so we can write over it */
04115    data.ied.pos -= pvt->calltoken_ie_len;
04116    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04117 
04118    /* make sure to update token length incase it ever has to be stripped off again */
04119    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04120 
04121    /* ---3.--- */
04122    AST_LIST_LOCK(&iaxq.queue);
04123    AST_LIST_REMOVE(&iaxq.queue, f, list);
04124    AST_LIST_UNLOCK(&iaxq.queue);
04125 
04126    /* ---4.--- */
04127    iax2_frame_free(f);
04128 
04129    /* ---5.--- */
04130    pvt->oseqno = 0;
04131    pvt->rseqno = 0;
04132    pvt->iseqno = 0;
04133    pvt->aseqno = 0;
04134    if (pvt->peercallno) {
04135       remove_by_peercallno(pvt);
04136       pvt->peercallno = 0;
04137    }
04138 
04139    /* ---6.--- */
04140    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04141 }

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

Definition at line 8082 of file chan_iax2.c.

References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, ies, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.

Referenced by socket_process().

08083 {
08084    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08085    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08086    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08087    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08088    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08089    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08090    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08091 }

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

Definition at line 2247 of file chan_iax2.c.

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

Referenced by pvt_destructor().

02248 {
02249    int i;
02250    struct peercnt *peercnt;
02251    struct peercnt tmp = {
02252       .addr = sin->sin_addr.s_addr,
02253    };
02254 
02255    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02256       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02257       if (option_debug) {
02258          ast_log(LOG_NOTICE, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02259       }
02260       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02261       if (i == -1) {
02262          ao2_ref(peercnt, -1);
02263       }
02264    }
02265 
02266    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02267 }

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

Definition at line 10365 of file chan_iax2.c.

References ast_cond_timedwait(), ast_cond_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), option_debug, sched, and sched_lock.

Referenced by start_network_thread().

10366 {
10367    for (;;) {
10368       int ms, count;
10369       struct timespec ts;
10370 
10371       pthread_testcancel();
10372 
10373       ast_mutex_lock(&sched_lock);
10374 
10375       ms = ast_sched_wait(sched);
10376 
10377       if (ms == -1) {
10378          ast_cond_wait(&sched_cond, &sched_lock);
10379       } else {
10380          struct timeval tv;
10381          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000));
10382          ts.tv_sec = tv.tv_sec;
10383          ts.tv_nsec = tv.tv_usec * 1000;
10384          ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10385       }
10386 
10387       ast_mutex_unlock(&sched_lock);
10388 
10389       pthread_testcancel();
10390 
10391       count = ast_sched_runq(sched);
10392       if (option_debug && count >= 20) {
10393          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10394       }
10395    }
10396 
10397    return NULL;
10398 }

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

Note:
This function assumes fr->callno is locked

IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.

Definition at line 3505 of file chan_iax2.c.

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, LOG_DEBUG, option_debug, ast_channel_tech::properties, sched, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().

Referenced by socket_process().

03506 {
03507    int type, len;
03508    int ret;
03509    int needfree = 0;
03510    struct ast_channel *owner = NULL;
03511    struct ast_channel *bridge = NULL;
03512    
03513    /* Attempt to recover wrapped timestamps */
03514    unwrap_timestamp(fr);
03515 
03516    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
03517    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03518       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03519    else {
03520 #if 0
03521       if (option_debug)
03522          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03523 #endif
03524       fr->af.delivery = ast_tv(0,0);
03525    }
03526 
03527    type = JB_TYPE_CONTROL;
03528    len = 0;
03529 
03530    if(fr->af.frametype == AST_FRAME_VOICE) {
03531       type = JB_TYPE_VOICE;
03532       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03533    } else if(fr->af.frametype == AST_FRAME_CNG) {
03534       type = JB_TYPE_SILENCE;
03535    }
03536 
03537    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03538       if (tsout)
03539          *tsout = fr->ts;
03540       __do_deliver(fr);
03541       return -1;
03542    }
03543 
03544    if ((owner = iaxs[fr->callno]->owner))
03545       bridge = ast_bridged_channel(owner);
03546 
03547    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
03548     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
03549    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03550       jb_frame frame;
03551 
03552       /* deliver any frames in the jb */
03553       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03554          __do_deliver(frame.data);
03555          /* __do_deliver() can make the call disappear */
03556          if (!iaxs[fr->callno])
03557             return -1;
03558       }
03559 
03560       jb_reset(iaxs[fr->callno]->jb);
03561 
03562       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03563 
03564       /* deliver this frame now */
03565       if (tsout)
03566          *tsout = fr->ts;
03567       __do_deliver(fr);
03568       return -1;
03569    }
03570 
03571    /* insert into jitterbuffer */
03572    /* TODO: Perhaps we could act immediately if it's not droppable and late */
03573    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03574          calc_rxstamp(iaxs[fr->callno],fr->ts));
03575    if (ret == JB_DROP) {
03576       needfree++;
03577    } else if (ret == JB_SCHED) {
03578       update_jbsched(iaxs[fr->callno]);
03579    }
03580    if (tsout)
03581       *tsout = fr->ts;
03582    if (needfree) {
03583       /* Free our iax frame */
03584       iax2_frame_free(fr);
03585       return -1;
03586    }
03587    return 0;
03588 }

static int scheduled_destroy ( const void *  vid  )  [static]

Definition at line 1496 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_destroy(), iaxs, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.

Referenced by iax2_hangup().

01497 {
01498    short callno = PTR_TO_CALLNO(vid);
01499    ast_mutex_lock(&iaxsl[callno]);
01500    if (iaxs[callno]) {
01501       if (option_debug) {
01502          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01503       }
01504       iax2_destroy(callno);
01505    }
01506    ast_mutex_unlock(&iaxsl[callno]);
01507    return 0;
01508 }

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

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

Referenced by handle_call_token(), and socket_process().

04026 {
04027    struct {
04028       struct ast_iax2_full_hdr f;
04029       struct iax_ie_data ied;
04030    } data;
04031    size_t size = sizeof(struct ast_iax2_full_hdr);
04032 
04033    if (ied) {
04034       size += ied->pos;
04035       memcpy(&data.ied, ied->buf, ied->pos);
04036    }
04037 
04038    data.f.scallno = htons(0x8000 | callno);
04039    data.f.dcallno = htons(dcallno);
04040    data.f.ts = htonl(ts);
04041    data.f.iseqno = seqno;
04042    data.f.oseqno = 0;
04043    data.f.type = AST_FRAME_IAX;
04044    data.f.csub = compress_subclass(command);
04045 
04046    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04047 }

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

Definition at line 6246 of file chan_iax2.c.

References __send_command().

Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().

06247 {
06248    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06249 }

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

Note:
Since this function calls iax2_predestroy() -> iax2_queue_hangup(), the pvt struct for the given call number may disappear during its execution.

Definition at line 6265 of file chan_iax2.c.

References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.

Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().

06266 {
06267    int call_num = i->callno;
06268    /* It is assumed that the callno has already been locked */
06269    iax2_predestroy(i->callno);
06270    if (!iaxs[call_num])
06271       return -1;
06272    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
06273 }

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

Definition at line 6275 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

06276 {
06277    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
06278 }

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

Definition at line 6251 of file chan_iax2.c.

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

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

06252 {
06253    int res;
06254    ast_mutex_lock(&iaxsl[callno]);
06255    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06256    ast_mutex_unlock(&iaxsl[callno]);
06257    return res;
06258 }

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

Definition at line 6280 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

06281 {
06282    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
06283 }

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

Definition at line 1173 of file chan_iax2.c.

References __send_lagrq(), and schedule_action.

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

01174 {
01175 #ifdef SCHED_MULTITHREADED
01176    if (schedule_action(__send_lagrq, data))
01177 #endif      
01178       __send_lagrq(data);
01179    
01180    return 0;
01181 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 2903 of file chan_iax2.c.

References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), iax2_registry::callno, errno, f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.

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

02904 {
02905    int res;
02906    int callno = f->callno;
02907 
02908    /* Don't send if there was an error, but return error instead */
02909    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02910        return -1;
02911    
02912    /* Called with iaxsl held */
02913    if (option_debug > 2 && iaxdebug)
02914       ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
02915    if (f->transfer) {
02916       if (iaxdebug)
02917          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02918       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02919                sizeof(iaxs[callno]->transfer));
02920    } else {
02921       if (iaxdebug)
02922          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02923       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02924                sizeof(iaxs[callno]->addr));
02925    }
02926    if (res < 0) {
02927       if (option_debug && iaxdebug)
02928          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02929       handle_error();
02930    } else
02931       res = 0;
02932    return res;
02933 }

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

Definition at line 1128 of file chan_iax2.c.

References __send_ping(), and schedule_action.

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

01129 {
01130 #ifdef SCHED_MULTITHREADED
01131    if (schedule_action(__send_ping, data))
01132 #endif      
01133       __send_ping(data);
01134 
01135    return 0;
01136 }

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

Definition at line 7760 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, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, option_debug, 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().

07761 {
07762    int res = 0;
07763    struct iax_frame *fr;
07764    struct ast_iax2_meta_hdr *meta;
07765    struct ast_iax2_meta_trunk_hdr *mth;
07766    int calls = 0;
07767    
07768    /* Point to frame */
07769    fr = (struct iax_frame *)tpeer->trunkdata;
07770    /* Point to meta data */
07771    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07772    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07773    if (tpeer->trunkdatalen) {
07774       /* We're actually sending a frame, so fill the meta trunk header and meta header */
07775       meta->zeros = 0;
07776       meta->metacmd = IAX_META_TRUNK;
07777       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07778          meta->cmddata = IAX_META_TRUNK_MINI;
07779       else
07780          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07781       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07782       /* And the rest of the ast_iax2 header */
07783       fr->direction = DIRECTION_OUTGRESS;
07784       fr->retrans = -1;
07785       fr->transfer = 0;
07786       /* Any appropriate call will do */
07787       fr->data = fr->afdata;
07788       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07789       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07790       calls = tpeer->calls;
07791 #if 0
07792       if (option_debug)
07793          ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
07794 #endif      
07795       /* Reset transmit trunk side data */
07796       tpeer->trunkdatalen = 0;
07797       tpeer->calls = 0;
07798    }
07799    if (res < 0)
07800       return res;
07801    return calls;
07802 }

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

Load configuration.

Definition at line 11234 of file chan_iax2.c.

References __ao2_link(), add_calltoken_ignore(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_callno_limits(), build_peer(), build_user(), capability, DEFAULT_MAXCALLNO_LIMIT, DEFAULT_MAXCALLNO_LIMIT_NONVAL, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), global_maxcallno, global_maxcallno_nonval, globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, peer_unref(), portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), ast_variable::value, and VERBOSE_PREFIX_2.

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

11235 {
11236    struct ast_config *cfg, *ucfg;
11237    int capability=iax2_capability;
11238    struct ast_variable *v;
11239    char *cat;
11240    const char *utype;
11241    const char *tosval;
11242    int format;
11243    int portno = IAX_DEFAULT_PORTNO;
11244    int  x;
11245    struct iax2_user *user;
11246    struct iax2_peer *peer;
11247    struct ast_netsock *ns;
11248 #if 0
11249    static unsigned short int last_port=0;
11250 #endif
11251 
11252    cfg = ast_config_load(config_file);
11253    
11254    if (!cfg) {
11255       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11256       return -1;
11257    }
11258 
11259    if (reload) {
11260       set_config_destroy();
11261    }
11262 
11263    /* Reset global codec prefs */   
11264    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11265    
11266    /* Reset Global Flags */
11267    memset(&globalflags, 0, sizeof(globalflags));
11268    ast_set_flag(&globalflags, IAX_RTUPDATE);
11269 
11270 #ifdef SO_NO_CHECK
11271    nochecksums = 0;
11272 #endif
11273 
11274    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11275    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11276    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
11277    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
11278 
11279    maxauthreq = 3;
11280 
11281    v = ast_variable_browse(cfg, "general");
11282 
11283    /* Seed initial tos value */
11284    tosval = ast_variable_retrieve(cfg, "general", "tos");
11285    if (tosval) {
11286       if (ast_str2tos(tosval, &tos))
11287          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
11288    }
11289    while(v) {
11290       if (!strcasecmp(v->name, "bindport")){ 
11291          if (reload)
11292             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11293          else
11294             portno = atoi(v->value);
11295       } else if (!strcasecmp(v->name, "pingtime")) 
11296          ping_time = atoi(v->value);
11297       else if (!strcasecmp(v->name, "iaxthreadcount")) {
11298          if (reload) {
11299             if (atoi(v->value) != iaxthreadcount)
11300                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11301          } else {
11302             iaxthreadcount = atoi(v->value);
11303             if (iaxthreadcount < 1) {
11304                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11305                iaxthreadcount = 1;
11306             } else if (iaxthreadcount > 256) {
11307                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11308                iaxthreadcount = 256;
11309             }
11310          }
11311       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11312          if (reload) {
11313             AST_LIST_LOCK(&dynamic_list);
11314             iaxmaxthreadcount = atoi(v->value);
11315             AST_LIST_UNLOCK(&dynamic_list);
11316          } else {
11317             iaxmaxthreadcount = atoi(v->value);
11318             if (iaxmaxthreadcount < 0) {
11319                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11320                iaxmaxthreadcount = 0;
11321             } else if (iaxmaxthreadcount > 256) {
11322                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11323                iaxmaxthreadcount = 256;
11324             }
11325          }
11326       } else if (!strcasecmp(v->name, "nochecksums")) {
11327 #ifdef SO_NO_CHECK
11328          if (ast_true(v->value))
11329             nochecksums = 1;
11330          else
11331             nochecksums = 0;
11332 #else
11333          if (ast_true(v->value))
11334             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11335 #endif
11336       }
11337       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
11338          maxjitterbuffer = atoi(v->value);
11339       else if (!strcasecmp(v->name, "resyncthreshold")) 
11340          resyncthreshold = atoi(v->value);
11341       else if (!strcasecmp(v->name, "maxjitterinterps")) 
11342          maxjitterinterps = atoi(v->value);
11343       else if (!strcasecmp(v->name, "lagrqtime")) 
11344          lagrq_time = atoi(v->value);
11345       else if (!strcasecmp(v->name, "maxregexpire")) 
11346          max_reg_expire = atoi(v->value);
11347       else if (!strcasecmp(v->name, "minregexpire")) 
11348          min_reg_expire = atoi(v->value);
11349       else if (!strcasecmp(v->name, "bindaddr")) {
11350          if (reload) {
11351             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11352          } else {
11353             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
11354                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11355             } else {
11356                if (option_verbose > 1) {
11357                   if (strchr(v->value, ':'))
11358                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
11359                   else
11360                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
11361                }
11362                if (defaultsockfd < 0) 
11363                   defaultsockfd = ast_netsock_sockfd(ns);
11364                ast_netsock_unref(ns);
11365             }
11366          }
11367       } else if (!strcasecmp(v->name, "authdebug"))
11368          authdebug = ast_true(v->value);
11369       else if (!strcasecmp(v->name, "encryption"))
11370          iax2_encryption = get_encrypt_methods(v->value);
11371       else if (!strcasecmp(v->name, "notransfer")) {
11372          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
11373          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
11374          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
11375       } else if (!strcasecmp(v->name, "transfer")) {
11376          if (!strcasecmp(v->value, "mediaonly")) {
11377             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
11378          } else if (ast_true(v->value)) {
11379             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11380          } else 
11381             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11382       } else if (!strcasecmp(v->name, "codecpriority")) {
11383          if(!strcasecmp(v->value, "caller"))
11384             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11385          else if(!strcasecmp(v->value, "disabled"))
11386             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11387          else if(!strcasecmp(v->value, "reqonly")) {
11388             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11389             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11390          }
11391       } else if (!strcasecmp(v->name, "jitterbuffer"))
11392          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
11393       else if (!strcasecmp(v->name, "forcejitterbuffer"))
11394          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
11395       else if (!strcasecmp(v->name, "delayreject"))
11396          delayreject = ast_true(v->value);
11397       else if (!strcasecmp(v->name, "allowfwdownload"))
11398          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11399       else if (!strcasecmp(v->name, "rtcachefriends"))
11400          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
11401       else if (!strcasecmp(v->name, "rtignoreregexpire"))
11402          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
11403       else if (!strcasecmp(v->name, "rtupdate"))
11404          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11405       else if (!strcasecmp(v->name, "trunktimestamps"))
11406          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11407       else if (!strcasecmp(v->name, "rtautoclear")) {
11408          int i = atoi(v->value);
11409          if(i > 0)
11410             global_rtautoclear = i;
11411          else
11412             i = 0;
11413          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
11414       } else if (!strcasecmp(v->name, "trunkfreq")) {
11415          trunkfreq = atoi(v->value);
11416          if (trunkfreq < 10)
11417             trunkfreq = 10;
11418       } else if (!strcasecmp(v->name, "autokill")) {
11419          if (sscanf(v->value, "%30d", &x) == 1) {
11420             if (x >= 0)
11421                autokill = x;
11422             else
11423                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11424          } else if (ast_true(v->value)) {
11425             autokill = DEFAULT_MAXMS;
11426          } else {
11427             autokill = 0;
11428          }
11429       } else if (!strcasecmp(v->name, "bandwidth")) {
11430          if (!strcasecmp(v->value, "low")) {
11431             capability = IAX_CAPABILITY_LOWBANDWIDTH;
11432          } else if (!strcasecmp(v->value, "medium")) {
11433             capability = IAX_CAPABILITY_MEDBANDWIDTH;
11434          } else if (!strcasecmp(v->value, "high")) {
11435             capability = IAX_CAPABILITY_FULLBANDWIDTH;
11436          } else
11437             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11438       } else if (!strcasecmp(v->name, "allow")) {
11439          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11440       } else if (!strcasecmp(v->name, "disallow")) {
11441          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11442       } else if (!strcasecmp(v->name, "register")) {
11443          iax2_register(v->value, v->lineno);
11444       } else if (!strcasecmp(v->name, "iaxcompat")) {
11445          iaxcompat = ast_true(v->value);
11446       } else if (!strcasecmp(v->name, "regcontext")) {
11447          ast_copy_string(regcontext, v->value, sizeof(regcontext));
11448          /* Create context if it doesn't exist already */
11449          if (!ast_context_find(regcontext))
11450             ast_context_create(NULL, regcontext, "IAX2");
11451       } else if (!strcasecmp(v->name, "tos")) {
11452          if (ast_str2tos(v->value, &tos))
11453             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
11454       } else if (!strcasecmp(v->name, "accountcode")) {
11455          ast_copy_string(accountcode, v->value, sizeof(accountcode));
11456       } else if (!strcasecmp(v->name, "mohinterpret")) {
11457          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11458       } else if (!strcasecmp(v->name, "mohsuggest")) {
11459          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11460       } else if (!strcasecmp(v->name, "amaflags")) {
11461          format = ast_cdr_amaflags2int(v->value);
11462          if (format < 0) {
11463             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11464          } else {
11465             amaflags = format;
11466          }
11467       } else if (!strcasecmp(v->name, "language")) {
11468          ast_copy_string(language, v->value, sizeof(language));
11469       } else if (!strcasecmp(v->name, "maxauthreq")) {
11470          maxauthreq = atoi(v->value);
11471          if (maxauthreq < 0)
11472             maxauthreq = 0;
11473       } else if (!strcasecmp(v->name, "adsi")) {
11474          adsi = ast_true(v->value);
11475       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11476          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
11477             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
11478          }
11479       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
11480          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
11481             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);
11482          }
11483       } else if(!strcasecmp(v->name, "calltokenoptional")) {
11484          if (add_calltoken_ignore(v->value)) {
11485             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
11486          }
11487       }/*else if (strcasecmp(v->name,"type")) */
11488       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11489       v = v->next;
11490    }
11491    
11492    if (defaultsockfd < 0) {
11493       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
11494          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11495       } else {
11496          if (option_verbose > 1)
11497             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11498          defaultsockfd = ast_netsock_sockfd(ns);
11499          ast_netsock_unref(ns);
11500       }
11501    }
11502    if (reload) {
11503       ast_netsock_release(outsock);
11504       outsock = ast_netsock_list_alloc();
11505       if (!outsock) {
11506          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11507          return -1;
11508       }
11509       ast_netsock_init(outsock);
11510    }
11511 
11512    if (min_reg_expire > max_reg_expire) {
11513       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11514          min_reg_expire, max_reg_expire, max_reg_expire);
11515       min_reg_expire = max_reg_expire;
11516    }
11517    iax2_capability = capability;
11518    
11519    ucfg = ast_config_load("users.conf");
11520    if (ucfg) {
11521       struct ast_variable *gen;
11522       int genhasiax;
11523       int genregisteriax;
11524       const char *hasiax, *registeriax;
11525       
11526       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11527       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11528       gen = ast_variable_browse(ucfg, "general");
11529       cat = ast_category_browse(ucfg, NULL);
11530       while (cat) {
11531          if (strcasecmp(cat, "general")) {
11532             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11533             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11534             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11535                /* Start with general parameters, then specific parameters, user and peer */
11536                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11537                if (user) {
11538                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11539                   user = user_unref(user);
11540                }
11541                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11542                if (peer) {
11543                   if (ast_test_flag(peer, IAX_DYNAMIC))
11544                      reg_source_db(peer);
11545                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11546                   peer = peer_unref(peer);
11547                }
11548             }
11549             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11550                char tmp[256];
11551                const char *host = ast_variable_retrieve(ucfg, cat, "host");
11552                const char *username = ast_variable_retrieve(ucfg, cat, "username");
11553                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11554                if (!host)
11555                   host = ast_variable_retrieve(ucfg, "general", "host");
11556                if (!username)
11557                   username = ast_variable_retrieve(ucfg, "general", "username");
11558                if (!secret)
11559                   secret = ast_variable_retrieve(ucfg, "general", "secret");
11560                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11561                   if (!ast_strlen_zero(secret))
11562                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11563                   else
11564                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11565                   iax2_register(tmp, 0);
11566                }
11567             }
11568          }
11569          cat = ast_category_browse(ucfg, cat);
11570       }
11571       ast_config_destroy(ucfg);
11572    }
11573    
11574    cat = ast_category_browse(cfg, NULL);
11575    while(cat) {
11576       if (strcasecmp(cat, "general")) {
11577          utype = ast_variable_retrieve(cfg, cat, "type");
11578          if (!strcasecmp(cat, "callnumberlimits")) {
11579             build_callno_limits(ast_variable_browse(cfg, cat));
11580          } else if (utype) {
11581             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11582                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11583                if (user) {
11584                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11585                   user = user_unref(user);
11586                }
11587             }
11588             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11589                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11590                if (peer) {
11591                   if (ast_test_flag(peer, IAX_DYNAMIC))
11592                      reg_source_db(peer);
11593                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11594                   peer = peer_unref(peer);
11595                }
11596             } else if (strcasecmp(utype, "user")) {
11597                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11598             }
11599          } else
11600             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11601       }
11602       cat = ast_category_browse(cfg, cat);
11603    }
11604    ast_config_destroy(cfg);
11605    set_timing();
11606    return 1;
11607 }

static void set_config_destroy ( void   )  [static]

Definition at line 11216 of file chan_iax2.c.

References addr_range_delme_cb(), ao2_callback(), ast_clear_flag, callno_limits, calltoken_ignores, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.

Referenced by set_config().

11217 {
11218    strcpy(accountcode, "");
11219    strcpy(language, "");
11220    strcpy(mohinterpret, "default");
11221    strcpy(mohsuggest, "");
11222    amaflags = 0;
11223    delayreject = 0;
11224    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
11225    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
11226    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
11227    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
11228    delete_users();
11229    ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
11230    ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
11231 }

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

Definition at line 1817 of file chan_iax2.c.

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

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

01818 {
01819    uint16_t limit = global_maxcallno;
01820    struct addr_range *addr_range;
01821    struct sockaddr_in sin = {
01822       .sin_addr.s_addr = peercnt->addr,
01823    };
01824 
01825 
01826    if (peercnt->reg && peercnt->limit) {
01827       return; /* this peercnt has a custom limit set by a registration */
01828    }
01829 
01830    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
01831       limit = addr_range->limit;
01832       if (option_debug) {
01833          ast_log(LOG_NOTICE, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
01834       }
01835       ao2_ref(addr_range, -1);
01836    }
01837 
01838    peercnt->limit = limit;
01839 }

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

Definition at line 1845 of file chan_iax2.c.

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

Referenced by reload_config().

01846 {
01847    struct peercnt *peercnt = obj;
01848 
01849    set_peercnt_limit(peercnt);
01850    if (option_debug) {
01851       ast_log(LOG_NOTICE, "Reset limits for peercnts table\n");
01852    }
01853    return 0;
01854 }

static void set_timing ( void   )  [static]

Definition at line 11201 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by set_config().

11202 {
11203 #ifdef HAVE_DAHDI
11204    int bs = trunkfreq * 8;
11205    if (timingfd > -1) {
11206       if (
11207 #ifdef DAHDI_TIMERACK
11208          ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
11209 #endif         
11210          ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
11211          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
11212    }
11213 #endif
11214 }

static void signal_condition ( ast_mutex_t lock,
ast_cond_t cond 
) [static]

Definition at line 850 of file chan_iax2.c.

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

Referenced by __schedule_action(), iax2_transmit(), and socket_read().

00851 {
00852    ast_mutex_lock(lock);
00853    ast_cond_signal(cond);
00854    ast_mutex_unlock(lock);
00855 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 8234 of file chan_iax2.c.

References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, 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_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, 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_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_tvzero(), ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, DEADLOCK_AVOIDANCE, decrypt_frame(), dp_lookup(), dpcache_lock, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), chan_iax2_pvt::first_iax_message, fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), 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_TXMEDIA, 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, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, iax_frame::list, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, ast_iax2_queue::queue, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.

Referenced by handle_deferred_full_frames().

08235 {
08236    struct sockaddr_in sin;
08237    int res;
08238    int updatehistory=1;
08239    int new = NEW_PREVENT;
08240    void *ptr;
08241    int dcallno = 0;
08242    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
08243    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
08244    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
08245    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
08246    struct ast_iax2_meta_trunk_hdr *mth;
08247    struct ast_iax2_meta_trunk_entry *mte;
08248    struct ast_iax2_meta_trunk_mini *mtm;
08249    struct iax_frame *fr;
08250    struct iax_frame *cur;
08251    struct ast_frame f = { 0, };
08252    struct ast_channel *c;
08253    struct iax2_dpcache *dp;
08254    struct iax2_peer *peer;
08255    struct iax2_trunk_peer *tpeer;
08256    struct timeval rxtrunktime;
08257    struct iax_ies ies;
08258    struct iax_ie_data ied0, ied1;
08259    int format;
08260    int fd;
08261    int exists;
08262    int minivid = 0;
08263    unsigned int ts;
08264    char empty[32]="";      /* Safety measure */
08265    struct iax_frame *duped_fr;
08266    char host_pref_buf[128];
08267    char caller_pref_buf[128];
08268    struct ast_codec_pref pref;
08269    char *using_prefs = "mine";
08270 
08271    /* allocate an iax_frame with 4096 bytes of data buffer */
08272    fr = alloca(sizeof(*fr) + 4096);
08273    memset(fr, 0, sizeof(*fr));
08274    fr->afdatalen = 4096; /* From alloca() above */
08275 
08276    /* Copy frequently used parameters to the stack */
08277    res = thread->buf_len;
08278    fd = thread->iofd;
08279    memcpy(&sin, &thread->iosin, sizeof(sin));
08280 
08281    if (res < sizeof(*mh)) {
08282       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
08283       return 1;
08284    }
08285    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
08286       if (res < sizeof(*vh)) {
08287          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08288          return 1;
08289       }
08290 
08291       /* This is a video frame, get call number */
08292       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
08293       minivid = 1;
08294    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
08295       unsigned char metatype;
08296 
08297       if (res < sizeof(*meta)) {
08298          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08299          return 1;
08300       }
08301 
08302       /* This is a meta header */
08303       switch(meta->metacmd) {
08304       case IAX_META_TRUNK:
08305          if (res < (sizeof(*meta) + sizeof(*mth))) {
08306             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
08307                sizeof(*meta) + sizeof(*mth));
08308             return 1;
08309          }
08310          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
08311          ts = ntohl(mth->ts);
08312          metatype = meta->cmddata;
08313          res -= (sizeof(*meta) + sizeof(*mth));
08314          ptr = mth->data;
08315          tpeer = find_tpeer(&sin, fd);
08316          if (!tpeer) {
08317             ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08318             return 1;
08319          }
08320          tpeer->trunkact = ast_tvnow();
08321          if (!ts || ast_tvzero(tpeer->rxtrunktime))
08322             tpeer->rxtrunktime = tpeer->trunkact;
08323          rxtrunktime = tpeer->rxtrunktime;
08324          ast_mutex_unlock(&tpeer->lock);
08325          while(res >= sizeof(*mte)) {
08326             /* Process channels */
08327             unsigned short callno, trunked_ts, len;
08328 
08329             if (metatype == IAX_META_TRUNK_MINI) {
08330                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
08331                ptr += sizeof(*mtm);
08332                res -= sizeof(*mtm);
08333                len = ntohs(mtm->len);
08334                callno = ntohs(mtm->mini.callno);
08335                trunked_ts = ntohs(mtm->mini.ts);
08336             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
08337                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
08338                ptr += sizeof(*mte);
08339                res -= sizeof(*mte);
08340                len = ntohs(mte->len);
08341                callno = ntohs(mte->callno);
08342                trunked_ts = 0;
08343             } else {
08344                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08345                break;
08346             }
08347             /* Stop if we don't have enough data */
08348             if (len > res)
08349                break;
08350             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
08351             if (fr->callno) {
08352                /* If it's a valid call, deliver the contents.  If not, we
08353                   drop it, since we don't have a scallno to use for an INVAL */
08354                /* Process as a mini frame */
08355                memset(&f, 0, sizeof(f));
08356                f.frametype = AST_FRAME_VOICE;
08357                if (iaxs[fr->callno]) {
08358                   if (iaxs[fr->callno]->voiceformat > 0) {
08359                      f.subclass = iaxs[fr->callno]->voiceformat;
08360                      f.datalen = len;
08361                      if (f.datalen >= 0) {
08362                         if (f.datalen)
08363                            f.data = ptr;
08364                         if(trunked_ts) {
08365                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
08366                         } else
08367                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
08368                         /* Don't pass any packets until we're started */
08369                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08370                            /* Common things */
08371                            f.src = "IAX2";
08372                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
08373                               f.samples = ast_codec_get_samples(&f);
08374                            iax_frame_wrap(fr, &f);
08375                            duped_fr = iaxfrdup2(fr);
08376                            if (duped_fr) {
08377                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
08378                            }
08379                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
08380                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08381                               iaxs[fr->callno]->last = fr->ts;
08382 #if 1
08383                               if (option_debug && iaxdebug)
08384                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08385 #endif
08386                            }
08387                         }
08388                      } else {
08389                         ast_log(LOG_WARNING, "Datalen < 0?\n");
08390                      }
08391                   } else {
08392                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
08393                      iax2_vnak(fr->callno);
08394                   }
08395                }
08396                ast_mutex_unlock(&iaxsl[fr->callno]);
08397             }
08398             ptr += len;
08399             res -= len;
08400          }
08401          
08402       }
08403       return 1;
08404    }
08405 
08406 #ifdef DEBUG_SUPPORT
08407    if (iaxdebug && (res >= sizeof(*fh)))
08408       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
08409 #endif
08410    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08411       if (res < sizeof(*fh)) {
08412          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08413          return 1;
08414       }
08415 
08416       /* Get the destination call number */
08417       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
08418       /* Retrieve the type and subclass */
08419       f.frametype = fh->type;
08420       if (f.frametype == AST_FRAME_VIDEO) {
08421          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
08422       } else {
08423          f.subclass = uncompress_subclass(fh->csub);
08424       }
08425 
08426       /* Deal with POKE/PONG without allocating a callno */
08427       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
08428          /* Reply back with a PONG, but don't care about the result. */
08429          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
08430          return 1;
08431       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
08432          /* Ignore */
08433          return 1;
08434       }
08435 
08436       f.datalen = res - sizeof(*fh);
08437       if (f.datalen) {
08438          if (f.frametype == AST_FRAME_IAX) {
08439             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
08440                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
08441                ast_mutex_unlock(&iaxsl[fr->callno]);
08442                return 1;
08443             }
08444             f.data = NULL;
08445             f.datalen = 0;
08446          } else {
08447             f.data = thread->buf + sizeof(*fh);
08448             memset(&ies, 0, sizeof(ies));
08449          }
08450       } else {
08451          if (f.frametype == AST_FRAME_IAX)
08452             f.data = NULL;
08453          else
08454             f.data = empty;
08455          memset(&ies, 0, sizeof(ies));
08456       }
08457 
08458       if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) {
08459          /* only set NEW_ALLOW if calltoken checks out */
08460          if (handle_call_token(fh, &ies, &sin, fd)) {
08461             return 1;
08462          }
08463 
08464          if (ies.calltoken && ies.calltokendata) {
08465             /* if we've gotten this far, and the calltoken ie data exists,
08466              * then calltoken validation _MUST_ have taken place.  If calltoken
08467              * data is provided, it is always validated reguardless of any
08468              * calltokenoptional or requirecalltoken options */
08469             new = NEW_ALLOW_CALLTOKEN_VALIDATED;
08470          } else {
08471             new = NEW_ALLOW;
08472          }
08473       }
08474    } else {
08475       /* Don't know anything about it yet */
08476       f.frametype = AST_FRAME_NULL;
08477       f.subclass = 0;
08478    }
08479 
08480    if (!fr->callno) {
08481       int check_dcallno = 0;
08482 
08483       /*
08484        * We enforce accurate destination call numbers for all full frames except
08485        * LAGRQ and PING commands.  This is because older versions of Asterisk
08486        * schedule these commands to get sent very quickly, and they will sometimes
08487        * be sent before they receive the first frame from the other side.  When
08488        * that happens, it doesn't contain the destination call number.  However,
08489        * not checking it for these frames is safe.
08490        * 
08491        * Discussed in the following thread:
08492        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
08493        */
08494 
08495       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08496          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
08497       }
08498 
08499       if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
08500          if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) {
08501             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
08502          } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) {
08503             send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
08504          }
08505          return 1;
08506       }
08507    }
08508 
08509    if (fr->callno > 0)
08510       ast_mutex_lock(&iaxsl[fr->callno]);
08511 
08512    if (!fr->callno || !iaxs[fr->callno]) {
08513       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
08514          frame, reply with an inval */
08515       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08516          /* We can only raw hangup control frames */
08517          if (((f.subclass != IAX_COMMAND_INVAL) &&
08518              (f.subclass != IAX_COMMAND_TXCNT) &&
08519              (f.subclass != IAX_COMMAND_TXACC) &&
08520              (f.subclass != IAX_COMMAND_FWDOWNL))||
08521              (f.frametype != AST_FRAME_IAX))
08522             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
08523             fd);
08524       }
08525       if (fr->callno > 0) 
08526          ast_mutex_unlock(&iaxsl[fr->callno]);
08527       return 1;
08528    }
08529    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
08530       if (decrypt_frame(fr->callno, fh, &f, &res)) {
08531          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
08532          ast_mutex_unlock(&iaxsl[fr->callno]);
08533          return 1;
08534       }
08535 #ifdef DEBUG_SUPPORT
08536       else if (iaxdebug)
08537          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
08538 #endif
08539    }
08540 
08541    /* count this frame */
08542    iaxs[fr->callno]->frames_received++;
08543 
08544    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
08545       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
08546       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
08547       unsigned short new_peercallno;
08548 
08549       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
08550       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
08551          if (iaxs[fr->callno]->peercallno) {
08552             remove_by_peercallno(iaxs[fr->callno]);
08553          }
08554          iaxs[fr->callno]->peercallno = new_peercallno;
08555          store_by_peercallno(iaxs[fr->callno]);
08556       }
08557    }
08558    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08559       if (option_debug  && iaxdebug)
08560          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
08561       /* Check if it's out of order (and not an ACK or INVAL) */
08562       fr->oseqno = fh->oseqno;
08563       fr->iseqno = fh->iseqno;
08564       fr->ts = ntohl(fh->ts);
08565 #ifdef IAXTESTS
08566       if (test_resync) {
08567          if (option_debug)
08568             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
08569          fr->ts += test_resync;
08570       }
08571 #endif /* IAXTESTS */
08572 #if 0
08573       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
08574            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
08575                         (f.subclass == IAX_COMMAND_NEW ||
08576                          f.subclass == IAX_COMMAND_AUTHREQ ||
08577                          f.subclass == IAX_COMMAND_ACCEPT ||
08578                          f.subclass == IAX_COMMAND_REJECT))      ) )
08579 #endif
08580       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
08581          updatehistory = 0;
08582       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
08583          (iaxs[fr->callno]->iseqno ||
08584             ((f.subclass != IAX_COMMAND_TXCNT) &&
08585             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
08586             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
08587             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
08588             (f.subclass != IAX_COMMAND_TXACC)) ||
08589             (f.frametype != AST_FRAME_IAX))) {
08590          if (
08591           ((f.subclass != IAX_COMMAND_ACK) &&
08592            (f.subclass != IAX_COMMAND_INVAL) &&
08593            (f.subclass != IAX_COMMAND_TXCNT) &&
08594            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
08595            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
08596            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
08597            (f.subclass != IAX_COMMAND_TXACC) &&
08598            (f.subclass != IAX_COMMAND_VNAK)) ||
08599            (f.frametype != AST_FRAME_IAX)) {
08600             /* If it's not an ACK packet, it's out of order. */
08601             if (option_debug)
08602                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
08603                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
08604             /* Check to see if we need to request retransmission,
08605              * and take sequence number wraparound into account */
08606             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
08607                /* If we've already seen it, ack it XXX There's a border condition here XXX */
08608                if ((f.frametype != AST_FRAME_IAX) || 
08609                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
08610                   if (option_debug)
08611                      ast_log(LOG_DEBUG, "Acking anyway\n");
08612                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
08613                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
08614                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08615                }
08616             } else {
08617                /* Send a VNAK requesting retransmission */
08618                iax2_vnak(fr->callno);
08619             }
08620             ast_mutex_unlock(&iaxsl[fr->callno]);
08621             return 1;
08622          }
08623       } else {
08624          /* Increment unless it's an ACK or VNAK */
08625          if (((f.subclass != IAX_COMMAND_ACK) &&
08626              (f.subclass != IAX_COMMAND_INVAL) &&
08627              (f.subclass != IAX_COMMAND_TXCNT) &&
08628              (f.subclass != IAX_COMMAND_TXACC) &&
08629             (f.subclass != IAX_COMMAND_VNAK)) ||
08630              (f.frametype != AST_FRAME_IAX))
08631             iaxs[fr->callno]->iseqno++;
08632       }
08633       /* Ensure text frames are NULL-terminated */
08634       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
08635          if (res < thread->buf_size)
08636             thread->buf[res++] = '\0';
08637          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
08638             thread->buf[res - 1] = '\0';
08639       }
08640 
08641       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
08642          from the real peer, not the transfer peer */
08643       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
08644           ((f.subclass != IAX_COMMAND_INVAL) ||
08645            (f.frametype != AST_FRAME_IAX))) {
08646          unsigned char x;
08647          int call_to_destroy;
08648          /* XXX This code is not very efficient.  Surely there is a better way which still
08649                 properly handles boundary conditions? XXX */
08650          /* First we have to qualify that the ACKed value is within our window */
08651          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
08652             if (fr->iseqno == x)
08653                break;
08654          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
08655             /* The acknowledgement is within our window.  Time to acknowledge everything
08656                that it says to */
08657             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
08658                /* Ack the packet with the given timestamp */
08659                if (option_debug && iaxdebug)
08660                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
08661                call_to_destroy = 0;
08662                AST_LIST_LOCK(&iaxq.queue);
08663                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08664                   /* If it's our call, and our timestamp, mark -1 retries */
08665                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
08666                      cur->retries = -1;
08667                      /* Destroy call if this is the end */
08668                      if (cur->final)
08669                         call_to_destroy = fr->callno;
08670                   }
08671                }
08672                AST_LIST_UNLOCK(&iaxq.queue);
08673                if (call_to_destroy) {
08674                   if (iaxdebug && option_debug)
08675                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
08676                   ast_mutex_lock(&iaxsl[call_to_destroy]);
08677                   iax2_destroy(call_to_destroy);
08678                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
08679                }
08680             }
08681             /* Note how much we've received acknowledgement for */
08682             if (iaxs[fr->callno])
08683                iaxs[fr->callno]->rseqno = fr->iseqno;
08684             else {
08685                /* Stop processing now */
08686                ast_mutex_unlock(&iaxsl[fr->callno]);
08687                return 1;
08688             }
08689          } else if (option_debug)
08690             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
08691       }
08692       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
08693          ((f.frametype != AST_FRAME_IAX) || 
08694           ((f.subclass != IAX_COMMAND_TXACC) &&
08695            (f.subclass != IAX_COMMAND_TXCNT)))) {
08696          /* Only messages we accept from a transfer host are TXACC and TXCNT */
08697          ast_mutex_unlock(&iaxsl[fr->callno]);
08698          return 1;
08699       }
08700 
08701       /* when we receive the first full frame for a new incoming channel,
08702          it is safe to start the PBX on the channel because we have now
08703          completed a 3-way handshake with the peer */
08704       if ((f.frametype == AST_FRAME_VOICE) ||
08705           (f.frametype == AST_FRAME_VIDEO) ||
08706           (f.frametype == AST_FRAME_IAX)) {
08707          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
08708             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08709             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
08710                ast_mutex_unlock(&iaxsl[fr->callno]);
08711                return 1;
08712             }
08713          }
08714       }
08715 
08716       if (f.frametype == AST_FRAME_VOICE) {
08717          if (f.subclass != iaxs[fr->callno]->voiceformat) {
08718                iaxs[fr->callno]->voiceformat = f.subclass;
08719                if (option_debug)
08720                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
08721                if (iaxs[fr->callno]->owner) {
08722                   int orignative;
08723 retryowner:
08724                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
08725                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08726                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
08727                   }
08728                   if (iaxs[fr->callno]) {
08729                      if (iaxs[fr->callno]->owner) {
08730                         orignative = iaxs[fr->callno]->owner->nativeformats;
08731                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
08732                         if (iaxs[fr->callno]->owner->readformat)
08733                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08734                         iaxs[fr->callno]->owner->nativeformats = orignative;
08735                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
08736                      }
08737                   } else {
08738                      if (option_debug)
08739                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
08740                      ast_mutex_unlock(&iaxsl[fr->callno]);
08741                      return 1;
08742                   }
08743                }
08744          }
08745       }
08746       if (f.frametype == AST_FRAME_VIDEO) {
08747          if (f.subclass != iaxs[fr->callno]->videoformat) {
08748             if (option_debug)
08749                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
08750             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
08751          }
08752       }
08753       if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
08754          if (f.subclass == AST_CONTROL_BUSY) {
08755             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
08756          } else if (f.subclass == AST_CONTROL_CONGESTION) {
08757             iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
08758          }
08759       }
08760       if (f.frametype == AST_FRAME_IAX) {
08761          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
08762          /* Handle the IAX pseudo frame itself */
08763          if (option_debug && iaxdebug) {
08764             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
08765          }
08766 
08767                         /* Update last ts unless the frame's timestamp originated with us. */
08768          if (iaxs[fr->callno]->last < fr->ts &&
08769                             f.subclass != IAX_COMMAND_ACK &&
08770                             f.subclass != IAX_COMMAND_PONG &&
08771                             f.subclass != IAX_COMMAND_LAGRP) {
08772             iaxs[fr->callno]->last = fr->ts;
08773             if (option_debug && iaxdebug) {
08774                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08775             }
08776          }
08777          iaxs[fr->callno]->last_iax_message = f.subclass;
08778          if (!iaxs[fr->callno]->first_iax_message) {
08779             iaxs[fr->callno]->first_iax_message = f.subclass;
08780          }
08781          switch(f.subclass) {
08782          case IAX_COMMAND_ACK:
08783             /* Do nothing */
08784             break;
08785          case IAX_COMMAND_QUELCH:
08786             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08787                     /* Generate Manager Hold event, if necessary*/
08788                if (iaxs[fr->callno]->owner) {
08789                   manager_event(EVENT_FLAG_CALL, "Hold",
08790                      "Channel: %s\r\n"
08791                      "Uniqueid: %s\r\n",
08792                      iaxs[fr->callno]->owner->name, 
08793                      iaxs[fr->callno]->owner->uniqueid);
08794                }
08795 
08796                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
08797                if (ies.musiconhold) {
08798                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08799                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
08800                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
08801                         S_OR(mohsuggest, NULL),
08802                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
08803                      if (!iaxs[fr->callno]) {
08804                         ast_mutex_unlock(&iaxsl[fr->callno]);
08805                         return 1;
08806                      }
08807                   }
08808                }
08809             }
08810             break;
08811          case IAX_COMMAND_UNQUELCH:
08812             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08813                     /* Generate Manager Unhold event, if necessary*/
08814                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
08815                   manager_event(EVENT_FLAG_CALL, "Unhold",
08816                      "Channel: %s\r\n"
08817                      "Uniqueid: %s\r\n",
08818                      iaxs[fr->callno]->owner->name, 
08819                      iaxs[fr->callno]->owner->uniqueid);
08820                }
08821 
08822                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
08823                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08824                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
08825                   if (!iaxs[fr->callno]) {
08826                      ast_mutex_unlock(&iaxsl[fr->callno]);
08827                      return 1;
08828                   }
08829                }
08830             }
08831             break;
08832          case IAX_COMMAND_TXACC:
08833             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
08834                /* Ack the packet with the given timestamp */
08835                AST_LIST_LOCK(&iaxq.queue);
08836                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08837                   /* Cancel any outstanding txcnt's */
08838                   if ((fr->callno == cur->callno) && (cur->transfer))
08839                      cur->retries = -1;
08840                }
08841                AST_LIST_UNLOCK(&iaxq.queue);
08842                memset(&ied1, 0, sizeof(ied1));
08843                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
08844                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
08845                iaxs[fr->callno]->transferring = TRANSFER_READY;
08846             }
08847             break;
08848          case IAX_COMMAND_NEW:
08849             /* Ignore if it's already up */
08850             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
08851                break;
08852             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08853                ast_mutex_unlock(&iaxsl[fr->callno]);
08854                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08855                ast_mutex_lock(&iaxsl[fr->callno]);
08856                if (!iaxs[fr->callno]) {
08857                   ast_mutex_unlock(&iaxsl[fr->callno]);
08858                   return 1;
08859                }
08860             }
08861             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
08862             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
08863                int new_callno;
08864                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
08865                   fr->callno = new_callno;
08866             }
08867             /* For security, always ack immediately */
08868             if (delayreject)
08869                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08870             if (check_access(fr->callno, &sin, &ies)) {
08871                /* They're not allowed on */
08872                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08873                if (authdebug)
08874                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
08875                break;
08876             }
08877             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08878                const char *context, *exten, *cid_num;
08879 
08880                context = ast_strdupa(iaxs[fr->callno]->context);
08881                exten = ast_strdupa(iaxs[fr->callno]->exten);
08882                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
08883 
08884                /* This might re-enter the IAX code and need the lock */
08885                ast_mutex_unlock(&iaxsl[fr->callno]);
08886                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
08887                ast_mutex_lock(&iaxsl[fr->callno]);
08888 
08889                if (!iaxs[fr->callno]) {
08890                   ast_mutex_unlock(&iaxsl[fr->callno]);
08891                   return 1;
08892                }
08893             } else
08894                exists = 0;
08895             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
08896                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08897                   memset(&ied0, 0, sizeof(ied0));
08898                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08899                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08900                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08901                   if (!iaxs[fr->callno]) {
08902                      ast_mutex_unlock(&iaxsl[fr->callno]);
08903                      return 1;
08904                   }
08905                   if (authdebug)
08906                      ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
08907                } else {
08908                   /* Select an appropriate format */
08909 
08910                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08911                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08912                         using_prefs = "reqonly";
08913                      } else {
08914                         using_prefs = "disabled";
08915                      }
08916                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08917                      memset(&pref, 0, sizeof(pref));
08918                      strcpy(caller_pref_buf, "disabled");
08919                      strcpy(host_pref_buf, "disabled");
08920                   } else {
08921                      using_prefs = "mine";
08922                      /* If the information elements are in here... use them */
08923                      if (ies.codec_prefs)
08924                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08925                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08926                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
08927                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08928                            pref = iaxs[fr->callno]->rprefs;
08929                            using_prefs = "caller";
08930                         } else {
08931                            pref = iaxs[fr->callno]->prefs;
08932                         }
08933                      } else
08934                         pref = iaxs[fr->callno]->prefs;
08935                      
08936                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08937                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08938                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08939                   }
08940                   if (!format) {
08941                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08942                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08943                      if (!format) {
08944                         memset(&ied0, 0, sizeof(ied0));
08945                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08946                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08947                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08948                         if (!iaxs[fr->callno]) {
08949                            ast_mutex_unlock(&iaxsl[fr->callno]);
08950                            return 1;
08951                         }
08952                         if (authdebug) {
08953                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08954                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
08955                            else 
08956                               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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08957                         }
08958                      } else {
08959                         /* Pick one... */
08960                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08961                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08962                               format = 0;
08963                         } else {
08964                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08965                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08966                               memset(&pref, 0, sizeof(pref));
08967                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08968                               strcpy(caller_pref_buf,"disabled");
08969                               strcpy(host_pref_buf,"disabled");
08970                            } else {
08971                               using_prefs = "mine";
08972                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08973                                  /* Do the opposite of what we tried above. */
08974                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08975                                     pref = iaxs[fr->callno]->prefs;                       
08976                                  } else {
08977                                     pref = iaxs[fr->callno]->rprefs;
08978                                     using_prefs = "caller";
08979                                  }
08980                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08981                            
08982                               } else /* if no codec_prefs IE do it the old way */
08983                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08984                            }
08985                         }
08986 
08987                         if (!format) {
08988                            memset(&ied0, 0, sizeof(ied0));
08989                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08990                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08991                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08992                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08993                            if (!iaxs[fr->callno]) {
08994                               ast_mutex_unlock(&iaxsl[fr->callno]);
08995                               return 1;
08996                            }
08997                            if (authdebug)
08998                               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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08999                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
09000                            break;
09001                         }
09002                      }
09003                   }
09004                   if (format) {
09005                      /* No authentication required, let them in */
09006                      memset(&ied1, 0, sizeof(ied1));
09007                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09008                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09009                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09010                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09011                         if (option_verbose > 2) 
09012                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
09013                                     "%srequested format = %s,\n"
09014                                     "%srequested prefs = %s,\n"
09015                                     "%sactual format = %s,\n"
09016                                     "%shost prefs = %s,\n"
09017                                     "%spriority = %s\n",
09018                                     ast_inet_ntoa(sin.sin_addr), 
09019                                     VERBOSE_PREFIX_4,
09020                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
09021                                     VERBOSE_PREFIX_4,
09022                                     caller_pref_buf,
09023                                     VERBOSE_PREFIX_4,
09024                                     ast_getformatname(format), 
09025                                     VERBOSE_PREFIX_4,
09026                                     host_pref_buf, 
09027                                     VERBOSE_PREFIX_4,
09028                                     using_prefs);
09029                         
09030                         iaxs[fr->callno]->chosenformat = format;
09031                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
09032                      } else {
09033                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09034                         /* If this is a TBD call, we're ready but now what...  */
09035                         if (option_verbose > 2)
09036                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09037                      }
09038                   }
09039                }
09040                break;
09041             }
09042             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
09043                merge_encryption(iaxs[fr->callno],ies.encmethods);
09044             else
09045                iaxs[fr->callno]->encmethods = 0;
09046             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
09047                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
09048             if (!iaxs[fr->callno]) {
09049                ast_mutex_unlock(&iaxsl[fr->callno]);
09050                return 1;
09051             }
09052             break;
09053          case IAX_COMMAND_DPREQ:
09054             /* Request status in the dialplan */
09055             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
09056                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
09057                if (iaxcompat) {
09058                   /* Spawn a thread for the lookup */
09059                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
09060                } else {
09061                   /* Just look it up */
09062                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
09063                }
09064             }
09065             break;
09066          case IAX_COMMAND_HANGUP:
09067             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09068             if (option_debug)
09069                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
09070             /* Set hangup cause according to remote */
09071             if (ies.causecode && iaxs[fr->callno]->owner)
09072                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09073             /* Send ack immediately, before we destroy */
09074             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09075             iax2_destroy(fr->callno);
09076             break;
09077          case IAX_COMMAND_REJECT:
09078             /* Set hangup cause according to remote */
09079             if (ies.causecode && iaxs[fr->callno]->owner)
09080                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09081 
09082             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09083                if (iaxs[fr->callno]->owner && authdebug)
09084                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09085                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09086                      ies.cause ? ies.cause : "<Unknown>");
09087                if (option_debug)
09088                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
09089                      fr->callno);
09090             }
09091             /* Send ack immediately, before we destroy */
09092             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
09093                          fr->ts, NULL, 0, fr->iseqno);
09094             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
09095                iaxs[fr->callno]->error = EPERM;
09096             iax2_destroy(fr->callno);
09097             break;
09098          case IAX_COMMAND_TRANSFER:
09099          {
09100             struct ast_channel *bridged_chan;
09101 
09102             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
09103                /* Set BLINDTRANSFER channel variables */
09104 
09105                ast_mutex_unlock(&iaxsl[fr->callno]);
09106                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
09107                ast_mutex_lock(&iaxsl[fr->callno]);
09108                if (!iaxs[fr->callno]) {
09109                   ast_mutex_unlock(&iaxsl[fr->callno]);
09110                   return 1;
09111                }
09112 
09113                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
09114                if (!strcmp(ies.called_number, ast_parking_ext())) {
09115                   struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
09116                   ast_mutex_unlock(&iaxsl[fr->callno]);
09117                   if (iax_park(bridged_chan, saved_channel)) {
09118                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
09119                   } else {
09120                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
09121                   }
09122                   ast_mutex_lock(&iaxsl[fr->callno]);
09123                } else {
09124                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
09125                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
09126                         ies.called_number, iaxs[fr->callno]->context);
09127                   else
09128                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
09129                         ies.called_number, iaxs[fr->callno]->context);
09130                }
09131             } else
09132                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
09133 
09134             break;
09135          }
09136          case IAX_COMMAND_ACCEPT:
09137             /* Ignore if call is already up or needs authentication or is a TBD */
09138             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
09139                break;
09140             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09141                /* Send ack immediately, before we destroy */
09142                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09143                iax2_destroy(fr->callno);
09144                break;
09145             }
09146             if (ies.format) {
09147                iaxs[fr->callno]->peerformat = ies.format;
09148             } else {
09149                if (iaxs[fr->callno]->owner)
09150                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
09151                else
09152                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
09153             }
09154             if (option_verbose > 2)
09155                ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
09156             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
09157                memset(&ied0, 0, sizeof(ied0));
09158                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09159                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09160                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09161                if (!iaxs[fr->callno]) {
09162                   ast_mutex_unlock(&iaxsl[fr->callno]);
09163                   return 1;
09164                }
09165                if (authdebug)
09166                   ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09167             } else {
09168                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09169                if (iaxs[fr->callno]->owner) {
09170                   /* Switch us to use a compatible format */
09171                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
09172                   if (option_verbose > 2)
09173                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
09174 retryowner2:
09175                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
09176                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09177                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
09178                   }
09179                   
09180                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
09181                      /* Setup read/write formats properly. */
09182                      if (iaxs[fr->callno]->owner->writeformat)
09183                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
09184                      if (iaxs[fr->callno]->owner->readformat)
09185                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
09186                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
09187                   }
09188                }
09189             }
09190             if (iaxs[fr->callno]) {
09191                ast_mutex_lock(&dpcache_lock);
09192                dp = iaxs[fr->callno]->dpentries;
09193                while(dp) {
09194                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
09195                      iax2_dprequest(dp, fr->callno);
09196                   }
09197                   dp = dp->peer;
09198                }
09199                ast_mutex_unlock(&dpcache_lock);
09200             }
09201             break;
09202          case IAX_COMMAND_POKE:
09203             /* Send back a pong packet with the original timestamp */
09204             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
09205             if (!iaxs[fr->callno]) {
09206                ast_mutex_unlock(&iaxsl[fr->callno]);
09207                return 1;
09208             }
09209             break;
09210          case IAX_COMMAND_PING:
09211          {
09212             struct iax_ie_data pingied;
09213             construct_rr(iaxs[fr->callno], &pingied);
09214             /* Send back a pong packet with the original timestamp */
09215             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
09216          }
09217             break;
09218          case IAX_COMMAND_PONG:
09219             /* Calculate ping time */
09220             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
09221             /* save RR info */
09222             save_rr(fr, &ies);
09223 
09224             if (iaxs[fr->callno]->peerpoke) {
09225                peer = iaxs[fr->callno]->peerpoke;
09226                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
09227                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
09228                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
09229                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
09230                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
09231                   }
09232                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
09233                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
09234                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
09235                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
09236                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
09237                   }
09238                }
09239                peer->lastms = iaxs[fr->callno]->pingtime;
09240                if (peer->smoothing && (peer->lastms > -1))
09241                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
09242                else if (peer->smoothing && peer->lastms < 0)
09243                   peer->historicms = (0 + peer->historicms) / 2;
09244                else              
09245                   peer->historicms = iaxs[fr->callno]->pingtime;
09246 
09247                /* Remove scheduled iax2_poke_noanswer */
09248                if (peer->pokeexpire > -1) {
09249                   if (!ast_sched_del(sched, peer->pokeexpire)) {
09250                      peer_unref(peer);
09251                      peer->pokeexpire = -1;
09252                   }
09253                }
09254                /* Schedule the next cycle */
09255                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
09256                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09257                else
09258                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
09259                if (peer->pokeexpire == -1)
09260                   peer_unref(peer);
09261                /* and finally send the ack */
09262                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09263                /* And wrap up the qualify call */
09264                iax2_destroy(fr->callno);
09265                peer->callno = 0;
09266                if (option_debug)
09267                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
09268             }
09269             break;
09270          case IAX_COMMAND_LAGRQ:
09271          case IAX_COMMAND_LAGRP:
09272             f.src = "LAGRQ";
09273             f.mallocd = 0;
09274             f.offset = 0;
09275             f.samples = 0;
09276             iax_frame_wrap(fr, &f);
09277             if(f.subclass == IAX_COMMAND_LAGRQ) {
09278                /* Received a LAGRQ - echo back a LAGRP */
09279                fr->af.subclass = IAX_COMMAND_LAGRP;
09280                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
09281             } else {
09282                /* Received LAGRP in response to our LAGRQ */
09283                unsigned int ts;
09284                /* This is a reply we've been given, actually measure the difference */
09285                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
09286                iaxs[fr->callno]->lag = ts - fr->ts;
09287                if (option_debug && iaxdebug)
09288                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
09289                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
09290             }
09291             break;
09292          case IAX_COMMAND_AUTHREQ:
09293             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09294                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>");
09295                break;
09296             }
09297             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
09298                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
09299                         .subclass = AST_CONTROL_HANGUP,
09300                };
09301                ast_log(LOG_WARNING, 
09302                   "I don't know how to authenticate %s to %s\n", 
09303                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
09304                iax2_queue_frame(fr->callno, &hangup_fr);
09305             }
09306             if (!iaxs[fr->callno]) {
09307                ast_mutex_unlock(&iaxsl[fr->callno]);
09308                return 1;
09309             }
09310             break;
09311          case IAX_COMMAND_AUTHREP:
09312             /* For security, always ack immediately */
09313             if (delayreject)
09314                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09315             /* Ignore once we've started */
09316             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09317                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>");
09318                break;
09319             }
09320             if (authenticate_verify(iaxs[fr->callno], &ies)) {
09321                if (authdebug)
09322                   ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
09323                memset(&ied0, 0, sizeof(ied0));
09324                auth_fail(fr->callno, IAX_COMMAND_REJECT);
09325                break;
09326             }
09327             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09328                /* This might re-enter the IAX code and need the lock */
09329                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
09330             } else
09331                exists = 0;
09332             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09333                if (authdebug)
09334                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
09335                memset(&ied0, 0, sizeof(ied0));
09336                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09337                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09338                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09339                if (!iaxs[fr->callno]) {
09340                   ast_mutex_unlock(&iaxsl[fr->callno]);
09341                   return 1;
09342                }
09343             } else {
09344                /* Select an appropriate format */
09345                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09346                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09347                      using_prefs = "reqonly";
09348                   } else {
09349                      using_prefs = "disabled";
09350                   }
09351                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09352                   memset(&pref, 0, sizeof(pref));
09353                   strcpy(caller_pref_buf, "disabled");
09354                   strcpy(host_pref_buf, "disabled");
09355                } else {
09356                   using_prefs = "mine";
09357                   if (ies.codec_prefs)
09358                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09359                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09360                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09361                         pref = iaxs[fr->callno]->rprefs;
09362                         using_prefs = "caller";
09363                      } else {
09364                         pref = iaxs[fr->callno]->prefs;
09365                      }
09366                   } else /* if no codec_prefs IE do it the old way */
09367                      pref = iaxs[fr->callno]->prefs;
09368                
09369                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09370                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09371                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09372                }
09373                if (!format) {
09374                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09375                      if (option_debug)
09376                         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);
09377                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09378                   }
09379                   if (!format) {
09380                      if (authdebug) {
09381                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
09382                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09383                         else
09384                            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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09385                      }
09386                      memset(&ied0, 0, sizeof(ied0));
09387                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09388                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09389                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09390                      if (!iaxs[fr->callno]) {
09391                         ast_mutex_unlock(&iaxsl[fr->callno]);
09392                         return 1;
09393                      }
09394                   } else {
09395                      /* Pick one... */
09396                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09397                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09398                            format = 0;
09399                      } else {
09400                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09401                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09402                            memset(&pref, 0, sizeof(pref));
09403                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
09404                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09405                            strcpy(caller_pref_buf,"disabled");
09406                            strcpy(host_pref_buf,"disabled");
09407                         } else {
09408                            using_prefs = "mine";
09409                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09410                               /* Do the opposite of what we tried above. */
09411                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09412                                  pref = iaxs[fr->callno]->prefs;                 
09413                               } else {
09414                                  pref = iaxs[fr->callno]->rprefs;
09415                                  using_prefs = "caller";
09416                               }
09417                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09418                            } else /* if no codec_prefs IE do it the old way */
09419                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
09420                         }
09421                      }
09422                      if (!format) {
09423                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09424                         if (authdebug) {
09425                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09426                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09427                            else
09428                               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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09429                         }
09430                         memset(&ied0, 0, sizeof(ied0));
09431                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09432                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09433                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09434                         if (!iaxs[fr->callno]) {
09435                            ast_mutex_unlock(&iaxsl[fr->callno]);
09436                            return 1;
09437                         }
09438                      }
09439                   }
09440                }
09441                if (format) {
09442                   /* Authentication received */
09443                   memset(&ied1, 0, sizeof(ied1));
09444                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09445                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09446                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09447                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09448                      if (option_verbose > 2) 
09449                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
09450                                  "%srequested format = %s,\n"
09451                                  "%srequested prefs = %s,\n"
09452                                  "%sactual format = %s,\n"
09453                                  "%shost prefs = %s,\n"
09454                                  "%spriority = %s\n", 
09455                                  ast_inet_ntoa(sin.sin_addr), 
09456                                  VERBOSE_PREFIX_4,
09457                                  ast_getformatname(iaxs[fr->callno]->peerformat),
09458                                  VERBOSE_PREFIX_4,
09459                                  caller_pref_buf,
09460                                  VERBOSE_PREFIX_4,
09461                                  ast_getformatname(format),
09462                                  VERBOSE_PREFIX_4,
09463                                  host_pref_buf,
09464                                  VERBOSE_PREFIX_4,
09465                                  using_prefs);
09466 
09467                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09468                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
09469                         iax2_destroy(fr->callno);
09470                   } else {
09471                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09472                      /* If this is a TBD call, we're ready but now what...  */
09473                      if (option_verbose > 2)
09474                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09475                   }
09476                }
09477             }
09478             break;
09479          case IAX_COMMAND_DIAL:
09480             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
09481                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09482                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
09483                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
09484                   if (authdebug)
09485                      ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
09486                   memset(&ied0, 0, sizeof(ied0));
09487                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09488                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09489                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09490                   if (!iaxs[fr->callno]) {
09491                      ast_mutex_unlock(&iaxsl[fr->callno]);
09492                      return 1;
09493                   }
09494                } else {
09495                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09496                   if (option_verbose > 2) 
09497                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
09498                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09499                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
09500                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
09501                      iax2_destroy(fr->callno);
09502                }
09503             }
09504             break;
09505          case IAX_COMMAND_INVAL:
09506             iaxs[fr->callno]->error = ENOTCONN;
09507             if (option_debug)
09508                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
09509             iax2_destroy(fr->callno);
09510             if (option_debug)
09511                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
09512             break;
09513          case IAX_COMMAND_VNAK:
09514             if (option_debug)
09515                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
09516             /* Force retransmission */
09517             vnak_retransmit(fr->callno, fr->iseqno);
09518             break;
09519          case IAX_COMMAND_REGREQ:
09520          case IAX_COMMAND_REGREL:
09521             /* For security, always ack immediately */
09522             if (delayreject)
09523                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09524             if (register_verify(fr->callno, &sin, &ies)) {
09525                if (!iaxs[fr->callno]) {
09526                   ast_mutex_unlock(&iaxsl[fr->callno]);
09527                   return 1;
09528                }
09529                /* Send delayed failure */
09530                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
09531                break;
09532             }
09533             if (!iaxs[fr->callno]) {
09534                ast_mutex_unlock(&iaxsl[fr->callno]);
09535                return 1;
09536             }
09537             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
09538                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
09539 
09540                if (f.subclass == IAX_COMMAND_REGREL)
09541                   memset(&sin, 0, sizeof(sin));
09542                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
09543                   ast_log(LOG_WARNING, "Registry error\n");
09544                if (!iaxs[fr->callno]) {
09545                   ast_mutex_unlock(&iaxsl[fr->callno]);
09546                   return 1;
09547                }
09548                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09549                   ast_mutex_unlock(&iaxsl[fr->callno]);
09550                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09551                   ast_mutex_lock(&iaxsl[fr->callno]);
09552                   if (!iaxs[fr->callno]) {
09553                      ast_mutex_unlock(&iaxsl[fr->callno]);
09554                      return 1;
09555                   }
09556                }
09557                break;
09558             }
09559             registry_authrequest(fr->callno);
09560             if (!iaxs[fr->callno]) {
09561                ast_mutex_unlock(&iaxsl[fr->callno]);
09562                return 1;
09563             }
09564             break;
09565          case IAX_COMMAND_REGACK:
09566             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
09567                ast_log(LOG_WARNING, "Registration failure\n");
09568             /* Send ack immediately, before we destroy */
09569             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09570             iax2_destroy(fr->callno);
09571             break;
09572          case IAX_COMMAND_REGREJ:
09573             if (iaxs[fr->callno]->reg) {
09574                if (authdebug) {
09575                   ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
09576                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
09577                }
09578                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
09579             }
09580             /* Send ack immediately, before we destroy */
09581             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09582             iax2_destroy(fr->callno);
09583             break;
09584          case IAX_COMMAND_REGAUTH:
09585             /* Authentication request */
09586             if (registry_rerequest(&ies, fr->callno, &sin)) {
09587                memset(&ied0, 0, sizeof(ied0));
09588                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
09589                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09590                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09591                if (!iaxs[fr->callno]) {
09592                   ast_mutex_unlock(&iaxsl[fr->callno]);
09593                   return 1;
09594                }
09595             }
09596             break;
09597          case IAX_COMMAND_TXREJ:
09598             iaxs[fr->callno]->transferring = 0;
09599             if (option_verbose > 2) 
09600                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09601             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
09602             if (iaxs[fr->callno]->bridgecallno) {
09603                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
09604                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
09605                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
09606                }
09607             }
09608             break;
09609          case IAX_COMMAND_TXREADY:
09610             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
09611                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
09612                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
09613                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
09614                else
09615                   iaxs[fr->callno]->transferring = TRANSFER_READY;
09616                if (option_verbose > 2) 
09617                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09618                if (iaxs[fr->callno]->bridgecallno) {
09619                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
09620                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
09621                      /* They're both ready, now release them. */
09622                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
09623                         if (option_verbose > 2) 
09624                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09625                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09626 
09627                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
09628                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
09629 
09630                         memset(&ied0, 0, sizeof(ied0));
09631                         memset(&ied1, 0, sizeof(ied1));
09632                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09633                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09634                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
09635                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
09636                      } else {
09637                         if (option_verbose > 2) 
09638                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09639                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09640 
09641                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
09642                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
09643                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
09644                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09645 
09646                         /* Stop doing lag & ping requests */
09647                         stop_stuff(fr->callno);
09648                         stop_stuff(iaxs[fr->callno]->bridgecallno);
09649 
09650                         memset(&ied0, 0, sizeof(ied0));
09651                         memset(&ied1, 0, sizeof(ied1));
09652                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09653                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09654                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
09655                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
09656                      }
09657 
09658                   }
09659                }
09660             }
09661             break;
09662          case IAX_COMMAND_TXREQ:
09663             try_transfer(iaxs[fr->callno], &ies);
09664             break;
09665          case IAX_COMMAND_TXCNT:
09666             if (iaxs[fr->callno]->transferring)
09667                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
09668             break;
09669          case IAX_COMMAND_TXREL:
09670             /* Send ack immediately, rather than waiting until we've changed addresses */
09671             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09672             complete_transfer(fr->callno, &ies);
09673             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
09674             break;   
09675          case IAX_COMMAND_TXMEDIA:
09676             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
09677                                         AST_LIST_LOCK(&iaxq.queue);
09678                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
09679                                                 /* Cancel any outstanding frames and start anew */
09680                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
09681                                                         cur->retries = -1;
09682                                                 }
09683                                         }
09684                                         AST_LIST_UNLOCK(&iaxq.queue);
09685                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
09686                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
09687             }
09688             break;   
09689          case IAX_COMMAND_DPREP:
09690             complete_dpreply(iaxs[fr->callno], &ies);
09691             break;
09692          case IAX_COMMAND_UNSUPPORT:
09693             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
09694             break;
09695          case IAX_COMMAND_FWDOWNL:
09696             /* Firmware download */
09697             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
09698                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
09699                break;
09700             }
09701             memset(&ied0, 0, sizeof(ied0));
09702             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
09703             if (res < 0)
09704                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09705             else if (res > 0)
09706                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09707             else
09708                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09709             if (!iaxs[fr->callno]) {
09710                ast_mutex_unlock(&iaxsl[fr->callno]);
09711                return 1;
09712             }
09713             break;
09714          case IAX_COMMAND_CALLTOKEN:
09715          {
09716             struct iax_frame *cur;
09717             AST_LIST_LOCK(&iaxq.queue);
09718             AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
09719                /* find the last sent frame in our frame queue for this callno.
09720                 * There are many things to take into account before resending this frame.
09721                 * All of these are taken care of in resend_with_token() */
09722                if (cur->callno == fr->callno) {
09723                   break;
09724                }
09725             }
09726             AST_LIST_UNLOCK(&iaxq.queue);
09727 
09728             /* find last sent frame */
09729             if (cur && ies.calltoken && ies.calltokendata) {
09730                resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
09731             }
09732             break;
09733          }
09734          default:
09735             if (option_debug)
09736                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
09737             memset(&ied0, 0, sizeof(ied0));
09738             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
09739             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
09740          }
09741          /* Don't actually pass these frames along */
09742          if ((f.subclass != IAX_COMMAND_ACK) && 
09743            (f.subclass != IAX_COMMAND_TXCNT) && 
09744            (f.subclass != IAX_COMMAND_TXACC) && 
09745            (f.subclass != IAX_COMMAND_INVAL) &&
09746            (f.subclass != IAX_COMMAND_VNAK)) { 
09747             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09748                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09749          }
09750          ast_mutex_unlock(&iaxsl[fr->callno]);
09751          return 1;
09752       }
09753       /* Unless this is an ACK or INVAL frame, ack it */
09754       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09755          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09756    } else if (minivid) {
09757       f.frametype = AST_FRAME_VIDEO;
09758       if (iaxs[fr->callno]->videoformat > 0) 
09759          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
09760       else {
09761          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
09762          iax2_vnak(fr->callno);
09763          ast_mutex_unlock(&iaxsl[fr->callno]);
09764          return 1;
09765       }
09766       f.datalen = res - sizeof(*vh);
09767       if (f.datalen)
09768          f.data = thread->buf + sizeof(*vh);
09769       else
09770          f.data = NULL;
09771 #ifdef IAXTESTS
09772       if (test_resync) {
09773          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
09774       } else
09775 #endif /* IAXTESTS */
09776          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
09777    } else {
09778       /* A mini frame */
09779       f.frametype = AST_FRAME_VOICE;
09780       if (iaxs[fr->callno]->voiceformat > 0)
09781          f.subclass = iaxs[fr->callno]->voiceformat;
09782       else {
09783          if (option_debug)
09784             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
09785          iax2_vnak(fr->callno);
09786          ast_mutex_unlock(&iaxsl[fr->callno]);
09787          return 1;
09788       }
09789       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
09790       if (f.datalen < 0) {
09791          ast_log(LOG_WARNING, "Datalen < 0?\n");
09792          ast_mutex_unlock(&iaxsl[fr->callno]);
09793          return 1;
09794       }
09795       if (f.datalen)
09796          f.data = thread->buf + sizeof(*mh);
09797       else
09798          f.data = NULL;
09799 #ifdef IAXTESTS
09800       if (test_resync) {
09801          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
09802       } else
09803 #endif /* IAXTESTS */
09804       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
09805       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
09806    }
09807    /* Don't pass any packets until we're started */
09808    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09809       ast_mutex_unlock(&iaxsl[fr->callno]);
09810       return 1;
09811    }
09812    /* Common things */
09813    f.src = "IAX2";
09814    f.mallocd = 0;
09815    f.offset = 0;
09816    f.len = 0;
09817    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
09818       f.samples = ast_codec_get_samples(&f);
09819       /* We need to byteswap incoming slinear samples from network byte order */
09820       if (f.subclass == AST_FORMAT_SLINEAR)
09821          ast_frame_byteswap_be(&f);
09822    } else
09823       f.samples = 0;
09824    iax_frame_wrap(fr, &f);
09825 
09826    /* If this is our most recent packet, use it as our basis for timestamping */
09827    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09828       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
09829       fr->outoforder = 0;
09830    } else {
09831       if (option_debug && iaxdebug && iaxs[fr->callno])
09832          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);
09833       fr->outoforder = -1;
09834    }
09835    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
09836    duped_fr = iaxfrdup2(fr);
09837    if (duped_fr) {
09838       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
09839    }
09840    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09841       iaxs[fr->callno]->last = fr->ts;
09842 #if 1
09843       if (option_debug && iaxdebug)
09844          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09845 #endif
09846    }
09847 
09848    /* Always run again */
09849    ast_mutex_unlock(&iaxsl[fr->callno]);
09850    return 1;
09851 }

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

Definition at line 8156 of file chan_iax2.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, t, thread, and ast_iax2_full_hdr::type.

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

08157 {
08158    struct iax2_thread *thread;
08159    socklen_t len;
08160    time_t t;
08161    static time_t last_errtime = 0;
08162    struct ast_iax2_full_hdr *fh;
08163 
08164    if (!(thread = find_idle_thread())) {
08165       time(&t);
08166       if (t != last_errtime && option_debug)
08167          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
08168       last_errtime = t;
08169       usleep(1);
08170       return 1;
08171    }
08172 
08173    len = sizeof(thread->iosin);
08174    thread->iofd = fd;
08175    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
08176    thread->buf_size = sizeof(thread->readbuf);
08177    thread->buf = thread->readbuf;
08178    if (thread->buf_len < 0) {
08179       if (errno != ECONNREFUSED && errno != EAGAIN)
08180          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
08181       handle_error();
08182       thread->iostate = IAX_IOSTATE_IDLE;
08183       signal_condition(&thread->lock, &thread->cond);
08184       return 1;
08185    }
08186    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
08187       thread->iostate = IAX_IOSTATE_IDLE;
08188       signal_condition(&thread->lock, &thread->cond);
08189       return 1;
08190    }
08191    
08192    /* Determine if this frame is a full frame; if so, and any thread is currently
08193       processing a full frame for the same callno from this peer, then drop this
08194       frame (and the peer will retransmit it) */
08195    fh = (struct ast_iax2_full_hdr *) thread->buf;
08196    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08197       struct iax2_thread *cur = NULL;
08198       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08199       
08200       AST_LIST_LOCK(&active_list);
08201       AST_LIST_TRAVERSE(&active_list, cur, list) {
08202          if ((cur->ffinfo.callno == callno) &&
08203              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08204             break;
08205       }
08206       if (cur) {
08207          /* we found another thread processing a full frame for this call,
08208             so queue it up for processing later. */
08209          defer_full_frame(thread, cur);
08210          AST_LIST_UNLOCK(&active_list);
08211          thread->iostate = IAX_IOSTATE_IDLE;
08212          signal_condition(&thread->lock, &thread->cond);
08213          return 1;
08214       } else {
08215          /* this thread is going to process this frame, so mark it */
08216          thread->ffinfo.callno = callno;
08217          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08218          thread->ffinfo.type = fh->type;
08219          thread->ffinfo.csub = fh->csub;
08220       }
08221       AST_LIST_UNLOCK(&active_list);
08222    }
08223    
08224    /* Mark as ready and send on its way */
08225    thread->iostate = IAX_IOSTATE_READY;
08226 #ifdef DEBUG_SCHED_MULTITHREAD
08227    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08228 #endif
08229    signal_condition(&thread->lock, &thread->cond);
08230 
08231    return 1;
08232 }

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

Definition at line 7943 of file chan_iax2.c.

References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.

Referenced by socket_process().

07944 {
07945    pthread_t newthread;
07946    struct dpreq_data *dpr;
07947    pthread_attr_t attr;
07948    
07949    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07950       return;
07951 
07952    pthread_attr_init(&attr);
07953    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
07954 
07955    dpr->callno = callno;
07956    ast_copy_string(dpr->context, context, sizeof(dpr->context));
07957    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07958    if (callerid)
07959       dpr->callerid = ast_strdup(callerid);
07960    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
07961       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07962    }
07963 
07964    pthread_attr_destroy(&attr);
07965 }

static int start_network_thread ( void   )  [static]

Definition at line 10467 of file chan_iax2.c.

References ast_calloc, ast_cond_init(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create, ast_pthread_create_background, ast_verbose(), free, iax2_process_thread(), IAX_TYPE_POOL, iaxthreadcount, iax_frame::list, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.

Referenced by load_module().

10468 {
10469    pthread_attr_t attr;
10470    int threadcount = 0;
10471    int x;
10472    for (x = 0; x < iaxthreadcount; x++) {
10473       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
10474       if (thread) {
10475          thread->type = IAX_TYPE_POOL;
10476          thread->threadnum = ++threadcount;
10477          ast_mutex_init(&thread->lock);
10478          ast_cond_init(&thread->cond, NULL);
10479          pthread_attr_init(&attr);
10480          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
10481          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
10482             ast_log(LOG_WARNING, "Failed to create new thread!\n");
10483             free(thread);
10484             thread = NULL;
10485          }
10486          AST_LIST_LOCK(&idle_list);
10487          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10488          AST_LIST_UNLOCK(&idle_list);
10489       }
10490    }
10491    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10492    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10493    if (option_verbose > 1)
10494       ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
10495    return 0;
10496 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 7625 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

07626 {
07627    iax2_destroy_helper(iaxs[callno]);
07628 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1386 of file chan_iax2.c.

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

Referenced by __find_callno(), complete_transfer(), and socket_process().

01387 {
01388    if (!pvt->peercallno) {
01389       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01390       return;
01391    }
01392 
01393    ao2_link(iax_peercallno_pvts, pvt);
01394 }

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1367 of file chan_iax2.c.

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

Referenced by try_transfer().

01368 {
01369    if (!pvt->transfercallno) {
01370       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01371       return;
01372    }
01373 
01374    ao2_link(iax_transfercallno_pvts, pvt);
01375 }

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

Definition at line 7812 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, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), totalcalls, tpeerlock, tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

07813 {
07814    char buf[1024];
07815    int res;
07816    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
07817    int processed = 0;
07818    int totalcalls = 0;
07819 #ifdef DAHDI_TIMERACK
07820    int x = 1;
07821 #endif
07822    struct timeval now;
07823    if (iaxtrunkdebug)
07824       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
07825    gettimeofday(&now, NULL);
07826    if (events & AST_IO_PRI) {
07827 #ifdef DAHDI_TIMERACK
07828       /* Great, this is a timing interface, just call the ioctl */
07829       if (ioctl(fd, DAHDI_TIMERACK, &x)) {
07830          ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
07831          usleep(1);
07832          return -1;
07833       }
07834 #endif      
07835    } else {
07836       /* Read and ignore from the pseudo channel for timing */
07837       res = read(fd, buf, sizeof(buf));
07838       if (res < 1) {
07839          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
07840          return 1;
07841       }
07842    }
07843    /* For each peer that supports trunking... */
07844    ast_mutex_lock(&tpeerlock);
07845    tpeer = tpeers;
07846    while(tpeer) {
07847       processed++;
07848       res = 0;
07849       ast_mutex_lock(&tpeer->lock);
07850       /* We can drop a single tpeer per pass.  That makes all this logic
07851          substantially easier */
07852       if (!drop && iax2_trunk_expired(tpeer, &now)) {
07853          /* Take it out of the list, but don't free it yet, because it
07854             could be in use */
07855          if (prev)
07856             prev->next = tpeer->next;
07857          else
07858             tpeers = tpeer->next;
07859          drop = tpeer;
07860       } else {
07861          res = send_trunk(tpeer, &now);
07862          if (iaxtrunkdebug)
07863             ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
07864       }     
07865       totalcalls += res;   
07866       res = 0;
07867       ast_mutex_unlock(&tpeer->lock);
07868       prev = tpeer;
07869       tpeer = tpeer->next;
07870    }
07871    ast_mutex_unlock(&tpeerlock);
07872    if (drop) {
07873       ast_mutex_lock(&drop->lock);
07874       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
07875          because by the time they could get tpeerlock, we've already grabbed it */
07876       if (option_debug)
07877          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07878       if (drop->trunkdata) {
07879          free(drop->trunkdata);
07880          drop->trunkdata = NULL;
07881       }
07882       ast_mutex_unlock(&drop->lock);
07883       ast_mutex_destroy(&drop->lock);
07884       free(drop);
07885       
07886    }
07887    if (iaxtrunkdebug)
07888       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07889    iaxtrunkdebug =0;
07890    return 1;
07891 }

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

Definition at line 12509 of file chan_iax2.c.

References chan_iax2_pvt::frames_received, and match().

Referenced by load_objects().

12510 {
12511    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12512 
12513    /* The frames_received field is used to hold whether we're matching
12514     * against a full frame or not ... */
12515 
12516    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12517       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12518 }

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

Definition at line 12502 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

12503 {
12504    const struct chan_iax2_pvt *pvt = obj;
12505 
12506    return pvt->transfercallno;
12507 }

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

Definition at line 2889 of file chan_iax2.c.

References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.

Referenced by send_trunk().

02890 {
02891    int res;
02892    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02893                sizeof(*sin));
02894    if (res < 0) {
02895       if (option_debug)
02896          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02897       handle_error();
02898    } else
02899       res = 0;
02900    return res;
02901 }

static int try_firmware ( char *  s  )  [static]

Definition at line 2577 of file chan_iax2.c.

References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.

Referenced by reload_firmware().

02578 {
02579    struct stat stbuf;
02580    struct iax_firmware *cur;
02581    int ifd;
02582    int fd;
02583    int res;
02584    
02585    struct ast_iax2_firmware_header *fwh, fwh2;
02586    struct MD5Context md5;
02587    unsigned char sum[16];
02588    unsigned char buf[1024];
02589    int len, chunk;
02590    char *s2;
02591    char *last;
02592    s2 = alloca(strlen(s) + 100);
02593    if (!s2) {
02594       ast_log(LOG_WARNING, "Alloca failed!\n");
02595       return -1;
02596    }
02597    last = strrchr(s, '/');
02598    if (last)
02599       last++;
02600    else
02601       last = s;
02602    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02603    res = stat(s, &stbuf);
02604    if (res < 0) {
02605       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02606       return -1;
02607    }
02608    /* Make sure it's not a directory */
02609    if (S_ISDIR(stbuf.st_mode))
02610       return -1;
02611    ifd = open(s, O_RDONLY);
02612    if (ifd < 0) {
02613       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02614       return -1;
02615    }
02616    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
02617    if (fd < 0) {
02618       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02619       close(ifd);
02620       return -1;
02621    }
02622    /* Unlink our newly created file */
02623    unlink(s2);
02624    
02625    /* Now copy the firmware into it */
02626    len = stbuf.st_size;
02627    while(len) {
02628       chunk = len;
02629       if (chunk > sizeof(buf))
02630          chunk = sizeof(buf);
02631       res = read(ifd, buf, chunk);
02632       if (res != chunk) {
02633          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02634          close(ifd);
02635          close(fd);
02636          return -1;
02637       }
02638       res = write(fd, buf, chunk);
02639       if (res != chunk) {
02640          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02641          close(ifd);
02642          close(fd);
02643          return -1;
02644       }
02645       len -= chunk;
02646    }
02647    close(ifd);
02648    /* Return to the beginning */
02649    lseek(fd, 0, SEEK_SET);
02650    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02651       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02652       close(fd);
02653       return -1;
02654    }
02655    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02656       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02657       close(fd);
02658       return -1;
02659    }
02660    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02661       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02662       close(fd);
02663       return -1;
02664    }
02665    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02666       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02667       close(fd);
02668       return -1;
02669    }
02670    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
02671    if (fwh == MAP_FAILED) {
02672       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02673       close(fd);
02674       return -1;
02675    }
02676    MD5Init(&md5);
02677    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02678    MD5Final(sum, &md5);
02679    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02680       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02681       munmap((void*)fwh, stbuf.st_size);
02682       close(fd);
02683       return -1;
02684    }
02685    cur = waresl.wares;
02686    while(cur) {
02687       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02688          /* Found a candidate */
02689          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02690             /* The version we have on loaded is older, load this one instead */
02691             break;
02692          /* This version is no newer than what we have.  Don't worry about it.
02693             We'll consider it a proper load anyhow though */
02694          munmap((void*)fwh, stbuf.st_size);
02695          close(fd);
02696          return 0;
02697       }
02698       cur = cur->next;
02699    }
02700    if (!cur) {
02701       /* Allocate a new one and link it */
02702       if ((cur = ast_calloc(1, sizeof(*cur)))) {
02703          cur->fd = -1;
02704          cur->next = waresl.wares;
02705          waresl.wares = cur;
02706       }
02707    }
02708    if (cur) {
02709       if (cur->fwh) {
02710          munmap((void*)cur->fwh, cur->mmaplen);
02711       }
02712       if (cur->fd > -1)
02713          close(cur->fd);
02714       cur->fwh = fwh;
02715       cur->fd = fd;
02716       cur->mmaplen = stbuf.st_size;
02717       cur->dead = 0;
02718    }
02719    return 0;
02720 }

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

Definition at line 6993 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.

Referenced by socket_process().

06994 {
06995    int newcall = 0;
06996    char newip[256];
06997    struct iax_ie_data ied;
06998    struct sockaddr_in new;
06999    
07000    
07001    memset(&ied, 0, sizeof(ied));
07002    if (ies->apparent_addr)
07003       bcopy(ies->apparent_addr, &new, sizeof(new));
07004    if (ies->callno)
07005       newcall = ies->callno;
07006    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07007       ast_log(LOG_WARNING, "Invalid transfer request\n");
07008       return -1;
07009    }
07010    pvt->transfercallno = newcall;
07011    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07012    inet_aton(newip, &pvt->transfer.sin_addr);
07013    pvt->transfer.sin_family = AF_INET;
07014    pvt->transferring = TRANSFER_BEGIN;
07015    pvt->transferid = ies->transferid;
07016    store_by_transfercallno(pvt);
07017    if (ies->transferid)
07018       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07019    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07020    return 0;
07021 }

static int uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1203 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

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

01204 {
01205    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01206    if (csub & IAX_FLAG_SC_LOG) {
01207       /* special case for 'compressed' -1 */
01208       if (csub == 0xff)
01209          return -1;
01210       else
01211          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01212    }
01213    else
01214       return csub;
01215 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 7277 of file chan_iax2.c.

References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), iax2_peer::pokeexpire, and sched.

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

07278 {
07279    if (peer->expire > -1) {
07280       if (!ast_sched_del(sched, peer->expire)) {
07281          peer->expire = -1;
07282          peer_unref(peer);
07283       }
07284    }
07285 
07286    if (peer->pokeexpire > -1) {
07287       if (!ast_sched_del(sched, peer->pokeexpire)) {
07288          peer->pokeexpire = -1;
07289          peer_unref(peer);
07290       }
07291    }
07292 
07293    ao2_unlink(peers, peer);
07294 }

static int unload_module ( void   )  [static]

Definition at line 12468 of file chan_iax2.c.

References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.

12469 {
12470    ast_custom_function_unregister(&iaxpeer_function);
12471    return __unload_module();
12472 }

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

Definition at line 4624 of file chan_iax2.c.

References ast_mutex_unlock(), and iaxsl.

Referenced by iax2_bridge().

04625 {
04626    ast_mutex_unlock(&iaxsl[callno1]);
04627    ast_mutex_unlock(&iaxsl[callno0]);
04628 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

Definition at line 3360 of file chan_iax2.c.

References iax_frame::af, AST_FRAME_VIDEO, ast_log(), iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.

Referenced by schedule_delivery().

03361 {
03362    /* Video mini frames only encode the lower 15 bits of the session
03363     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
03364    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03365    const int lower_mask = (1 << ts_shift) - 1;
03366    const int upper_mask = ~lower_mask;
03367    const int last_upper = iaxs[fr->callno]->last & upper_mask;
03368 
03369    if ( (fr->ts & upper_mask) == last_upper ) {
03370       const int x = fr->ts - iaxs[fr->callno]->last;
03371       const int threshold = (ts_shift == 15) ? 25000 : 50000;
03372 
03373       if (x < -threshold) {
03374          /* Sudden big jump backwards in timestamp:
03375             What likely happened here is that miniframe timestamp has circled but we haven't
03376             gotten the update from the main packet.  We'll just pretend that we did, and
03377             update the timestamp appropriately. */
03378          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03379          if (option_debug && iaxdebug)
03380             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
03381       } else if (x > threshold) {
03382          /* Sudden apparent big jump forwards in timestamp:
03383             What's likely happened is this is an old miniframe belonging to the previous
03384             top 15 or 16-bit timestamp that has turned up out of order.
03385             Adjust the timestamp appropriately. */
03386          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03387          if (option_debug && iaxdebug)
03388             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
03389       }
03390    }
03391 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 3395 of file chan_iax2.c.

References AST_SCHED_DEL, ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.

Referenced by __get_from_jb(), and schedule_delivery().

03396 {
03397    int when;
03398    
03399    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03400    
03401    when = jb_next(pvt->jb) - when;
03402 
03403    AST_SCHED_DEL(sched, pvt->jbid);
03404 
03405    if(when <= 0) {
03406       /* XXX should really just empty until when > 0.. */
03407       when = 1;
03408    }
03409    
03410    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
03411 }

static void update_max_nontrunk ( void   )  [static]

Definition at line 1640 of file chan_iax2.c.

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

Referenced by __find_callno(), and make_trunk().

01641 {
01642    int max = 1;
01643    int x;
01644    /* XXX Prolly don't need locks here XXX */
01645    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01646       if (iaxs[x])
01647          max = x + 1;
01648    }
01649    maxnontrunkcall = max;
01650    if (option_debug && iaxdebug)
01651       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01652 }

static void update_max_trunk ( void   )  [static]

Definition at line 1406 of file chan_iax2.c.

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

Referenced by iax2_destroy(), and make_trunk().

01407 {
01408    int max = TRUNK_CALL_START;
01409    int x;
01410 
01411    /* XXX Prolly don't need locks here XXX */
01412    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01413       if (iaxs[x]) {
01414          max = x + 1;
01415       }
01416    }
01417 
01418    maxtrunkcall = max;
01419    if (option_debug && iaxdebug)
01420       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01421 }

static int update_packet ( struct iax_frame f  )  [static]

Definition at line 2960 of file chan_iax2.c.

References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.

Referenced by __attempt_transmit().

02961 {
02962    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02963    struct ast_iax2_full_hdr *fh = f->data;
02964    struct ast_frame af;
02965 
02966    /* if frame is encrypted. decrypt before updating it. */
02967    if (f->encmethods) {
02968       decode_frame(&f->mydcx, fh, &af, &f->datalen);
02969    }
02970    /* Mark this as a retransmission */
02971    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02972    /* Update iseqno */
02973    f->iseqno = iaxs[f->callno]->iseqno;
02974    fh->iseqno = f->iseqno;
02975 
02976    /* Now re-encrypt the frame */
02977    if (f->encmethods) {
02978    /* since this is a retransmit frame, create a new random padding
02979     * before re-encrypting. */
02980       build_rand_pad(f->semirand, sizeof(f->semirand));
02981       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02982    }
02983    return 0;
02984 }

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

Precondition:
iaxsl[callno] is locked
Note:
Since this function calls send_command_final(), the pvt struct for the given call number may disappear while executing this function.

Definition at line 7390 of file chan_iax2.c.

References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), iax2_peer::cid_name, iax2_peer::cid_num, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_peer::mailbox, manager_event(), iax2_peer::maxcallno, iax2_peer::name, option_verbose, peer_ref(), peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, VERBOSE_PREFIX_3, and iax2_peer::zonetag.

Referenced by socket_process().

07391 {
07392    /* Called from IAX thread only, with proper iaxsl lock */
07393    struct iax_ie_data ied;
07394    struct iax2_peer *p;
07395    int msgcount;
07396    char data[80];
07397    int version;
07398    const char *peer_name;
07399    int res = -1;
07400 
07401    memset(&ied, 0, sizeof(ied));
07402 
07403    peer_name = ast_strdupa(iaxs[callno]->peer);
07404 
07405    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
07406    ast_mutex_unlock(&iaxsl[callno]);
07407    if (!(p = find_peer(peer_name, 1))) {
07408       ast_mutex_lock(&iaxsl[callno]);
07409       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07410       return -1;
07411    }
07412    ast_mutex_lock(&iaxsl[callno]);
07413    if (!iaxs[callno])
07414       goto return_unref;
07415 
07416    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07417       if (sin->sin_addr.s_addr) {
07418          time_t nowtime;
07419          time(&nowtime);
07420          realtime_update_peer(peer_name, sin, nowtime);
07421       } else {
07422          realtime_update_peer(peer_name, sin, 0);
07423       }
07424    }
07425    if (inaddrcmp(&p->addr, sin)) {
07426       if (iax2_regfunk)
07427          iax2_regfunk(p->name, 1);
07428 
07429       /* modify entry in peercnts table as _not_ registered */
07430       peercnt_modify(0, 0, &p->addr);
07431 
07432       /* Stash the IP address from which they registered */
07433       memcpy(&p->addr, sin, sizeof(p->addr));
07434 
07435       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07436       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07437          ast_db_put("IAX/Registry", p->name, data);
07438          if  (option_verbose > 2)
07439             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
07440                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07441          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07442          register_peer_exten(p, 1);
07443          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07444       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07445          if  (option_verbose > 2)
07446             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
07447                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07448          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07449          register_peer_exten(p, 0);
07450          ast_db_del("IAX/Registry", p->name);
07451          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07452       }
07453       /* Update the host */
07454       /* Verify that the host is really there */
07455       iax2_poke_peer(p, callno);
07456    }
07457 
07458    /* modify entry in peercnts table as registered */
07459    if (p->maxcallno) {
07460       peercnt_modify(1, p->maxcallno, &p->addr);
07461    }
07462 
07463    /* Make sure our call still exists, an INVAL at the right point may make it go away */
07464    if (!iaxs[callno]) {
07465       res = -1;
07466       goto return_unref;
07467    }
07468 
07469    /* Store socket fd */
07470    p->sockfd = fd;
07471    /* Setup the expiry */
07472    if (p->expire > -1) {
07473       if (!ast_sched_del(sched, p->expire)) {
07474          p->expire = -1;
07475          peer_unref(p);
07476       }
07477    }
07478    /* treat an unspecified refresh interval as the minimum */
07479    if (!refresh)
07480       refresh = min_reg_expire;
07481    if (refresh > max_reg_expire) {
07482       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07483          p->name, max_reg_expire, refresh);
07484       p->expiry = max_reg_expire;
07485    } else if (refresh < min_reg_expire) {
07486       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07487          p->name, min_reg_expire, refresh);
07488       p->expiry = min_reg_expire;
07489    } else {
07490       p->expiry = refresh;
07491    }
07492    if (p->expiry && sin->sin_addr.s_addr) {
07493       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07494       if (p->expire == -1)
07495          peer_unref(p);
07496    }
07497    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07498    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07499    if (sin->sin_addr.s_addr) {
07500       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07501       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07502       if (!ast_strlen_zero(p->mailbox)) {
07503          int new, old;
07504          ast_app_inboxcount(p->mailbox, &new, &old);
07505          if (new > 255)
07506             new = 255;
07507          if (old > 255)
07508             old = 255;
07509          msgcount = (old << 8) | new;
07510          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07511       }
07512       if (ast_test_flag(p, IAX_HASCALLERID)) {
07513          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07514          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07515       }
07516    }
07517    version = iax_check_version(devtype);
07518    if (version) 
07519       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07520 
07521    res = 0;
07522 
07523 return_unref:
07524    peer_unref(p);
07525 
07526    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07527 }

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

Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1250 of file chan_iax2.c.

References iax2_user::name.

Referenced by load_objects().

01251 {
01252    struct iax2_user *user = obj, *user2 = arg;
01253 
01254    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01255 }

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

Definition at line 11136 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

11137 {
11138    struct iax2_user *user = obj;
11139 
11140    ast_set_flag(user, IAX_DELME);
11141 
11142    return 0;
11143 }

static void user_destructor ( void *  obj  )  [static]

Definition at line 10885 of file chan_iax2.c.

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

Referenced by build_user().

10886 {
10887    struct iax2_user *user = obj;
10888 
10889    ast_free_ha(user->ha);
10890    free_context(user->contexts);
10891    if(user->vars) {
10892       ast_variables_destroy(user->vars);
10893       user->vars = NULL;
10894    }
10895    ast_string_field_free_memory(user);
10896 }

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

Note:
The only member of the user passed here guaranteed to be set is the name field

Definition at line 1240 of file chan_iax2.c.

References ast_str_hash(), and iax2_user::name.

Referenced by load_objects().

01241 {
01242    const struct iax2_user *user = obj;
01243 
01244    return ast_str_hash(user->name);
01245 }

static struct iax2_user* user_ref ( struct iax2_user user  )  [inline, static]

Definition at line 1298 of file chan_iax2.c.

References ao2_ref().

01299 {
01300    ao2_ref(user, +1);
01301    return user;
01302 }

static struct iax2_user* user_unref ( struct iax2_user user  )  [inline, static]

Definition at line 1304 of file chan_iax2.c.

References ao2_ref().

Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), iax2_destroy_helper(), iax2_prune_realtime(), iax2_show_users(), prune_users(), requirecalltoken_mark_auto(), and set_config().

01305 {
01306    ao2_ref(user, -1);
01307    return NULL;
01308 }

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

Definition at line 7726 of file chan_iax2.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, iax_frame::list, ast_iax2_queue::queue, and send_packet().

Referenced by socket_process().

07727 {
07728    struct iax_frame *f;
07729 
07730    AST_LIST_LOCK(&iaxq.queue);
07731    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
07732       /* Send a copy immediately */
07733       if ((f->callno == callno) && iaxs[f->callno] &&
07734          ((unsigned char ) (f->oseqno - last) < 128) &&
07735          (f->retries >= 0)) {
07736          send_packet(f);
07737       }
07738    }
07739    AST_LIST_UNLOCK(&iaxq.queue);
07740 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

Definition at line 4522 of file chan_iax2.c.

References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.

Referenced by iax2_indicate(), and iax2_setoption().

04523 {
04524    unsigned short callno = pvt->callno;
04525 
04526    if (!pvt->peercallno) {
04527       /* We don't know the remote side's call number, yet.  :( */
04528       int count = 10;
04529       while (count-- && pvt && !pvt->peercallno) {
04530          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04531          pvt = iaxs[callno];
04532       }
04533       if (!pvt->peercallno) {
04534          return -1;
04535       }
04536    }
04537 
04538    return 0;
04539 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 12686 of file chan_iax2.c.

char accountcode[AST_MAX_ACCOUNT_CODE] [static]

Definition at line 216 of file chan_iax2.c.

Referenced by __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), dahdi_new(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().

int adsi = 0 [static]

Definition at line 220 of file chan_iax2.c.

Referenced by build_gateway().

int amaflags = 0 [static]

Definition at line 219 of file chan_iax2.c.

Referenced by build_device(), and build_gateway().

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 12686 of file chan_iax2.c.

int authdebug = 1 [static]

Definition at line 155 of file chan_iax2.c.

int autokill = 0 [static]

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

Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().

struct ao2_container* callno_pool [static]

table of available call numbers

Definition at line 661 of file chan_iax2.c.

Referenced by __unload_module(), create_callno_pools(), get_unused_callno(), load_objects(), and replace_callno().

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 666 of file chan_iax2.c.

Referenced by create_callno_pools().

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 664 of file chan_iax2.c.

Referenced by __unload_module(), create_callno_pools(), get_unused_callno(), load_objects(), and replace_callno().

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 704 of file chan_iax2.c.

Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().

struct ast_cli_entry cli_iax2[] [static]

Definition at line 12274 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_cli_entry cli_iax2_jb_debug_deprecated [static]

Initial value:

 {
   { "iax2", "jb", "debug", NULL },
   iax2_do_jb_debug, NULL,
   NULL }

Definition at line 12254 of file chan_iax2.c.

struct ast_cli_entry cli_iax2_no_debug_deprecated [static]

Initial value:

 {
   { "iax2", "no", "debug", NULL },
   iax2_no_debug, NULL,
   NULL }

Definition at line 12259 of file chan_iax2.c.

struct ast_cli_entry cli_iax2_no_jb_debug_deprecated [static]

Initial value:

 {
   { "iax2", "no", "jb", "debug", NULL },
   iax2_no_jb_debug, NULL,
   NULL }

Definition at line 12269 of file chan_iax2.c.

struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated [static]

Initial value:

 {
   { "iax2", "no", "trunk", "debug", NULL },
   iax2_no_trunk_debug, NULL,
   NULL }

Definition at line 12264 of file chan_iax2.c.

struct ast_cli_entry cli_iax2_trunk_debug_deprecated [static]

Initial value:

 {
   { "iax2", "trunk", "debug", NULL },
   iax2_do_trunk_debug, NULL,
   NULL }

Definition at line 12249 of file chan_iax2.c.

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

Definition at line 142 of file chan_iax2.c.

char debug_jb_usage[] [static]

Initial value:

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

Definition at line 12223 of file chan_iax2.c.

char debug_trunk_usage[] [static]

Initial value:

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

Definition at line 12215 of file chan_iax2.c.

char debug_usage[] [static]

Initial value:

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

Definition at line 12207 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static]

Definition at line 706 of file chan_iax2.c.

Referenced by set_config().

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 708 of file chan_iax2.c.

Referenced by set_config().

int defaultsockfd = -1 [static]

Definition at line 173 of file chan_iax2.c.

int delayreject = 0 [static]

Definition at line 221 of file chan_iax2.c.

struct iax2_dpcache * dpcache [static]

Referenced by find_cache(), and iax2_show_cache().

ast_mutex_t dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 782 of file chan_iax2.c.

Referenced by complete_dpreply(), find_cache(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), iax2_show_cache(), and socket_process().

uint16_t global_maxcallno [static]

Definition at line 710 of file chan_iax2.c.

Referenced by set_config(), and set_peercnt_limit().

uint16_t global_maxcallno_nonval [static]

Total num of call numbers allowed to be allocated without calltoken validation

Definition at line 713 of file chan_iax2.c.

Referenced by get_unused_callno(), iax2_show_callnumber_usage(), and set_config().

int global_rtautoclear = 120 [static]

Definition at line 274 of file chan_iax2.c.

struct ast_flags globalflags = { 0 } [static]

Definition at line 224 of file chan_iax2.c.

Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().

int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]

Definition at line 202 of file chan_iax2.c.

int iax2_encryption = 0 [static]

Definition at line 222 of file chan_iax2.c.

enum { ... } iax2_flags

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

Definition at line 175 of file chan_iax2.c.

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

enum { ... } iax2_state

struct ast_switch iax2_switch [static]

Definition at line 12135 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]

Definition at line 973 of file chan_iax2.c.

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

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

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().

struct ao2_container* iax_transfercallno_pvts [static]

Another container of iax2_pvt structures.

*

Active IAX2 pvt stucts used during transfering a call are stored here.

Definition at line 924 of file chan_iax2.c.

Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().

int iaxactivethreadcount = 0 [static]

Definition at line 471 of file chan_iax2.c.

Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().

int iaxcompat = 0 [static]

Definition at line 157 of file chan_iax2.c.

int iaxdebug = 0 [static]

Definition at line 204 of file chan_iax2.c.

int iaxdefaultdpcache = 10 * 60 [static]

Definition at line 160 of file chan_iax2.c.

int iaxdefaulttimeout = 5 [static]

Definition at line 162 of file chan_iax2.c.

int iaxdynamicthreadcount = 0 [static]

Definition at line 469 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 470 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 468 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

struct ast_custom_function iaxpeer_function

Definition at line 12071 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct ast_iax2_queue iaxq [static]

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

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static]

Definition at line 905 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_frame_subclass2str(), iax_showframe(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), vnak_retransmit(), and wait_for_peercallno().

ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static]

Definition at line 906 of file chan_iax2.c.

Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), iax2_bridge(), iax2_call(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), update_registry(), and wait_for_peercallno().

int iaxthreadcount = DEFAULT_THREAD_COUNT [static]

Definition at line 467 of file chan_iax2.c.

Referenced by iax2_show_threads(), set_config(), and start_network_thread().

int iaxtrunkdebug = 0 [static]

Definition at line 206 of file chan_iax2.c.

struct io_context* io [static]

Definition at line 199 of file chan_iax2.c.

int lagrq_time = 10 [static]

Definition at line 150 of file chan_iax2.c.

char language[MAX_LANGUAGE] = "" [static]

Definition at line 144 of file chan_iax2.c.

int last_authmethod = 0 [static]

Definition at line 158 of file chan_iax2.c.

const time_t MAX_CALLTOKEN_DELAY = 10 [static]

Definition at line 675 of file chan_iax2.c.

int max_reg_expire [static]

Definition at line 167 of file chan_iax2.c.

int max_retries = 4 [static]

Definition at line 148 of file chan_iax2.c.

int maxauthreq = 3 [static]

Definition at line 147 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]

Definition at line 151 of file chan_iax2.c.

int maxjitterinterps = 10 [static]

Definition at line 153 of file chan_iax2.c.

int maxnontrunkcall = 1 [static]

Definition at line 931 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 930 of file chan_iax2.c.

int min_reg_expire [static]

Definition at line 166 of file chan_iax2.c.

char mohinterpret[MAX_MUSICCLASS] [static]

Definition at line 217 of file chan_iax2.c.

char mohsuggest[MAX_MUSICCLASS] [static]

Definition at line 218 of file chan_iax2.c.

Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().

struct ast_netsock_list* netsock [static]

Definition at line 171 of file chan_iax2.c.

Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().

pthread_t netthreadid = AST_PTHREADT_NULL [static]

Definition at line 226 of file chan_iax2.c.

char no_debug_jb_usage[] [static]

Initial value:

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

Definition at line 12227 of file chan_iax2.c.

char no_debug_trunk_usage[] [static]

Initial value:

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

Definition at line 12219 of file chan_iax2.c.

char no_debug_usage[] [static]

Initial value:

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

Definition at line 12211 of file chan_iax2.c.

struct ast_netsock_list* outsock [static]

used if sourceaddress specified and bindaddr == INADDR_ANY

Definition at line 172 of file chan_iax2.c.

Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().

char* papp = "IAX2Provision" [static]

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

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

Definition at line 698 of file chan_iax2.c.

Referenced by __unload_module(), iax2_show_callnumber_usage(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().

struct ao2_container* peers [static]

Definition at line 691 of file chan_iax2.c.

int ping_time = 21 [static]

Definition at line 149 of file chan_iax2.c.

struct ast_codec_pref prefs [static]

Definition at line 138 of file chan_iax2.c.

Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().

char prune_realtime_usage[] [static]

Initial value:

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

Definition at line 12161 of file chan_iax2.c.

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

Definition at line 10103 of file chan_iax2.c.

int randomcalltokendata [static]

Definition at line 673 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]

Definition at line 145 of file chan_iax2.c.

int resyncthreshold = 1000 [static]

Definition at line 152 of file chan_iax2.c.

struct sched_context* sched [static]

Definition at line 200 of file chan_iax2.c.

ast_cond_t sched_cond [static]

Definition at line 229 of file chan_iax2.c.

ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 228 of file chan_iax2.c.

Referenced by __unload_module(), iax2_sched_add(), iax2_transmit(), and sched_thread().

pthread_t schedthreadid = AST_PTHREADT_NULL [static]

Definition at line 227 of file chan_iax2.c.

char show_cache_usage[] [static]

Initial value:

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

Definition at line 12149 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 12157 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 12181 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 12199 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 12185 of file chan_iax2.c.

char show_peer_usage[] [static]

Initial value:

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

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

char show_prov_usage[] [static]

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

char show_stats_usage[] [static]

Initial value:

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

Definition at line 12145 of file chan_iax2.c.

char show_threads_usage[] [static]

Initial value:

 
"Usage: iax2 show threads\n"
"       Lists status of IAX helper threads\n"

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

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

Definition at line 140 of file chan_iax2.c.

int test_losspct = 0 [static]

Definition at line 208 of file chan_iax2.c.

int timingfd = -1 [static]

Definition at line 169 of file chan_iax2.c.

unsigned int tos = 0 [static]

Definition at line 164 of file chan_iax2.c.

uint16_t total_nonval_callno_used = 0 [static]

Definition at line 715 of file chan_iax2.c.

Referenced by get_unused_callno(), iax2_show_callnumber_usage(), and replace_callno().

ast_mutex_t tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 397 of file chan_iax2.c.

Referenced by find_tpeer(), and timing_read().

struct iax2_trunk_peer * tpeers [static]

Referenced by find_tpeer(), and timing_read().

int trunkfreq = 20 [static]

Definition at line 154 of file chan_iax2.c.

struct ao2_container* users [static]

Definition at line 694 of file chan_iax2.c.

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


Generated on Wed Oct 14 15:02:09 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7