Sun Aug 15 20:33:35 2010

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  chan_iax2_pvt::signaling_queue
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
struct  signaling_queue_entry

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), IAX_SHRINKCALLERID = (1 << 27)
}
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 void free_signaling_queue_entry (struct signaling_queue_entry *s)
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 queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f)
 All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
static int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
static struct iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
static void realtime_update_peer (const char *peername, struct 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 void send_signaling (struct chan_iax2_pvt *pvt)
 This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int set_config (const char *config_file, int reload)
 Load configuration.
static void set_config_destroy (void)
static void set_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 768 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 764 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 778 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 766 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 770 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 772 of file chan_iax2.c.

Referenced by find_cache(), and iax2_show_cache().

#define CACHE_FLAG_TRANSMITTED   (1 << 5)

Request transmitted

Definition at line 774 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 776 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 457 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 378 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 800 of file chan_iax2.c.

Referenced by socket_read().

#define IAX_IOSTATE_PROCESSING   2

Definition at line 802 of file chan_iax2.c.

#define IAX_IOSTATE_READY   1

Definition at line 801 of file chan_iax2.c.

Referenced by socket_read().

#define IAX_IOSTATE_SCHEDREADY   3

Definition at line 803 of file chan_iax2.c.

Referenced by __schedule_action().

#define IAX_TYPE_DYNAMIC   2

Definition at line 806 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 805 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 466 of file chan_iax2.c.

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

#define MAX_JITTER_BUFFER   50

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

Referenced by load_objects(), and set_config().

#define MAX_RETRY_TIME   10000

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

#define MAX_TRUNKDATA   640 * 200

40ms, uncompressed linear * 200 channels

Definition at line 458 of file chan_iax2.c.

Referenced by iax2_trunk_queue(), and timing_read().

#define MAX_USER_BUCKETS   MAX_PEER_BUCKETS

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

#define MIN_RETRY_TIME   100

Definition at line 451 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 1101 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 939 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 463 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?
IAX_SHRINKCALLERID  Turn on and off caller id shrinking

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    IAX_SHRINKCALLERID  = (1 << 27),   /*!< Turn on and off caller id shrinking */
00273 } iax2_flags;

anonymous enum

Enumerator:
NEW_PREVENT 
NEW_ALLOW 
NEW_FORCE 
NEW_ALLOW_CALLTOKEN_VALIDATED 

Definition at line 1673 of file chan_iax2.c.

01673      {
01674    /* do not allow a new call number, only search ones in use for match */
01675    NEW_PREVENT = 0,
01676    /* search for match first, then allow a new one to be allocated */
01677    NEW_ALLOW = 1,
01678    /* do not search for match, force a new call number */
01679    NEW_FORCE = 2,
01680    /* do not search for match, force a new call number.  Signifies call number
01681     * has been calltoken validated */
01682    NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01683 };

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

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

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


Function Documentation

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

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

03058 {
03059    /* Attempt to transmit the frame to the remote peer...
03060       Called without iaxsl held. */
03061    struct iax_frame *f = (struct iax_frame *)data;
03062    int freeme=0;
03063    int callno = f->callno;
03064    /* Make sure this call is still active */
03065    if (callno) 
03066       ast_mutex_lock(&iaxsl[callno]);
03067    if (callno && iaxs[callno]) {
03068       if ((f->retries < 0) /* Already ACK'd */ ||
03069           (f->retries >= max_retries) /* Too many attempts */) {
03070             /* Record an error if we've transmitted too many times */
03071             if (f->retries >= max_retries) {
03072                if (f->transfer) {
03073                   /* Transfer timeout */
03074                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03075                } else if (f->final) {
03076                   if (f->final) 
03077                      iax2_destroy(callno);
03078                } else {
03079                   if (iaxs[callno]->owner)
03080                      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);
03081                   iaxs[callno]->error = ETIMEDOUT;
03082                   if (iaxs[callno]->owner) {
03083                      struct ast_frame fr = { 0, };
03084                      /* Hangup the fd */
03085                      fr.frametype = AST_FRAME_CONTROL;
03086                      fr.subclass = AST_CONTROL_HANGUP;
03087                      iax2_queue_frame(callno, &fr); // XXX
03088                      /* Remember, owner could disappear */
03089                      if (iaxs[callno] && iaxs[callno]->owner)
03090                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03091                   } else {
03092                      if (iaxs[callno]->reg) {
03093                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03094                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03095                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03096                      }
03097                      iax2_destroy(callno);
03098                   }
03099                }
03100 
03101             }
03102             freeme++;
03103       } else {
03104          /* Update it if it needs it */
03105          update_packet(f);
03106          /* Attempt transmission */
03107          send_packet(f);
03108          f->retries++;
03109          /* Try again later after 10 times as long */
03110          f->retrytime *= 10;
03111          if (f->retrytime > MAX_RETRY_TIME)
03112             f->retrytime = MAX_RETRY_TIME;
03113          /* Transfer messages max out at one second */
03114          if (f->transfer && (f->retrytime > 1000))
03115             f->retrytime = 1000;
03116          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03117       }
03118    } else {
03119       /* Make sure it gets freed */
03120       f->retries = -1;
03121       freeme++;
03122    }
03123    if (callno)
03124       ast_mutex_unlock(&iaxsl[callno]);
03125    /* Do not try again */
03126    if (freeme) {
03127       /* Don't attempt delivery, just remove it from the queue */
03128       AST_LIST_LOCK(&iaxq.queue);
03129       AST_LIST_REMOVE(&iaxq.queue, f, list);
03130       iaxq.count--;
03131       AST_LIST_UNLOCK(&iaxq.queue);
03132       f->retrans = -1; /* this is safe because this is the scheduled function */
03133       /* Free the IAX frame */
03134       iax2_frame_free(f);
03135    }
03136 }

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

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

07712 {
07713    /* Called from IAX thread only, without iaxs lock */
07714    int callno = (int)(long)(nothing);
07715    struct iax_ie_data ied;
07716    ast_mutex_lock(&iaxsl[callno]);
07717    if (iaxs[callno]) {
07718       memset(&ied, 0, sizeof(ied));
07719       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07720          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07721          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07722       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07723          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07724          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07725       }
07726       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07727    }
07728    ast_mutex_unlock(&iaxsl[callno]);
07729 }

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

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

04043 {
04044    int callno = PTR_TO_CALLNO(nothing);
04045    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
04046    ast_mutex_lock(&iaxsl[callno]);
04047    if (iaxs[callno]) {
04048       iaxs[callno]->initid = -1;
04049       iax2_queue_frame(callno, &f);
04050       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04051    }
04052    ast_mutex_unlock(&iaxsl[callno]);
04053 }

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

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

07761 {
07762    /* Called from IAX thread only, without iaxs lock */
07763    int callno = (int)(long)(nothing);
07764    struct iax_ie_data ied;
07765    ast_mutex_lock(&iaxsl[callno]);
07766    if (iaxs[callno]) {
07767       memset(&ied, 0, sizeof(ied));
07768       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07769       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07770       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07771    }
07772    ast_mutex_unlock(&iaxsl[callno]);
07773 }

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

02911 {
02912    /* Just deliver the packet by using queueing.  This is called by
02913      the IAX thread with the iaxsl lock held. */
02914    struct iax_frame *fr = data;
02915    fr->retrans = -1;
02916    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02917    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02918       iax2_queue_frame(fr->callno, &fr->af);
02919    /* Free our iax frame */
02920    iax2_frame_free(fr);
02921    /* And don't run again */
02922    return 0;
02923 }

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

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

07378 {
07379    struct iax2_peer *peer = (struct iax2_peer *) data;
07380 
07381    if (!peer)
07382       return;
07383 
07384    peer->expire = -1;
07385 
07386    if (option_debug)
07387       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
07388    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07389       realtime_update_peer(peer->name, &peer->addr, 0);
07390    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07391    /* modify entry in peercnts table as _not_ registered */
07392    peercnt_modify(0, 0, &peer->addr);
07393    /* Reset the address */
07394    memset(&peer->addr, 0, sizeof(peer->addr));
07395    /* Reset expiry value */
07396    peer->expiry = min_reg_expire;
07397    if (!ast_test_flag(peer, IAX_TEMPONLY))
07398       ast_db_del("IAX/Registry", peer->name);
07399    register_peer_exten(peer, 0);
07400    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07401    if (iax2_regfunk)
07402       iax2_regfunk(peer->name, 0);
07403 
07404    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07405       unlink_peer(peer);
07406 
07407    peer_unref(peer);
07408 }

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

02370 {
02371    int res = 0;
02372    int x;
02373    /* this call is calltoken validated as long as it is either NEW_FORCE
02374     * or NEW_ALLOW_CALLTOKEN_VALIDATED */
02375    int validated = (new > NEW_ALLOW) ? 1 : 0;
02376    char host[80];
02377 
02378    if (new <= NEW_ALLOW) {
02379       if (callno) {
02380          struct chan_iax2_pvt *pvt;
02381          struct chan_iax2_pvt tmp_pvt = {
02382             .callno = dcallno,
02383             .peercallno = callno,
02384             .transfercallno = callno,
02385             /* hack!! */
02386             .frames_received = check_dcallno,
02387          };
02388 
02389          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02390          /* this works for finding normal call numbers not involving transfering */ 
02391          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02392             if (return_locked) {
02393                ast_mutex_lock(&iaxsl[pvt->callno]);
02394             }
02395             res = pvt->callno;
02396             ao2_ref(pvt, -1);
02397             pvt = NULL;
02398             return res;
02399          }
02400          /* this searches for transfer call numbers that might not get caught otherwise */
02401          memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02402          memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02403          if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02404             if (return_locked) {
02405                ast_mutex_lock(&iaxsl[pvt->callno]);
02406             }
02407             res = pvt->callno;
02408             ao2_ref(pvt, -1);
02409             pvt = NULL;
02410             return res;
02411          }
02412       }
02413       /* This will occur on the first response to a message that we initiated,
02414        * such as a PING. */
02415       if (dcallno) {
02416          ast_mutex_lock(&iaxsl[dcallno]);
02417       }
02418       if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02419          iaxs[dcallno]->peercallno = callno;
02420          res = dcallno;
02421          store_by_peercallno(iaxs[dcallno]);
02422          if (!res || !return_locked) {
02423             ast_mutex_unlock(&iaxsl[dcallno]);
02424          }
02425          return res;
02426       }
02427       if (dcallno) {
02428          ast_mutex_unlock(&iaxsl[dcallno]);
02429       }
02430 #ifdef IAX_OLD_FIND
02431       /* If we get here, we SHOULD NOT find a call structure for this
02432          callno; if we do, it means that there is a call structure that
02433          has a peer callno but did NOT get entered into the hash table,
02434          which is bad.
02435 
02436          If we find a call structure using this old, slow method, output a log
02437          message so we'll know about it. After a few months of leaving this in
02438          place, if we don't hear about people seeing these messages, we can
02439          remove this code for good.
02440       */
02441 
02442       for (x = 1; !res && x < maxnontrunkcall; x++) {
02443          ast_mutex_lock(&iaxsl[x]);
02444          if (iaxs[x]) {
02445             /* Look for an exact match */
02446             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02447                res = x;
02448             }
02449          }
02450          if (!res || !return_locked)
02451             ast_mutex_unlock(&iaxsl[x]);
02452       }
02453 
02454       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02455          ast_mutex_lock(&iaxsl[x]);
02456          if (iaxs[x]) {
02457             /* Look for an exact match */
02458             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02459                res = x;
02460             }
02461          }
02462          if (!res || !return_locked)
02463             ast_mutex_unlock(&iaxsl[x]);
02464       }
02465 
02466       if (res) {
02467          ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
02468       }
02469 #endif
02470    }
02471    if (!res && (new >= NEW_ALLOW)) {
02472       struct callno_entry *callno_entry;
02473       /* It may seem odd that we look through the peer list for a name for
02474        * this *incoming* call.  Well, it is weird.  However, users don't
02475        * have an IP address/port number that we can match against.  So,
02476        * this is just checking for a peer that has that IP/port and
02477        * assuming that we have a user of the same name.  This isn't always
02478        * correct, but it will be changed if needed after authentication. */
02479       if (!iax2_getpeername(*sin, host, sizeof(host)))
02480          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02481 
02482       if (peercnt_add(sin)) {
02483          /* This address has hit its callnumber limit.  When the limit
02484           * is reached, the connection is not added to the peercnts table.*/
02485          return 0;
02486       }
02487 
02488       if (!(callno_entry = get_unused_callno(0, validated))) {
02489          /* since we ran out of space, remove the peercnt
02490           * entry we added earlier */
02491          peercnt_remove_by_addr(sin);
02492          ast_log(LOG_WARNING, "No more space\n");
02493          return 0;
02494       }
02495       x = callno_entry->callno;
02496       ast_mutex_lock(&iaxsl[x]);
02497 
02498       iaxs[x] = new_iax(sin, host);
02499       update_max_nontrunk();
02500       if (iaxs[x]) {
02501          if (option_debug && iaxdebug)
02502             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
02503          iaxs[x]->callno_entry = callno_entry;
02504          iaxs[x]->sockfd = sockfd;
02505          iaxs[x]->addr.sin_port = sin->sin_port;
02506          iaxs[x]->addr.sin_family = sin->sin_family;
02507          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02508          iaxs[x]->peercallno = callno;
02509          iaxs[x]->callno = x;
02510          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02511          iaxs[x]->expiry = min_reg_expire;
02512          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02513          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02514          iaxs[x]->amaflags = amaflags;
02515          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02516          
02517          ast_string_field_set(iaxs[x], accountcode, accountcode);
02518          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02519          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02520 
02521          if (iaxs[x]->peercallno) {
02522             store_by_peercallno(iaxs[x]);
02523          }
02524       } else {
02525          ast_log(LOG_WARNING, "Out of resources\n");
02526          ast_mutex_unlock(&iaxsl[x]);
02527          replace_callno(callno_entry);
02528          return 0;
02529       }
02530       if (!return_locked)
02531          ast_mutex_unlock(&iaxsl[x]);
02532       res = x;
02533    }
02534    return res;
02535 }

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

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

03485 {
03486    int callno = PTR_TO_CALLNO(p);
03487    struct chan_iax2_pvt *pvt = NULL;
03488    struct iax_frame *fr;
03489    jb_frame frame;
03490    int ret;
03491    long now;
03492    long next;
03493    struct timeval tv;
03494    
03495    /* Make sure we have a valid private structure before going on */
03496    ast_mutex_lock(&iaxsl[callno]);
03497    pvt = iaxs[callno];
03498    if (!pvt) {
03499       /* No go! */
03500       ast_mutex_unlock(&iaxsl[callno]);
03501       return;
03502    }
03503 
03504    pvt->jbid = -1;
03505    
03506    gettimeofday(&tv,NULL);
03507    /* round up a millisecond since ast_sched_runq does; */
03508    /* prevents us from spinning while waiting for our now */
03509    /* to catch up with runq's now */
03510    tv.tv_usec += 1000;
03511    
03512    now = ast_tvdiff_ms(tv, pvt->rxcore);
03513    
03514    if(now >= (next = jb_next(pvt->jb))) {
03515       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
03516       switch(ret) {
03517       case JB_OK:
03518          fr = frame.data;
03519          __do_deliver(fr);
03520          /* __do_deliver() can cause the call to disappear */
03521          pvt = iaxs[callno];
03522          break;
03523       case JB_INTERP:
03524       {
03525          struct ast_frame af = { 0, };
03526          
03527          /* create an interpolation frame */
03528          af.frametype = AST_FRAME_VOICE;
03529          af.subclass = pvt->voiceformat;
03530          af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
03531          af.src  = "IAX2 JB interpolation";
03532          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03533          af.offset = AST_FRIENDLY_OFFSET;
03534          
03535          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
03536           * which we'd need to malloc, and then it would free it.  That seems like a drag */
03537          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03538             iax2_queue_frame(callno, &af);
03539             /* iax2_queue_frame() could cause the call to disappear */
03540             pvt = iaxs[callno];
03541          }
03542       }
03543          break;
03544       case JB_DROP:
03545          iax2_frame_free(frame.data);
03546          break;
03547       case JB_NOFRAME:
03548       case JB_EMPTY:
03549          /* do nothing */
03550          break;
03551       default:
03552          /* shouldn't happen */
03553          break;
03554       }
03555    }
03556    if (pvt)
03557       update_jbsched(pvt);
03558    ast_mutex_unlock(&iaxsl[callno]);
03559 }

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

Definition at line 7058 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

07059 {
07060    struct iax2_registry *reg = (struct iax2_registry *)data;
07061    reg->expire = -1;
07062    iax2_do_register(reg);
07063 }

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

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

10270 {
10271    struct iax2_peer *peer = (struct iax2_peer *)data;
10272    int callno;
10273 
10274    if (peer->lastms > -1) {
10275       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10276       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10277       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
10278    }
10279    if ((callno = peer->callno) > 0) {
10280       ast_mutex_lock(&iaxsl[callno]);
10281       iax2_destroy(callno);
10282       ast_mutex_unlock(&iaxsl[callno]);
10283    }
10284    peer->callno = 0;
10285    peer->lastms = -1;
10286    /* Try again quickly */
10287    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10288    if (peer->pokeexpire == -1)
10289       peer_unref(peer);
10290 }

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

Definition at line 7823 of file chan_iax2.c.

References iax2_poke_peer(), and peer_unref().

Referenced by iax2_poke_peer_s().

07824 {
07825    struct iax2_peer *peer = (struct iax2_peer *)data;
07826    iax2_poke_peer(peer, 0);
07827    peer_unref(peer);
07828 }

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

Definition at line 5780 of file chan_iax2.c.

References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_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(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and iax2_peer::username.

Referenced by iax2_show_peers(), and manager_iax2_show_peers().

05781 {
05782    regex_t regexbuf;
05783    int havepattern = 0;
05784    int total_peers = 0;
05785    int online_peers = 0;
05786    int offline_peers = 0;
05787    int unmonitored_peers = 0;
05788    struct ao2_iterator i;
05789 
05790 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
05791 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
05792 
05793    struct iax2_peer *peer = NULL;
05794    char name[256];
05795    int registeredonly=0;
05796    char *term = manager ? "\r\n" : "\n";
05797 
05798    switch (argc) {
05799    case 6:
05800       if (!strcasecmp(argv[3], "registered"))
05801          registeredonly = 1;
05802       else
05803          return RESULT_SHOWUSAGE;
05804       if (!strcasecmp(argv[4], "like")) {
05805          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05806             return RESULT_SHOWUSAGE;
05807          havepattern = 1;
05808       } else
05809          return RESULT_SHOWUSAGE;
05810       break;
05811    case 5:
05812       if (!strcasecmp(argv[3], "like")) {
05813          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05814             return RESULT_SHOWUSAGE;
05815          havepattern = 1;
05816       } else
05817          return RESULT_SHOWUSAGE;
05818       break;
05819    case 4:
05820       if (!strcasecmp(argv[3], "registered"))
05821          registeredonly = 1;
05822       else
05823          return RESULT_SHOWUSAGE;
05824       break;
05825    case 3:
05826       break;
05827    default:
05828       return RESULT_SHOWUSAGE;
05829    }
05830 
05831 
05832    if (s)
05833       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
05834    else
05835       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
05836 
05837    i = ao2_iterator_init(peers, 0);
05838    for (peer = ao2_iterator_next(&i); peer; 
05839       peer_unref(peer), peer = ao2_iterator_next(&i)) {
05840       char nm[20];
05841       char status[20];
05842       char srch[2000];
05843       int retstatus;
05844 
05845       if (registeredonly && !peer->addr.sin_addr.s_addr)
05846          continue;
05847       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
05848          continue;
05849 
05850       if (!ast_strlen_zero(peer->username))
05851          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05852       else
05853          ast_copy_string(name, peer->name, sizeof(name));
05854       
05855       retstatus = peer_status(peer, status, sizeof(status));
05856       if (retstatus > 0)
05857          online_peers++;
05858       else if (!retstatus)
05859          offline_peers++;
05860       else
05861          unmonitored_peers++;
05862       
05863       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05864       
05865       snprintf(srch, sizeof(srch), FORMAT, name, 
05866           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05867           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05868           nm,
05869           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05870           peer->encmethods ? "(E)" : "   ", status, term);
05871       
05872       if (s)
05873          astman_append(s, FORMAT, name, 
05874                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
05875                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05876                   nm,
05877                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05878                   peer->encmethods ? "(E)" : "   ", status, term);
05879       else
05880          ast_cli(fd, FORMAT, name, 
05881             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05882             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05883             nm,
05884             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
05885             peer->encmethods ? "(E)" : "   ", status, term);
05886       total_peers++;
05887    }
05888    ao2_iterator_destroy(&i);
05889 
05890    if (s)
05891       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05892    else
05893       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05894 
05895    if (havepattern)
05896       regfree(&regexbuf);
05897 
05898    return RESULT_SUCCESS;
05899 #undef FORMAT
05900 #undef FORMAT2
05901 }

static void __reg_module ( void   )  [static]

Definition at line 12802 of file chan_iax2.c.

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

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

01077 {
01078    struct iax2_thread *thread = NULL;
01079    static time_t lasterror;
01080    static time_t t;
01081 
01082    thread = find_idle_thread();
01083 
01084    if (thread != NULL) {
01085       thread->schedfunc = func;
01086       thread->scheddata = data;
01087       thread->iostate = IAX_IOSTATE_SCHEDREADY;
01088 #ifdef DEBUG_SCHED_MULTITHREAD
01089       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01090 #endif
01091       signal_condition(&thread->lock, &thread->cond);
01092       return 0;
01093    }
01094    time(&t);
01095    if (t != lasterror && option_debug) 
01096       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
01097    lasterror = t;
01098 
01099    return -1;
01100 }

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

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

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

06308 {
06309    struct ast_frame f = { 0, };
06310    int res = 0;
06311    f.frametype = type;
06312    f.subclass = command;
06313    f.datalen = datalen;
06314    f.src = __FUNCTION__;
06315    f.data = (void *) data;
06316 
06317    if ((res = queue_signalling(i, &f)) <= 0) {
06318       return res;
06319    }
06320    return iax2_send(i, &f, ts, seqno, now, transfer, final);
06321 }

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

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

01164 {
01165    int callno = (long) data;
01166 
01167    ast_mutex_lock(&iaxsl[callno]);
01168 
01169    if (iaxs[callno]) {
01170       if (iaxs[callno]->peercallno) {
01171          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01172          iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01173       } else {
01174          /* I am the schedule, so I'm allowed to do this */
01175          iaxs[callno]->lagid = -1;
01176       }
01177    } else {
01178       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);
01179    }
01180 
01181    ast_mutex_unlock(&iaxsl[callno]);
01182 }

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

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

01119 {
01120    int callno = (long) data;
01121 
01122    ast_mutex_lock(&iaxsl[callno]);
01123 
01124    if (iaxs[callno]) {
01125       if (iaxs[callno]->peercallno) {
01126          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01127          iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01128       } else {
01129          /* I am the schedule, so I'm allowed to do this */
01130          iaxs[callno]->pingid = -1;
01131       }
01132    } else if (option_debug > 0) {
01133       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);
01134    }
01135 
01136    ast_mutex_unlock(&iaxsl[callno]);
01137 }

static int __unload_module ( void   )  [static]

Definition at line 12490 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, 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, peers, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, users, and waresl.

12491 {
12492    struct iax2_thread *thread = NULL;
12493    int x;
12494 
12495    /* Make sure threads do not hold shared resources when they are canceled */
12496    
12497    /* Grab the sched lock resource to keep it away from threads about to die */
12498    /* Cancel the network thread, close the net socket */
12499    if (netthreadid != AST_PTHREADT_NULL) {
12500       AST_LIST_LOCK(&iaxq.queue);
12501       ast_mutex_lock(&sched_lock);
12502       pthread_cancel(netthreadid);
12503       ast_cond_signal(&sched_cond);
12504       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
12505       AST_LIST_UNLOCK(&iaxq.queue);
12506       pthread_join(netthreadid, NULL);
12507    }
12508    if (schedthreadid != AST_PTHREADT_NULL) {
12509       ast_mutex_lock(&sched_lock);  
12510       pthread_cancel(schedthreadid);
12511       ast_cond_signal(&sched_cond);
12512       ast_mutex_unlock(&sched_lock);   
12513       pthread_join(schedthreadid, NULL);
12514    }
12515    
12516    /* Call for all threads to halt */
12517    AST_LIST_LOCK(&idle_list);
12518    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
12519       AST_LIST_REMOVE_CURRENT(&idle_list, list);
12520       pthread_cancel(thread->threadid);
12521    }
12522    AST_LIST_TRAVERSE_SAFE_END
12523    AST_LIST_UNLOCK(&idle_list);
12524 
12525    AST_LIST_LOCK(&active_list);
12526    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
12527       AST_LIST_REMOVE_CURRENT(&active_list, list);
12528       pthread_cancel(thread->threadid);
12529    }
12530    AST_LIST_TRAVERSE_SAFE_END
12531    AST_LIST_UNLOCK(&active_list);
12532 
12533    AST_LIST_LOCK(&dynamic_list);
12534         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
12535       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
12536       pthread_cancel(thread->threadid);
12537         }
12538    AST_LIST_TRAVERSE_SAFE_END
12539         AST_LIST_UNLOCK(&dynamic_list);
12540 
12541    AST_LIST_HEAD_DESTROY(&iaxq.queue);
12542 
12543    /* Wait for threads to exit */
12544    while(0 < iaxactivethreadcount)
12545       usleep(10000);
12546    
12547    ast_netsock_release(netsock);
12548    ast_netsock_release(outsock);
12549    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12550       if (iaxs[x]) {
12551          iax2_destroy(x);
12552       }
12553    }
12554    ast_manager_unregister( "IAXpeers" );
12555    ast_manager_unregister( "IAXnetstats" );
12556    ast_unregister_application(papp);
12557    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12558    ast_unregister_switch(&iax2_switch);
12559    ast_channel_unregister(&iax2_tech);
12560    delete_users();
12561    iax_provision_unload();
12562    sched_context_destroy(sched);
12563    reload_firmware(1);
12564 
12565    ast_mutex_destroy(&waresl.lock);
12566 
12567    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12568       ast_mutex_destroy(&iaxsl[x]);
12569    }
12570 
12571    ao2_ref(peers, -1);
12572    ao2_ref(users, -1);
12573    ao2_ref(iax_peercallno_pvts, -1);
12574    ao2_ref(iax_transfercallno_pvts, -1);  
12575    ao2_ref(peercnts, -1);
12576    ao2_ref(callno_limits, -1);
12577    ao2_ref(calltoken_ignores, -1);
12578    ao2_ref(callno_pool, -1);
12579    ao2_ref(callno_pool_trunk, -1);
12580 
12581    return 0;
12582 }

static void __unreg_module ( void   )  [static]

Definition at line 12802 of file chan_iax2.c.

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

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

02137 {
02138    struct addr_range tmp;
02139    struct addr_range *addr_range = NULL;
02140    struct ast_ha *ha = NULL;
02141 
02142    if (ast_strlen_zero(addr)) {
02143       ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02144       return -1;
02145    }
02146 
02147    ha = ast_append_ha("permit", addr, NULL);
02148 
02149    /* check for valid config information */
02150    if (!ha) {
02151       ast_log(LOG_WARNING, "Error creating calltokenoptional entry %s\n", addr);
02152       return -1;
02153    }
02154 
02155    ast_copy_ha(ha, &tmp.ha);
02156    /* find or create the addr_range */
02157    if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02158       ao2_lock(addr_range);
02159       addr_range->delme = 0;
02160       ao2_unlock(addr_range);
02161    } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02162       /* copy over config data into addr_range object */
02163       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */
02164       ao2_link(calltoken_ignores, addr_range);
02165    } else {
02166       ast_free_ha(ha);
02167       return -1;
02168    }
02169 
02170    ast_free_ha(ha);
02171    ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02172 
02173    return 0;
02174 }

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

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

04121 {
04122    /* first make sure their are two empty bytes left in ied->buf */
04123    if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04124       ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;  /* type */
04125       ied->buf[ied->pos++] = 0;   /* data size,  ZERO in this case */
04126       pvt->calltoken_ie_len = 2;
04127    }
04128 }

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

Definition at line 1790 of file chan_iax2.c.

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

Referenced by load_objects().

01791 {
01792    struct addr_range *lim1 = obj, *lim2 = arg;
01793    return ((lim1->ha.netaddr.s_addr == lim2->ha.netaddr.s_addr) &&
01794       (lim1->ha.netmask.s_addr == lim2->ha.netmask.s_addr)) ?
01795       CMP_MATCH | CMP_STOP : 0;
01796 }

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

Definition at line 1777 of file chan_iax2.c.

References addr_range::delme.

Referenced by set_config_destroy().

01778 {
01779    struct addr_range *lim = obj;
01780    lim->delme = 1;
01781    return 0;
01782 }

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

Definition at line 1784 of file chan_iax2.c.

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

Referenced by load_objects().

01785 {
01786    const struct addr_range *lim = obj;
01787    return abs((int) lim->ha.netaddr.s_addr);
01788 }

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

Definition at line 1810 of file chan_iax2.c.

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

Referenced by calltoken_required(), and set_peercnt_limit().

01811 {
01812    struct addr_range *addr_range = obj;
01813    struct sockaddr_in *sin = arg;
01814 
01815    if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) {
01816       return CMP_MATCH | CMP_STOP;
01817    }
01818    return 0;
01819 }

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

Definition at line 6362 of file chan_iax2.c.

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

Referenced by check_access().

06363 {
06364    while(con) {
06365       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
06366          return -1;
06367       con = con->next;
06368    }
06369    return 0;
06370 }

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

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

06123 {
06124    int x;
06125    int numchans = 0;
06126    char first_message[10] = { 0, };
06127    char last_message[10] = { 0, };
06128    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06129       ast_mutex_lock(&iaxsl[x]);
06130       if (iaxs[x]) {
06131          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
06132          char *fmt;
06133          jb_info jbinfo;
06134 
06135          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06136             jb_getinfo(iaxs[x]->jb, &jbinfo);
06137             localjitter = jbinfo.jitter;
06138             localdelay = jbinfo.current - jbinfo.min;
06139             locallost = jbinfo.frames_lost;
06140             locallosspct = jbinfo.losspct/1000;
06141             localdropped = jbinfo.frames_dropped;
06142             localooo = jbinfo.frames_ooo;
06143          } else {
06144             localjitter = -1;
06145             localdelay = 0;
06146             locallost = -1;
06147             locallosspct = -1;
06148             localdropped = 0;
06149             localooo = -1;
06150          }
06151          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06152          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06153          if (limit_fmt)
06154             fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n";
06155          else
06156             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n";
06157          if (s)
06158 
06159             astman_append(s, fmt,
06160                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06161                      iaxs[x]->pingtime,
06162                      localjitter,
06163                      localdelay,
06164                      locallost,
06165                      locallosspct,
06166                      localdropped,
06167                      localooo,
06168                      iaxs[x]->frames_received/1000,
06169                      iaxs[x]->remote_rr.jitter,
06170                      iaxs[x]->remote_rr.delay,
06171                      iaxs[x]->remote_rr.losscnt,
06172                      iaxs[x]->remote_rr.losspct,
06173                      iaxs[x]->remote_rr.dropped,
06174                      iaxs[x]->remote_rr.ooo,
06175                      iaxs[x]->remote_rr.packets/1000,
06176                           (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06177                     first_message,
06178                     (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06179                     last_message);
06180          else
06181             ast_cli(fd, fmt,
06182                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06183                iaxs[x]->pingtime,
06184                localjitter,
06185                localdelay,
06186                locallost,
06187                locallosspct,
06188                localdropped,
06189                localooo,
06190                iaxs[x]->frames_received/1000,
06191                iaxs[x]->remote_rr.jitter,
06192                iaxs[x]->remote_rr.delay,
06193                iaxs[x]->remote_rr.losscnt,
06194                iaxs[x]->remote_rr.losspct,
06195                iaxs[x]->remote_rr.dropped,
06196                iaxs[x]->remote_rr.ooo,
06197                iaxs[x]->remote_rr.packets/1000,
06198                (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06199                first_message,
06200                (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06201                last_message);
06202          numchans++;
06203       }
06204       ast_mutex_unlock(&iaxsl[x]);
06205    }
06206    return numchans;
06207 }

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

04946 {
04947    struct ast_channel *tmp;
04948    struct chan_iax2_pvt *i;
04949    struct ast_variable *v = NULL;
04950 
04951    if (!(i = iaxs[callno])) {
04952       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04953       return NULL;
04954    }
04955 
04956    /* Don't hold call lock */
04957    ast_mutex_unlock(&iaxsl[callno]);
04958    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);
04959    ast_mutex_lock(&iaxsl[callno]);
04960    if (i != iaxs[callno]) {
04961       if (tmp) {
04962          /* unlock and relock iaxsl[callno] to preserve locking order */
04963          ast_mutex_unlock(&iaxsl[callno]);
04964          ast_channel_free(tmp);
04965          ast_mutex_lock(&iaxsl[callno]);
04966       }
04967       return NULL;
04968    }
04969 
04970    if (!tmp)
04971       return NULL;
04972    tmp->tech = &iax2_tech;
04973    /* We can support any format by default, until we get restricted */
04974    tmp->nativeformats = capability;
04975    tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04976    tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04977    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04978 
04979    /* Don't use ast_set_callerid() here because it will
04980     * generate a NewCallerID event before the NewChannel event */
04981    if (!ast_strlen_zero(i->ani))
04982       tmp->cid.cid_ani = ast_strdup(i->ani);
04983    else
04984       tmp->cid.cid_ani = ast_strdup(i->cid_num);
04985    tmp->cid.cid_dnid = ast_strdup(i->dnid);
04986    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04987    tmp->cid.cid_pres = i->calling_pres;
04988    tmp->cid.cid_ton = i->calling_ton;
04989    tmp->cid.cid_tns = i->calling_tns;
04990    if (!ast_strlen_zero(i->language))
04991       ast_string_field_set(tmp, language, i->language);
04992    if (!ast_strlen_zero(i->accountcode))
04993       ast_string_field_set(tmp, accountcode, i->accountcode);
04994    if (i->amaflags)
04995       tmp->amaflags = i->amaflags;
04996    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04997    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04998    if (i->adsi)
04999       tmp->adsicpe = i->peeradsicpe;
05000    else
05001       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05002    i->owner = tmp;
05003    i->capability = capability;
05004 
05005    for (v = i->vars ; v ; v = v->next)
05006       pbx_builtin_setvar_helper(tmp, v->name, v->value);
05007 
05008    if (state != AST_STATE_DOWN) {
05009       if (ast_pbx_start(tmp)) {
05010          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05011          ast_hangup(tmp);
05012          i->owner = NULL;
05013          return NULL;
05014       }
05015    }
05016 
05017    ast_module_ref(ast_module_info->self);
05018    
05019    return tmp;
05020 }

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

Definition at line 3138 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and network_thread().

03139 {
03140 #ifdef SCHED_MULTITHREADED
03141    if (schedule_action(__attempt_transmit, data))
03142 #endif      
03143       __attempt_transmit(data);
03144    return 0;
03145 }

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

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

07746 {
07747    /* Schedule sending the authentication failure in one second, to prevent
07748       guessing */
07749    if (iaxs[callno]) {
07750       iaxs[callno]->authfail = failcode;
07751       if (delayreject) {
07752          AST_SCHED_DEL(sched, iaxs[callno]->authid);
07753          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
07754       } else
07755          auth_reject((void *)(long)callno);
07756    }
07757    return 0;
07758 }

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

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

07732 {
07733    int callno = (int)(long)(data);
07734    ast_mutex_lock(&iaxsl[callno]);
07735    if (iaxs[callno])
07736       iaxs[callno]->authid = -1;
07737    ast_mutex_unlock(&iaxsl[callno]);
07738 #ifdef SCHED_MULTITHREADED
07739    if (schedule_action(__auth_reject, data))
07740 #endif      
07741       __auth_reject(data);
07742    return 0;
07743 }

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

06926 {
06927    int res = -1;
06928    int x;
06929    if (!ast_strlen_zero(keyn)) {
06930       if (!(authmethods & IAX_AUTH_RSA)) {
06931          if (ast_strlen_zero(secret)) 
06932             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));
06933       } else if (ast_strlen_zero(challenge)) {
06934          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06935       } else {
06936          char sig[256];
06937          struct ast_key *key;
06938          key = ast_key_get(keyn, AST_KEY_PRIVATE);
06939          if (!key) {
06940             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06941          } else {
06942             if (ast_sign(key, (char*)challenge, sig)) {
06943                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06944                res = -1;
06945             } else {
06946                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06947                res = 0;
06948             }
06949          }
06950       }
06951    } 
06952    /* Fall back */
06953    if (res && !ast_strlen_zero(secret)) {
06954       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06955          struct MD5Context md5;
06956          unsigned char digest[16];
06957          char digres[128];
06958          MD5Init(&md5);
06959          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06960          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06961          MD5Final(digest, &md5);
06962          /* If they support md5, authenticate with it.  */
06963          for (x=0;x<16;x++)
06964             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
06965          if (pvt) {
06966             build_encryption_keys(digest, pvt);
06967          }
06968          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06969          res = 0;
06970       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06971          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06972          res = 0;
06973       } else
06974          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06975    }
06976    return res;
06977 }

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

References iax2_peer::addr, ao2_iterator_destroy(), 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(), peers, realtime_peer(), iax2_peer::secret, send_command(), and iax2_peer::username.

Referenced by socket_process().

06984 {
06985    struct iax2_peer *peer = NULL;
06986    /* Start pessimistic */
06987    int res = -1;
06988    int authmethods = 0;
06989    struct iax_ie_data ied;
06990    uint16_t callno = p->callno;
06991 
06992    memset(&ied, 0, sizeof(ied));
06993    
06994    if (ies->username)
06995       ast_string_field_set(p, username, ies->username);
06996    if (ies->challenge)
06997       ast_string_field_set(p, challenge, ies->challenge);
06998    if (ies->authmethods)
06999       authmethods = ies->authmethods;
07000    if (authmethods & IAX_AUTH_MD5)
07001       merge_encryption(p, ies->encmethods);
07002    else
07003       p->encmethods = 0;
07004 
07005    /* Check for override RSA authentication first */
07006    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
07007       /* Normal password authentication */
07008       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
07009    } else {
07010       struct ao2_iterator i = ao2_iterator_init(peers, 0);
07011       while ((peer = ao2_iterator_next(&i))) {
07012          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
07013              /* No peer specified at our end, or this is the peer */
07014              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
07015              /* No username specified in peer rule, or this is the right username */
07016              && (!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)))
07017              /* No specified host, or this is our host */
07018             ) {
07019             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
07020             if (!res) {
07021                peer_unref(peer);
07022                break;
07023             }
07024          }
07025          peer_unref(peer);
07026       }
07027       ao2_iterator_destroy(&i);
07028       if (!peer) {
07029          /* We checked our list and didn't find one.  It's unlikely, but possible, 
07030             that we're trying to authenticate *to* a realtime peer */
07031          const char *peer_name = ast_strdupa(p->peer);
07032          ast_mutex_unlock(&iaxsl[callno]);
07033          if ((peer = realtime_peer(peer_name, NULL))) {
07034             ast_mutex_lock(&iaxsl[callno]);
07035             if (!(p = iaxs[callno])) {
07036                peer_unref(peer);
07037                return -1;
07038             }
07039             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
07040             peer_unref(peer);
07041          }
07042          if (!peer) {
07043             ast_mutex_lock(&iaxsl[callno]);
07044             if (!(p = iaxs[callno]))
07045                return -1;
07046          }
07047       }
07048    }
07049    if (ies->encmethods)
07050       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
07051    if (!res)
07052       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
07053    return res;
07054 }

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 6634 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(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

06635 {
06636    struct iax_ie_data ied;
06637    int res = -1, authreq_restrict = 0;
06638    char challenge[10];
06639    struct chan_iax2_pvt *p = iaxs[call_num];
06640 
06641    memset(&ied, 0, sizeof(ied));
06642 
06643    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
06644    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06645       struct iax2_user *user, tmp_user = {
06646          .name = p->username, 
06647       };
06648 
06649       user = ao2_find(users, &tmp_user, OBJ_POINTER);
06650       if (user) {
06651          if (user->curauthreq == user->maxauthreq)
06652             authreq_restrict = 1;
06653          else
06654             user->curauthreq++;
06655          user = user_unref(user);
06656       }
06657    }
06658 
06659    /* If the AUTHREQ limit test failed, send back an error */
06660    if (authreq_restrict) {
06661       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06662       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06663       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06664       return 0;
06665    }
06666 
06667    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06668    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06669       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06670       ast_string_field_set(p, challenge, challenge);
06671       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
06672       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06673    }
06674    if (p->encmethods)
06675       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06676 
06677    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06678 
06679    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06680 
06681    if (p->encmethods)
06682       ast_set_flag(p, IAX_ENCRYPTED);
06683 
06684    return res;
06685 }

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

Definition at line 6687 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(), chan_iax2_pvt::username, and users.

Referenced by socket_process().

06688 {
06689    char requeststr[256];
06690    char md5secret[256] = "";
06691    char secret[256] = "";
06692    char rsasecret[256] = "";
06693    int res = -1; 
06694    int x;
06695    struct iax2_user *user, tmp_user = {
06696       .name = p->username, 
06697    };
06698 
06699    if (p->authrej) {
06700       return res;
06701    }
06702    user = ao2_find(users, &tmp_user, OBJ_POINTER);
06703    if (user) {
06704       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06705          ast_atomic_fetchadd_int(&user->curauthreq, -1);
06706          ast_clear_flag(p, IAX_MAXAUTHREQ);
06707       }
06708       ast_string_field_set(p, host, user->name);
06709       user = user_unref(user);
06710    }
06711 
06712    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06713       return res;
06714    if (ies->password)
06715       ast_copy_string(secret, ies->password, sizeof(secret));
06716    if (ies->md5_result)
06717       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06718    if (ies->rsa_result)
06719       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06720    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06721       struct ast_key *key;
06722       char *keyn;
06723       char tmpkey[256];
06724       char *stringp=NULL;
06725       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06726       stringp=tmpkey;
06727       keyn = strsep(&stringp, ":");
06728       while(keyn) {
06729          key = ast_key_get(keyn, AST_KEY_PUBLIC);
06730          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06731             res = 0;
06732             break;
06733          } else if (!key)
06734             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06735          keyn = strsep(&stringp, ":");
06736       }
06737    } else if (p->authmethods & IAX_AUTH_MD5) {
06738       struct MD5Context md5;
06739       unsigned char digest[16];
06740       char *tmppw, *stringp;
06741       
06742       tmppw = ast_strdupa(p->secret);
06743       stringp = tmppw;
06744       while((tmppw = strsep(&stringp, ";"))) {
06745          MD5Init(&md5);
06746          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06747          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06748          MD5Final(digest, &md5);
06749          /* If they support md5, authenticate with it.  */
06750          for (x=0;x<16;x++)
06751             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06752          if (!strcasecmp(requeststr, md5secret)) {
06753             res = 0;
06754             break;
06755          }
06756       }
06757    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06758       if (!strcmp(secret, p->secret))
06759          res = 0;
06760    }
06761    return res;
06762 }

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

Definition at line 4055 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call(), and sip_call().

04056 {
04057 #ifdef SCHED_MULTITHREADED
04058    if (schedule_action(__auto_congest, data))
04059 #endif      
04060       __auto_congest(data);
04061    return 0;
04062 }

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

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

07776 {
07777    int callno = (int)(long)(data);
07778    ast_mutex_lock(&iaxsl[callno]);
07779    if (iaxs[callno]) {
07780       iaxs[callno]->autoid = -1;
07781    }
07782    ast_mutex_unlock(&iaxsl[callno]);
07783 #ifdef SCHED_MULTITHREADED
07784    if (schedule_action(__auto_hangup, data))
07785 #endif      
07786       __auto_hangup(data);
07787    return 0;
07788 }

static void build_callno_limits ( struct ast_variable v  )  [static]

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

02084 {
02085    struct addr_range *addr_range = NULL;
02086    struct addr_range tmp;
02087    struct ast_ha *ha;
02088    int limit;
02089    int found;
02090 
02091    for (; v; v = v->next) {
02092       limit = -1;
02093       found = 0;
02094       ha = ast_append_ha("permit", v->name, NULL);
02095 
02096       /* check for valid config information */
02097       if (!ha) {
02098          ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02099          continue;
02100       } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02101          ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02102          ast_free_ha(ha);
02103          continue;
02104       }
02105 
02106       ast_copy_ha(ha, &tmp.ha);
02107       /* find or create the addr_range */
02108       if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02109          ao2_lock(addr_range);
02110          found = 1;
02111       } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02112          ast_free_ha(ha);
02113          return; /* out of memory */
02114       }
02115 
02116       /* copy over config data into addr_range object */
02117       ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */
02118       ast_free_ha(ha); /* cleanup the tmp ha */
02119       addr_range->limit = limit;
02120       addr_range->delme = 0;
02121 
02122       /* cleanup */
02123       if (found) {
02124          ao2_unlock(addr_range);
02125       } else {
02126          ao2_link(callno_limits, addr_range);
02127       }
02128       ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */
02129    }
02130 }

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

Definition at line 10602 of file chan_iax2.c.

References ast_calloc, and ast_copy_string().

Referenced by build_user().

10603 {
10604    struct iax2_context *con;
10605 
10606    if ((con = ast_calloc(1, sizeof(*con))))
10607       ast_copy_string(con->context, context, sizeof(con->context));
10608    
10609    return con;
10610 }

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

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

05350 {
05351    /* it is required to hold the corresponding decrypt key to our encrypt key
05352     * in the pvt struct because queued frames occasionally need to be decrypted and
05353     * re-encrypted when updated for a retransmission */
05354    build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
05355    aes_encrypt_key128(digest, &pvt->ecx);
05356    aes_decrypt_key128(digest, &pvt->mydcx);
05357 }

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

Definition at line 5343 of file chan_iax2.c.

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

Referenced by authenticate(), and decrypt_frame().

05344 {
05345    build_ecx_key(digest, pvt);
05346    aes_decrypt_key128(digest, &pvt->dcx);
05347 }

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 10749 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, peers, prefs, iax2_peer::regexten, S_OR, sched, secret, unlink_peer(), ast_variable::value, and zonetag.

10750 {
10751    struct iax2_peer *peer = NULL;
10752    struct ast_ha *oldha = NULL;
10753    int maskfound=0;
10754    int found=0;
10755    int firstpass=1;
10756    struct iax2_peer tmp_peer = {
10757       .name = name,
10758    };
10759 
10760    if (!temponly) {
10761       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10762       if (peer && !ast_test_flag(peer, IAX_DELME))
10763          firstpass = 0;
10764    }
10765 
10766    if (peer) {
10767       found++;
10768       if (firstpass) {
10769          oldha = peer->ha;
10770          peer->ha = NULL;
10771       }
10772       unlink_peer(peer);
10773    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10774       peer->expire = -1;
10775       peer->pokeexpire = -1;
10776       peer->sockfd = defaultsockfd;
10777       if (ast_string_field_init(peer, 32))
10778          peer = peer_unref(peer);
10779    }
10780 
10781    if (peer) {
10782       if (firstpass) {
10783          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10784          peer->encmethods = iax2_encryption;
10785          peer->adsi = adsi;
10786          ast_string_field_set(peer,secret,"");
10787          if (!found) {
10788             ast_string_field_set(peer, name, name);
10789             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10790             peer->expiry = min_reg_expire;
10791          }
10792          peer->prefs = prefs;
10793          peer->capability = iax2_capability;
10794          peer->smoothing = 0;
10795          peer->pokefreqok = DEFAULT_FREQ_OK;
10796          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10797          peer->maxcallno = 0;
10798          peercnt_modify(0, 0, &peer->addr);
10799          peer->calltoken_required = CALLTOKEN_DEFAULT;
10800          ast_string_field_set(peer,context,"");
10801          ast_string_field_set(peer,peercontext,"");
10802          ast_clear_flag(peer, IAX_HASCALLERID);
10803          ast_string_field_set(peer, cid_name, "");
10804          ast_string_field_set(peer, cid_num, "");
10805          ast_string_field_set(peer, mohinterpret, mohinterpret);
10806          ast_string_field_set(peer, mohsuggest, mohsuggest);
10807       }
10808 
10809       if (!v) {
10810          v = alt;
10811          alt = NULL;
10812       }
10813       while(v) {
10814          if (!strcasecmp(v->name, "secret")) {
10815             ast_string_field_set(peer, secret, v->value);
10816          } else if (!strcasecmp(v->name, "mailbox")) {
10817             ast_string_field_set(peer, mailbox, v->value);
10818          } else if (!strcasecmp(v->name, "hasvoicemail")) {
10819             if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10820                ast_string_field_set(peer, mailbox, name);
10821             }
10822          } else if (!strcasecmp(v->name, "mohinterpret")) {
10823             ast_string_field_set(peer, mohinterpret, v->value);
10824          } else if (!strcasecmp(v->name, "mohsuggest")) {
10825             ast_string_field_set(peer, mohsuggest, v->value);
10826          } else if (!strcasecmp(v->name, "dbsecret")) {
10827             ast_string_field_set(peer, dbsecret, v->value);
10828          } else if (!strcasecmp(v->name, "trunk")) {
10829             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
10830             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
10831                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
10832                ast_clear_flag(peer, IAX_TRUNK);
10833             }
10834          } else if (!strcasecmp(v->name, "auth")) {
10835             peer->authmethods = get_auth_methods(v->value);
10836          } else if (!strcasecmp(v->name, "encryption")) {
10837             peer->encmethods = get_encrypt_methods(v->value);
10838          } else if (!strcasecmp(v->name, "notransfer")) {
10839             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10840             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
10841             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
10842          } else if (!strcasecmp(v->name, "transfer")) {
10843             if (!strcasecmp(v->value, "mediaonly")) {
10844                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
10845             } else if (ast_true(v->value)) {
10846                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10847             } else 
10848                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10849          } else if (!strcasecmp(v->name, "jitterbuffer")) {
10850             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
10851          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10852             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
10853          } else if (!strcasecmp(v->name, "host")) {
10854             if (!strcasecmp(v->value, "dynamic")) {
10855                /* They'll register with us */
10856                ast_set_flag(peer, IAX_DYNAMIC); 
10857                if (!found) {
10858                   /* Initialize stuff iff we're not found, otherwise
10859                      we keep going with what we had */
10860                   memset(&peer->addr.sin_addr, 0, 4);
10861                   if (peer->addr.sin_port) {
10862                      /* If we've already got a port, make it the default rather than absolute */
10863                      peer->defaddr.sin_port = peer->addr.sin_port;
10864                      peer->addr.sin_port = 0;
10865                   }
10866                }
10867             } else {
10868                /* Non-dynamic.  Make sure we become that way if we're not */
10869                AST_SCHED_DEL(sched, peer->expire);
10870                ast_clear_flag(peer, IAX_DYNAMIC);
10871                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
10872                   return peer_unref(peer);
10873                if (!peer->addr.sin_port)
10874                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10875             }
10876             if (!maskfound)
10877                inet_aton("255.255.255.255", &peer->mask);
10878          } else if (!strcasecmp(v->name, "defaultip")) {
10879             if (ast_get_ip(&peer->defaddr, v->value))
10880                return peer_unref(peer);
10881          } else if (!strcasecmp(v->name, "sourceaddress")) {
10882             peer_set_srcaddr(peer, v->value);
10883          } else if (!strcasecmp(v->name, "permit") ||
10884                   !strcasecmp(v->name, "deny")) {
10885             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
10886          } else if (!strcasecmp(v->name, "mask")) {
10887             maskfound++;
10888             inet_aton(v->value, &peer->mask);
10889          } else if (!strcasecmp(v->name, "context")) {
10890             ast_string_field_set(peer, context, v->value);
10891          } else if (!strcasecmp(v->name, "regexten")) {
10892             ast_string_field_set(peer, regexten, v->value);
10893          } else if (!strcasecmp(v->name, "peercontext")) {
10894             ast_string_field_set(peer, peercontext, v->value);
10895          } else if (!strcasecmp(v->name, "port")) {
10896             if (ast_test_flag(peer, IAX_DYNAMIC))
10897                peer->defaddr.sin_port = htons(atoi(v->value));
10898             else
10899                peer->addr.sin_port = htons(atoi(v->value));
10900          } else if (!strcasecmp(v->name, "username")) {
10901             ast_string_field_set(peer, username, v->value);
10902          } else if (!strcasecmp(v->name, "allow")) {
10903             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10904          } else if (!strcasecmp(v->name, "disallow")) {
10905             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10906          } else if (!strcasecmp(v->name, "callerid")) {
10907             if (!ast_strlen_zero(v->value)) {
10908                char name2[80];
10909                char num2[80];
10910                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10911                ast_string_field_set(peer, cid_name, name2);
10912                ast_string_field_set(peer, cid_num, num2);
10913             } else {
10914                ast_string_field_set(peer, cid_name, "");
10915                ast_string_field_set(peer, cid_num, "");
10916             }
10917             ast_set_flag(peer, IAX_HASCALLERID);
10918          } else if (!strcasecmp(v->name, "fullname")) {
10919             ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10920             ast_set_flag(peer, IAX_HASCALLERID);
10921          } else if (!strcasecmp(v->name, "cid_number")) {
10922             ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10923             ast_set_flag(peer, IAX_HASCALLERID);
10924          } else if (!strcasecmp(v->name, "sendani")) {
10925             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
10926          } else if (!strcasecmp(v->name, "inkeys")) {
10927             ast_string_field_set(peer, inkeys, v->value);
10928          } else if (!strcasecmp(v->name, "outkey")) {
10929             ast_string_field_set(peer, outkey, v->value);
10930          } else if (!strcasecmp(v->name, "qualify")) {
10931             if (!strcasecmp(v->value, "no")) {
10932                peer->maxms = 0;
10933             } else if (!strcasecmp(v->value, "yes")) {
10934                peer->maxms = DEFAULT_MAXMS;
10935             } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
10936                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);
10937                peer->maxms = 0;
10938             }
10939          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10940             peer->smoothing = ast_true(v->value);
10941          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10942             if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
10943                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);
10944             }
10945          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10946             if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
10947                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);
10948             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10949          } else if (!strcasecmp(v->name, "timezone")) {
10950             ast_string_field_set(peer, zonetag, v->value);
10951          } else if (!strcasecmp(v->name, "adsi")) {
10952             peer->adsi = ast_true(v->value);
10953          } else if (!strcasecmp(v->name, "maxcallnumbers")) {
10954             if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
10955                ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
10956             } else {
10957                peercnt_modify(1, peer->maxcallno, &peer->addr);
10958             }
10959          } else if (!strcasecmp(v->name, "requirecalltoken")) {
10960             /* default is required unless in optional ip list */
10961             if (ast_false(v->value)) {
10962                peer->calltoken_required = CALLTOKEN_NO;
10963             } else if (!strcasecmp(v->value, "auto")) {
10964                peer->calltoken_required = CALLTOKEN_AUTO;
10965             } else if (ast_true(v->value)) {
10966                peer->calltoken_required = CALLTOKEN_YES;
10967             } else {
10968                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
10969             }
10970          } /* else if (strcasecmp(v->name,"type")) */
10971          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10972          v = v->next;
10973          if (!v) {
10974             v = alt;
10975             alt = NULL;
10976          }
10977       }
10978       if (!peer->authmethods)
10979          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10980       ast_clear_flag(peer, IAX_DELME); 
10981       /* Make sure these are IPv4 addresses */
10982       peer->addr.sin_family = AF_INET;
10983    }
10984    if (oldha)
10985       ast_free_ha(oldha);
10986    return peer;
10987 }

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

Definition at line 5333 of file chan_iax2.c.

References ast_random().

Referenced by build_ecx_key(), and update_packet().

05334 {
05335    long tmp;
05336    for (tmp = ast_random(); len > 0; tmp = ast_random()) {
05337       memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
05338       buf += sizeof(tmp);
05339       len -= sizeof(tmp);
05340    }
05341 }

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 11003 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(), users, ast_variable::value, and iax2_user::vars.

11004 {
11005    struct iax2_user *user = NULL;
11006    struct iax2_context *con, *conl = NULL;
11007    struct ast_ha *oldha = NULL;
11008    struct iax2_context *oldcon = NULL;
11009    int format;
11010    int firstpass=1;
11011    int oldcurauthreq = 0;
11012    char *varname = NULL, *varval = NULL;
11013    struct ast_variable *tmpvar = NULL;
11014    struct iax2_user tmp_user = {
11015       .name = name,
11016    };
11017 
11018    if (!temponly) {
11019       user = ao2_find(users, &tmp_user, OBJ_POINTER);
11020       if (user && !ast_test_flag(user, IAX_DELME))
11021          firstpass = 0;
11022    }
11023 
11024    if (user) {
11025       if (firstpass) {
11026          oldcurauthreq = user->curauthreq;
11027          oldha = user->ha;
11028          oldcon = user->contexts;
11029          user->ha = NULL;
11030          user->contexts = NULL;
11031       }
11032       /* Already in the list, remove it and it will be added back (or FREE'd) */
11033       ao2_unlink(users, user);
11034    } else {
11035       user = ao2_alloc(sizeof(*user), user_destructor);
11036    }
11037    
11038    if (user) {
11039       if (firstpass) {
11040          ast_string_field_free_memory(user);
11041          memset(user, 0, sizeof(struct iax2_user));
11042          if (ast_string_field_init(user, 32)) {
11043             user = user_unref(user);
11044             goto cleanup;
11045          }
11046          user->maxauthreq = maxauthreq;
11047          user->curauthreq = oldcurauthreq;
11048          user->prefs = prefs;
11049          user->capability = iax2_capability;
11050          user->encmethods = iax2_encryption;
11051          user->adsi = adsi;
11052          user->calltoken_required = CALLTOKEN_DEFAULT;
11053          ast_string_field_set(user, name, name);
11054          ast_string_field_set(user, language, language);
11055          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
11056          ast_clear_flag(user, IAX_HASCALLERID);
11057          ast_string_field_set(user, cid_name, "");
11058          ast_string_field_set(user, cid_num, "");
11059          ast_string_field_set(user, accountcode, accountcode);
11060          ast_string_field_set(user, mohinterpret, mohinterpret);
11061          ast_string_field_set(user, mohsuggest, mohsuggest);
11062       }
11063       if (!v) {
11064          v = alt;
11065          alt = NULL;
11066       }
11067       while(v) {
11068          if (!strcasecmp(v->name, "context")) {
11069             con = build_context(v->value);
11070             if (con) {
11071                if (conl)
11072                   conl->next = con;
11073                else
11074                   user->contexts = con;
11075                conl = con;
11076             }
11077          } else if (!strcasecmp(v->name, "permit") ||
11078                   !strcasecmp(v->name, "deny")) {
11079             user->ha = ast_append_ha(v->name, v->value, user->ha);
11080          } else if (!strcasecmp(v->name, "setvar")) {
11081             varname = ast_strdupa(v->value);
11082             if (varname && (varval = strchr(varname,'='))) {
11083                *varval = '\0';
11084                varval++;
11085                if((tmpvar = ast_variable_new(varname, varval))) {
11086                   tmpvar->next = user->vars; 
11087                   user->vars = tmpvar;
11088                }
11089             }
11090          } else if (!strcasecmp(v->name, "allow")) {
11091             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
11092          } else if (!strcasecmp(v->name, "disallow")) {
11093             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
11094          } else if (!strcasecmp(v->name, "trunk")) {
11095             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
11096             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
11097                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
11098                ast_clear_flag(user, IAX_TRUNK);
11099             }
11100          } else if (!strcasecmp(v->name, "auth")) {
11101             user->authmethods = get_auth_methods(v->value);
11102          } else if (!strcasecmp(v->name, "encryption")) {
11103             user->encmethods = get_encrypt_methods(v->value);
11104          } else if (!strcasecmp(v->name, "notransfer")) {
11105             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
11106             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
11107             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
11108          } else if (!strcasecmp(v->name, "transfer")) {
11109             if (!strcasecmp(v->value, "mediaonly")) {
11110                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
11111             } else if (ast_true(v->value)) {
11112                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11113             } else 
11114                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11115          } else if (!strcasecmp(v->name, "codecpriority")) {
11116             if(!strcasecmp(v->value, "caller"))
11117                ast_set_flag(user, IAX_CODEC_USER_FIRST);
11118             else if(!strcasecmp(v->value, "disabled"))
11119                ast_set_flag(user, IAX_CODEC_NOPREFS);
11120             else if(!strcasecmp(v->value, "reqonly")) {
11121                ast_set_flag(user, IAX_CODEC_NOCAP);
11122                ast_set_flag(user, IAX_CODEC_NOPREFS);
11123             }
11124          } else if (!strcasecmp(v->name, "jitterbuffer")) {
11125             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
11126          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
11127             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
11128          } else if (!strcasecmp(v->name, "dbsecret")) {
11129             ast_string_field_set(user, dbsecret, v->value);
11130          } else if (!strcasecmp(v->name, "secret")) {
11131             if (!ast_strlen_zero(user->secret)) {
11132                char *old = ast_strdupa(user->secret);
11133 
11134                ast_string_field_build(user, secret, "%s;%s", old, v->value);
11135             } else
11136                ast_string_field_set(user, secret, v->value);
11137          } else if (!strcasecmp(v->name, "callerid")) {
11138             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
11139                char name2[80];
11140                char num2[80];
11141                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
11142                ast_string_field_set(user, cid_name, name2);
11143                ast_string_field_set(user, cid_num, num2);
11144                ast_set_flag(user, IAX_HASCALLERID);
11145             } else {
11146                ast_clear_flag(user, IAX_HASCALLERID);
11147                ast_string_field_set(user, cid_name, "");
11148                ast_string_field_set(user, cid_num, "");
11149             }
11150          } else if (!strcasecmp(v->name, "fullname")) {
11151             if (!ast_strlen_zero(v->value)) {
11152                ast_string_field_set(user, cid_name, v->value);
11153                ast_set_flag(user, IAX_HASCALLERID);
11154             } else {
11155                ast_string_field_set(user, cid_name, "");
11156                if (ast_strlen_zero(user->cid_num))
11157                   ast_clear_flag(user, IAX_HASCALLERID);
11158             }
11159          } else if (!strcasecmp(v->name, "cid_number")) {
11160             if (!ast_strlen_zero(v->value)) {
11161                ast_string_field_set(user, cid_num, v->value);
11162                ast_set_flag(user, IAX_HASCALLERID);
11163             } else {
11164                ast_string_field_set(user, cid_num, "");
11165                if (ast_strlen_zero(user->cid_name))
11166                   ast_clear_flag(user, IAX_HASCALLERID);
11167             }
11168          } else if (!strcasecmp(v->name, "accountcode")) {
11169             ast_string_field_set(user, accountcode, v->value);
11170          } else if (!strcasecmp(v->name, "mohinterpret")) {
11171             ast_string_field_set(user, mohinterpret, v->value);
11172          } else if (!strcasecmp(v->name, "mohsuggest")) {
11173             ast_string_field_set(user, mohsuggest, v->value);
11174          } else if (!strcasecmp(v->name, "language")) {
11175             ast_string_field_set(user, language, v->value);
11176          } else if (!strcasecmp(v->name, "amaflags")) {
11177             format = ast_cdr_amaflags2int(v->value);
11178             if (format < 0) {
11179                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11180             } else {
11181                user->amaflags = format;
11182             }
11183          } else if (!strcasecmp(v->name, "inkeys")) {
11184             ast_string_field_set(user, inkeys, v->value);
11185          } else if (!strcasecmp(v->name, "maxauthreq")) {
11186             user->maxauthreq = atoi(v->value);
11187             if (user->maxauthreq < 0)
11188                user->maxauthreq = 0;
11189          } else if (!strcasecmp(v->name, "adsi")) {
11190             user->adsi = ast_true(v->value);
11191          } else if (!strcasecmp(v->name, "requirecalltoken")) {
11192             /* default is required unless in optional ip list */
11193             if (ast_false(v->value)) {
11194                user->calltoken_required = CALLTOKEN_NO;
11195             } else if (!strcasecmp(v->value, "auto")) {
11196                user->calltoken_required = CALLTOKEN_AUTO;
11197             } else if (ast_true(v->value)) {
11198                user->calltoken_required = CALLTOKEN_YES;
11199             } else {
11200                ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
11201             }
11202          } /* else if (strcasecmp(v->name,"type")) */
11203          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11204          v = v->next;
11205          if (!v) {
11206             v = alt;
11207             alt = NULL;
11208          }
11209       }
11210       if (!user->authmethods) {
11211          if (!ast_strlen_zero(user->secret)) {
11212             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11213             if (!ast_strlen_zero(user->inkeys))
11214                user->authmethods |= IAX_AUTH_RSA;
11215          } else if (!ast_strlen_zero(user->inkeys)) {
11216             user->authmethods = IAX_AUTH_RSA;
11217          } else {
11218             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11219          }
11220       }
11221       ast_clear_flag(user, IAX_DELME);
11222    }
11223 cleanup:
11224    if (oldha)
11225       ast_free_ha(oldha);
11226    if (oldcon)
11227       free_context(oldcon);
11228    return user;
11229 }

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

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

11771 {
11772    struct sockaddr_in sin;
11773    int x;
11774    int callno;
11775    struct iax_ie_data ied;
11776    struct create_addr_info cai;
11777    struct parsed_dial_string pds;
11778    char *tmpstr;
11779 
11780    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11781       /* Look for an *exact match* call.  Once a call is negotiated, it can only
11782          look up entries for a single context */
11783       if (!ast_mutex_trylock(&iaxsl[x])) {
11784          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11785             return x;
11786          ast_mutex_unlock(&iaxsl[x]);
11787       }
11788    }
11789 
11790    /* No match found, we need to create a new one */
11791 
11792    memset(&cai, 0, sizeof(cai));
11793    memset(&ied, 0, sizeof(ied));
11794    memset(&pds, 0, sizeof(pds));
11795 
11796    tmpstr = ast_strdupa(data);
11797    parse_dial_string(tmpstr, &pds);
11798 
11799    if (ast_strlen_zero(pds.peer)) {
11800       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11801       return -1;
11802    }
11803 
11804    /* Populate our address from the given */
11805    if (create_addr(pds.peer, NULL, &sin, &cai))
11806       return -1;
11807 
11808    if (option_debug)
11809       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
11810          pds.peer, pds.username, pds.password, pds.context);
11811 
11812    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11813    if (callno < 1) {
11814       ast_log(LOG_WARNING, "Unable to create call\n");
11815       return -1;
11816    }
11817 
11818    ast_string_field_set(iaxs[callno], dproot, data);
11819    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11820 
11821    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11822    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11823    /* the string format is slightly different from a standard dial string,
11824       because the context appears in the 'exten' position
11825    */
11826    if (pds.exten)
11827       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11828    if (pds.username)
11829       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11830    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11831    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11832    /* Keep password handy */
11833    if (pds.password)
11834       ast_string_field_set(iaxs[callno], secret, pds.password);
11835    if (pds.key)
11836       ast_string_field_set(iaxs[callno], outkey, pds.key);
11837    /* Start the call going */
11838    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
11839    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11840 
11841    return callno;
11842 }

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

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

05200 {
05201    /* Returns where in "receive time" we are.  That is, how many ms
05202       since we received (or would have received) the frame with timestamp 0 */
05203    int ms;
05204 #ifdef IAXTESTS
05205    int jit;
05206 #endif /* IAXTESTS */
05207    /* Setup rxcore if necessary */
05208    if (ast_tvzero(p->rxcore)) {
05209       p->rxcore = ast_tvnow();
05210       if (option_debug && iaxdebug)
05211          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
05212                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
05213       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
05214 #if 1
05215       if (option_debug && iaxdebug)
05216          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
05217                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
05218 #endif
05219    }
05220 
05221    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
05222 #ifdef IAXTESTS
05223    if (test_jit) {
05224       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
05225          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
05226          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
05227             jit = -jit;
05228          ms += jit;
05229       }
05230    }
05231    if (test_late) {
05232       ms += test_late;
05233       test_late = 0;
05234    }
05235 #endif /* IAXTESTS */
05236    return ms;
05237 }

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

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

05067 {
05068    int ms;
05069    int voice = 0;
05070    int genuine = 0;
05071    int adjust;
05072    int rate = ast_format_rate(f->subclass) / 1000;
05073    struct timeval *delivery = NULL;
05074 
05075 
05076    /* What sort of frame do we have?: voice is self-explanatory
05077       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
05078       non-genuine frames are CONTROL frames [ringing etc], DTMF
05079       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
05080       the others need a timestamp slaved to the voice frames so that they go in sequence
05081    */
05082    if (f) {
05083       if (f->frametype == AST_FRAME_VOICE) {
05084          voice = 1;
05085          delivery = &f->delivery;
05086       } else if (f->frametype == AST_FRAME_IAX) {
05087          genuine = 1;
05088       } else if (f->frametype == AST_FRAME_CNG) {
05089          p->notsilenttx = 0;  
05090       }
05091    }
05092    if (ast_tvzero(p->offset)) {
05093       gettimeofday(&p->offset, NULL);
05094       /* Round to nearest 20ms for nice looking traces */
05095       p->offset.tv_usec -= p->offset.tv_usec % 20000;
05096    }
05097    /* If the timestamp is specified, just send it as is */
05098    if (ts)
05099       return ts;
05100    /* If we have a time that the frame arrived, always use it to make our timestamp */
05101    if (delivery && !ast_tvzero(*delivery)) {
05102       ms = ast_tvdiff_ms(*delivery, p->offset);
05103       if (ms < 0) {
05104          ms = 0;
05105       }
05106       if (option_debug > 2 && iaxdebug)
05107          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05108    } else {
05109       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05110       if (ms < 0)
05111          ms = 0;
05112       if (voice) {
05113          /* On a voice frame, use predicted values if appropriate */
05114          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05115             /* Adjust our txcore, keeping voice and non-voice synchronized */
05116             /* AN EXPLANATION:
05117                When we send voice, we usually send "calculated" timestamps worked out
05118                on the basis of the number of samples sent. When we send other frames,
05119                we usually send timestamps worked out from the real clock.
05120                The problem is that they can tend to drift out of step because the 
05121                   source channel's clock and our clock may not be exactly at the same rate.
05122                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
05123                for this call.  Moving it adjusts timestamps for non-voice frames.
05124                We make the adjustment in the style of a moving average.  Each time we
05125                adjust p->offset by 10% of the difference between our clock-derived
05126                timestamp and the predicted timestamp.  That's why you see "10000"
05127                below even though IAX2 timestamps are in milliseconds.
05128                The use of a moving average avoids offset moving too radically.
05129                Generally, "adjust" roams back and forth around 0, with offset hardly
05130                changing at all.  But if a consistent different starts to develop it
05131                will be eliminated over the course of 10 frames (200-300msecs) 
05132             */
05133             adjust = (ms - p->nextpred);
05134             if (adjust < 0)
05135                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05136             else if (adjust > 0)
05137                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05138 
05139             if (!p->nextpred) {
05140                p->nextpred = ms; /*f->samples / rate;*/
05141                if (p->nextpred <= p->lastsent)
05142                   p->nextpred = p->lastsent + 3;
05143             }
05144             ms = p->nextpred;
05145          } else {
05146                 /* in this case, just use the actual
05147             * time, since we're either way off
05148             * (shouldn't happen), or we're  ending a
05149             * silent period -- and seed the next
05150             * predicted time.  Also, round ms to the
05151             * next multiple of frame size (so our
05152             * silent periods are multiples of
05153             * frame size too) */
05154 
05155             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05156                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05157                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05158 
05159             if (f->samples >= rate) /* check to make sure we dont core dump */
05160             {
05161                int diff = ms % (f->samples / rate);
05162                if (diff)
05163                    ms += f->samples/rate - diff;
05164             }
05165 
05166             p->nextpred = ms;
05167             p->notsilenttx = 1;
05168          }
05169       } else if ( f->frametype == AST_FRAME_VIDEO ) {
05170          /*
05171          * IAX2 draft 03 says that timestamps MUST be in order.
05172          * It does not say anything about several frames having the same timestamp
05173          * When transporting video, we can have a frame that spans multiple iax packets
05174          * (so called slices), so it would make sense to use the same timestamp for all of
05175          * them
05176          * We do want to make sure that frames don't go backwards though
05177          */
05178          if ( (unsigned int)ms < p->lastsent )
05179             ms = p->lastsent;
05180       } else {
05181          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
05182             it's a genuine frame */
05183          if (genuine) {
05184             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
05185             if (ms <= p->lastsent)
05186                ms = p->lastsent + 3;
05187          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05188             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
05189             ms = p->lastsent + 3;
05190          }
05191       }
05192    }
05193    p->lastsent = ms;
05194    if (voice)
05195       p->nextpred = p->nextpred + f->samples / rate;
05196    return ms;
05197 }

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

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

05023 {
05024    unsigned long int mssincetx; /* unsigned to handle overflows */
05025    long int ms, pred;
05026 
05027    tpeer->trunkact = *tv;
05028    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
05029    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05030       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
05031       tpeer->txtrunktime = *tv;
05032       tpeer->lastsent = 999999;
05033    }
05034    /* Update last transmit time now */
05035    tpeer->lasttxtime = *tv;
05036    
05037    /* Calculate ms offset */
05038    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
05039    /* Predict from last value */
05040    pred = tpeer->lastsent + sampms;
05041    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05042       ms = pred;
05043    
05044    /* We never send the same timestamp twice, so fudge a little if we must */
05045    if (ms == tpeer->lastsent)
05046       ms = tpeer->lastsent + 1;
05047    tpeer->lastsent = ms;
05048    return ms;
05049 }

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

Definition at line 2270 of file chan_iax2.c.

References ast_random().

Referenced by create_callno_pools().

02271 {
02272    return abs(ast_random());
02273 }

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

Definition at line 1826 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(), realtime_peer(), realtime_user(), S_OR, and user_unref().

Referenced by handle_call_token().

01827 {
01828    struct addr_range *addr_range;
01829    struct iax2_peer *peer = NULL;
01830    struct iax2_user *user = NULL;
01831    /* if no username is given, check for guest accounts */
01832    const char *find = S_OR(name, "guest");
01833    int res = 1;  /* required by default */
01834    int optional = 0;
01835    enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
01836    /* There are only two cases in which calltoken validation is not required.
01837     * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and
01838     *         the peer definition has not set the requirecalltoken option.
01839     * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no.
01840     */
01841 
01842    /* ----- Case 1 ----- */
01843    if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
01844       ao2_ref(addr_range, -1);
01845       optional = 1;
01846    }
01847 
01848    /* ----- Case 2 ----- */
01849    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
01850       calltoken_required = user->calltoken_required;
01851    } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
01852       calltoken_required = user->calltoken_required;
01853    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
01854       calltoken_required = peer->calltoken_required;
01855    } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
01856       calltoken_required = peer->calltoken_required;
01857    }
01858 
01859    if (peer) {
01860       peer_unref(peer);
01861    }
01862    if (user) {
01863       user_unref(user);
01864    }
01865    if (option_debug) {
01866    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);
01867    }
01868    if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
01869       (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
01870       res = 0;
01871    }
01872 
01873    return res;
01874 }

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

Definition at line 6373 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_destroy(), 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, globalflags, 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_SHRINKCALLERID, 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(), users, ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.

Referenced by socket_process().

06374 {
06375    /* Start pessimistic */
06376    int res = -1;
06377    int version = 2;
06378    struct iax2_user *user = NULL, *best = NULL;
06379    int bestscore = 0;
06380    int gotcapability = 0;
06381    struct ast_variable *v = NULL, *tmpvar = NULL;
06382    struct ao2_iterator i;
06383 
06384    if (!iaxs[callno])
06385       return res;
06386    if (ies->called_number)
06387       ast_string_field_set(iaxs[callno], exten, ies->called_number);
06388    if (ies->calling_number) {
06389       if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 
06390          ast_shrink_phone_number(ies->calling_number);
06391       }
06392       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06393    }
06394    if (ies->calling_name)
06395       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06396    if (ies->calling_ani)
06397       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06398    if (ies->dnid)
06399       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06400    if (ies->rdnis)
06401       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06402    if (ies->called_context)
06403       ast_string_field_set(iaxs[callno], context, ies->called_context);
06404    if (ies->language)
06405       ast_string_field_set(iaxs[callno], language, ies->language);
06406    if (ies->username)
06407       ast_string_field_set(iaxs[callno], username, ies->username);
06408    if (ies->calling_ton > -1)
06409       iaxs[callno]->calling_ton = ies->calling_ton;
06410    if (ies->calling_tns > -1)
06411       iaxs[callno]->calling_tns = ies->calling_tns;
06412    if (ies->calling_pres > -1)
06413       iaxs[callno]->calling_pres = ies->calling_pres;
06414    if (ies->format)
06415       iaxs[callno]->peerformat = ies->format;
06416    if (ies->adsicpe)
06417       iaxs[callno]->peeradsicpe = ies->adsicpe;
06418    if (ies->capability) {
06419       gotcapability = 1;
06420       iaxs[callno]->peercapability = ies->capability;
06421    } 
06422    if (ies->version)
06423       version = ies->version;
06424 
06425    /* Use provided preferences until told otherwise for actual preferences */
06426    if(ies->codec_prefs) {
06427       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06428       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06429    }
06430 
06431    if (!gotcapability) 
06432       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06433    if (version > IAX_PROTO_VERSION) {
06434       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
06435          ast_inet_ntoa(sin->sin_addr), version);
06436       return res;
06437    }
06438    /* Search the userlist for a compatible entry, and fill in the rest */
06439    i = ao2_iterator_init(users, 0);
06440    while ((user = ao2_iterator_next(&i))) {
06441       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
06442          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
06443          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
06444          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
06445               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
06446          if (!ast_strlen_zero(iaxs[callno]->username)) {
06447             /* Exact match, stop right now. */
06448             if (best)
06449                user_unref(best);
06450             best = user;
06451             break;
06452          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06453             /* No required authentication */
06454             if (user->ha) {
06455                /* There was host authentication and we passed, bonus! */
06456                if (bestscore < 4) {
06457                   bestscore = 4;
06458                   if (best)
06459                      user_unref(best);
06460                   best = user;
06461                   continue;
06462                }
06463             } else {
06464                /* No host access, but no secret, either, not bad */
06465                if (bestscore < 3) {
06466                   bestscore = 3;
06467                   if (best)
06468                      user_unref(best);
06469                   best = user;
06470                   continue;
06471                }
06472             }
06473          } else {
06474             if (user->ha) {
06475                /* Authentication, but host access too, eh, it's something.. */
06476                if (bestscore < 2) {
06477                   bestscore = 2;
06478                   if (best)
06479                      user_unref(best);
06480                   best = user;
06481                   continue;
06482                }
06483             } else {
06484                /* Authentication and no host access...  This is our baseline */
06485                if (bestscore < 1) {
06486                   bestscore = 1;
06487                   if (best)
06488                      user_unref(best);
06489                   best = user;
06490                   continue;
06491                }
06492             }
06493          }
06494       }
06495       user_unref(user);
06496    }
06497    ao2_iterator_destroy(&i);
06498    user = best;
06499    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06500       user = realtime_user(iaxs[callno]->username, sin);
06501       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
06502           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
06503          user = user_unref(user);
06504       }
06505    }
06506    if (user) {
06507       /* We found our match (use the first) */
06508       /* copy vars */
06509       for (v = user->vars ; v ; v = v->next) {
06510          if((tmpvar = ast_variable_new(v->name, v->value))) {
06511             tmpvar->next = iaxs[callno]->vars; 
06512             iaxs[callno]->vars = tmpvar;
06513          }
06514       }
06515       /* If a max AUTHREQ restriction is in place, activate it */
06516       if (user->maxauthreq > 0)
06517          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06518       iaxs[callno]->prefs = user->prefs;
06519       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06520       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06521       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06522       iaxs[callno]->encmethods = user->encmethods;
06523       /* Store the requested username if not specified */
06524       if (ast_strlen_zero(iaxs[callno]->username))
06525          ast_string_field_set(iaxs[callno], username, user->name);
06526       /* Store whether this is a trunked call, too, of course, and move if appropriate */
06527       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06528       iaxs[callno]->capability = user->capability;
06529       /* And use the default context */
06530       if (ast_strlen_zero(iaxs[callno]->context)) {
06531          if (user->contexts)
06532             ast_string_field_set(iaxs[callno], context, user->contexts->context);
06533          else
06534             ast_string_field_set(iaxs[callno], context, context);
06535       }
06536       /* And any input keys */
06537       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06538       /* And the permitted authentication methods */
06539       iaxs[callno]->authmethods = user->authmethods;
06540       iaxs[callno]->adsi = user->adsi;
06541       /* If the user has callerid, override the remote caller id. */
06542       if (ast_test_flag(user, IAX_HASCALLERID)) {
06543          iaxs[callno]->calling_tns = 0;
06544          iaxs[callno]->calling_ton = 0;
06545          ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06546          ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06547          ast_string_field_set(iaxs[callno], ani, user->cid_num);
06548          iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06549       } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06550          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06551       } /* else user is allowed to set their own CID settings */
06552       if (!ast_strlen_zero(user->accountcode))
06553          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06554       if (!ast_strlen_zero(user->mohinterpret))
06555          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06556       if (!ast_strlen_zero(user->mohsuggest))
06557          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06558       if (user->amaflags)
06559          iaxs[callno]->amaflags = user->amaflags;
06560       if (!ast_strlen_zero(user->language))
06561          ast_string_field_set(iaxs[callno], language, user->language);
06562       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
06563       /* Keep this check last */
06564       if (!ast_strlen_zero(user->dbsecret)) {
06565          char *family, *key=NULL;
06566          char buf[80];
06567          family = ast_strdupa(user->dbsecret);
06568          key = strchr(family, '/');
06569          if (key) {
06570             *key = '\0';
06571             key++;
06572          }
06573          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06574             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06575          else
06576             ast_string_field_set(iaxs[callno], secret, buf);
06577       } else
06578          ast_string_field_set(iaxs[callno], secret, user->secret);
06579       res = 0;
06580       user = user_unref(user);
06581    } else {
06582        /* user was not found, but we should still fake an AUTHREQ.
06583         * Set authmethods to the last known authmethod used by the system
06584         * Set a fake secret, it's not looked at, just required to attempt authentication.
06585         * Set authrej so the AUTHREP is rejected without even looking at its contents */
06586       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06587       ast_string_field_set(iaxs[callno], secret, "badsecret");
06588       iaxs[callno]->authrej = 1;
06589       if (!ast_strlen_zero(iaxs[callno]->username)) {
06590          /* only send the AUTHREQ if a username was specified. */
06591          res = 0;
06592       }
06593    }
06594    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
06595    return res;
06596 }

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

Definition at line 8133 of file chan_iax2.c.

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

Referenced by socket_process().

08134 {
08135    unsigned int ourver;
08136    char rsi[80];
08137    snprintf(rsi, sizeof(rsi), "si-%s", si);
08138    if (iax_provision_version(&ourver, rsi, 1))
08139       return 0;
08140    if (option_debug)
08141       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
08142    if (ourver != ver) 
08143       iax2_provision(sin, sockfd, NULL, rsi, 1);
08144    return 0;
08145 }

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

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

Referenced by peer_set_srcaddr().

10629 {
10630    int sd;
10631    int res;
10632    
10633    sd = socket(AF_INET, SOCK_DGRAM, 0);
10634    if (sd < 0) {
10635       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10636       return -1;
10637    }
10638 
10639    res = bind(sd, sa, salen);
10640    if (res < 0) {
10641       if (option_debug)
10642          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
10643       close(sd);
10644       return 1;
10645    }
10646 
10647    close(sd);
10648    return 0;
10649 }

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

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

07105 {
07106    char exten[256] = "";
07107    int status = CACHE_FLAG_UNKNOWN;
07108    int expiry = iaxdefaultdpcache;
07109    int x;
07110    int matchmore = 0;
07111    struct iax2_dpcache *dp, *prev;
07112    
07113    if (ies->called_number)
07114       ast_copy_string(exten, ies->called_number, sizeof(exten));
07115 
07116    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
07117       status = CACHE_FLAG_EXISTS;
07118    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
07119       status = CACHE_FLAG_CANEXIST;
07120    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
07121       status = CACHE_FLAG_NONEXISTENT;
07122 
07123    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
07124       /* Don't really do anything with this */
07125    }
07126    if (ies->refresh)
07127       expiry = ies->refresh;
07128    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
07129       matchmore = CACHE_FLAG_MATCHMORE;
07130    ast_mutex_lock(&dpcache_lock);
07131    prev = NULL;
07132    dp = pvt->dpentries;
07133    while(dp) {
07134       if (!strcmp(dp->exten, exten)) {
07135          /* Let them go */
07136          if (prev)
07137             prev->peer = dp->peer;
07138          else
07139             pvt->dpentries = dp->peer;
07140          dp->peer = NULL;
07141          dp->callno = 0;
07142          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
07143          if (dp->flags & CACHE_FLAG_PENDING) {
07144             dp->flags &= ~CACHE_FLAG_PENDING;
07145             dp->flags |= status;
07146             dp->flags |= matchmore;
07147          }
07148          /* Wake up waiters */
07149          for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
07150             if (dp->waiters[x] > -1) {
07151                if (write(dp->waiters[x], "asdf", 4) < 0) {
07152                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
07153                }
07154             }
07155          }
07156       }
07157       prev = dp;
07158       dp = dp->peer;
07159    }
07160    ast_mutex_unlock(&dpcache_lock);
07161    return 0;
07162 }

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

Definition at line 3323 of file chan_iax2.c.

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

03324 {
03325    int which = 0;
03326    struct iax2_peer *peer;
03327    char *res = NULL;
03328    int wordlen = strlen(word);
03329    struct ao2_iterator i;
03330 
03331    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
03332    if (pos != 3)
03333       return NULL;
03334 
03335    i = ao2_iterator_init(peers, 0);
03336    while ((peer = ao2_iterator_next(&i))) {
03337       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
03338          res = ast_strdup(peer->name);
03339          peer_unref(peer);
03340          break;
03341       }
03342       peer_unref(peer);
03343    }
03344    ao2_iterator_destroy(&i);
03345 
03346    return res;
03347 }

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

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

07165 {
07166    int peercallno = 0;
07167    struct chan_iax2_pvt *pvt = iaxs[callno];
07168    struct iax_frame *cur;
07169    jb_frame frame;
07170 
07171    if (ies->callno)
07172       peercallno = ies->callno;
07173 
07174    if (peercallno < 1) {
07175       ast_log(LOG_WARNING, "Invalid transfer request\n");
07176       return -1;
07177    }
07178    remove_by_transfercallno(pvt);
07179    /* since a transfer has taken place, the address will change.
07180     * This must be accounted for in the peercnts table.  Remove
07181     * the old address and add the new one */
07182    peercnt_remove_by_addr(&pvt->addr);
07183    peercnt_add(&pvt->transfer);
07184    /* now copy over the new address */
07185    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
07186    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
07187    /* Reset sequence numbers */
07188    pvt->oseqno = 0;
07189    pvt->rseqno = 0;
07190    pvt->iseqno = 0;
07191    pvt->aseqno = 0;
07192 
07193    if (pvt->peercallno) {
07194       remove_by_peercallno(pvt);
07195    }
07196    pvt->peercallno = peercallno;
07197    /*this is where the transfering call swiches hash tables */
07198    store_by_peercallno(pvt);
07199    pvt->transferring = TRANSFER_NONE;
07200    pvt->svoiceformat = -1;
07201    pvt->voiceformat = 0;
07202    pvt->svideoformat = -1;
07203    pvt->videoformat = 0;
07204    pvt->transfercallno = -1;
07205    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
07206    memset(&pvt->offset, 0, sizeof(pvt->offset));
07207    /* reset jitterbuffer */
07208    while(jb_getall(pvt->jb,&frame) == JB_OK)
07209       iax2_frame_free(frame.data);
07210    jb_reset(pvt->jb);
07211    pvt->lag = 0;
07212    pvt->last = 0;
07213    pvt->lastsent = 0;
07214    pvt->nextpred = 0;
07215    pvt->pingtime = DEFAULT_RETRY_TIME;
07216    AST_LIST_LOCK(&iaxq.queue);
07217    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07218       /* We must cancel any packets that would have been transmitted
07219          because now we're talking to someone new.  It's okay, they
07220          were transmitted to someone that didn't care anyway. */
07221       if (callno == cur->callno) 
07222          cur->retries = -1;
07223    }
07224    AST_LIST_UNLOCK(&iaxq.queue);
07225    return 0; 
07226 }

static unsigned char compress_subclass ( int  subclass  )  [static]

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

01195 {
01196    int x;
01197    int power=-1;
01198    /* If it's 128 or smaller, just return it */
01199    if (subclass < IAX_FLAG_SC_LOG)
01200       return subclass;
01201    /* Otherwise find its power */
01202    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01203       if (subclass & (1 << x)) {
01204          if (power > -1) {
01205             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01206             return 0;
01207          } else
01208             power = x;
01209       }
01210    }
01211    return power | IAX_FLAG_SC_LOG;
01212 }

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

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

08148 {
08149    jb_info stats;
08150    jb_getinfo(pvt->jb, &stats);
08151    
08152    memset(iep, 0, sizeof(*iep));
08153 
08154    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
08155    if(stats.frames_in == 0) stats.frames_in = 1;
08156    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
08157    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
08158    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
08159    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
08160    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
08161 }

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

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

03948 {
03949    struct ast_hostent ahp;
03950    struct hostent *hp;
03951    struct iax2_peer *peer;
03952    int res = -1;
03953    struct ast_codec_pref ourprefs;
03954 
03955    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03956    cai->sockfd = defaultsockfd;
03957    cai->maxtime = 0;
03958    sin->sin_family = AF_INET;
03959 
03960    if (!(peer = find_peer(peername, 1))) {
03961       cai->found = 0;
03962 
03963       hp = ast_gethostbyname(peername, &ahp);
03964       if (hp) {
03965          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03966          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03967          /* use global iax prefs for unknown peer/user */
03968          /* But move the calling channel's native codec to the top of the preference list */
03969          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03970          if (c)
03971             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03972          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03973          return 0;
03974       } else {
03975          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03976          return -1;
03977       }
03978    }
03979 
03980    cai->found = 1;
03981    
03982    /* if the peer has no address (current or default), return failure */
03983    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03984       goto return_unref;
03985 
03986    /* if the peer is being monitored and is currently unreachable, return failure */
03987    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03988       goto return_unref;
03989 
03990    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03991    cai->maxtime = peer->maxms;
03992    cai->capability = peer->capability;
03993    cai->encmethods = peer->encmethods;
03994    cai->sockfd = peer->sockfd;
03995    cai->adsi = peer->adsi;
03996    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03997    /* Move the calling channel's native codec to the top of the preference list */
03998    if (c) {
03999       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
04000       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04001    }
04002    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04003    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04004    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04005    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04006    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04007    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04008    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04009    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04010    if (ast_strlen_zero(peer->dbsecret)) {
04011       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04012    } else {
04013       char *family;
04014       char *key = NULL;
04015 
04016       family = ast_strdupa(peer->dbsecret);
04017       key = strchr(family, '/');
04018       if (key)
04019          *key++ = '\0';
04020       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04021          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04022          goto return_unref;
04023       }
04024    }
04025 
04026    if (peer->addr.sin_addr.s_addr) {
04027       sin->sin_addr = peer->addr.sin_addr;
04028       sin->sin_port = peer->addr.sin_port;
04029    } else {
04030       sin->sin_addr = peer->defaddr.sin_addr;
04031       sin->sin_port = peer->defaddr.sin_port;
04032    }
04033 
04034    res = 0;
04035 
04036 return_unref:
04037    peer_unref(peer);
04038 
04039    return res;
04040 }

static int create_callno_pools ( void   )  [static]

Definition at line 2275 of file chan_iax2.c.

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

Referenced by load_objects().

02276 {
02277    uint16_t i;
02278 
02279    if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02280       return -1;
02281    }
02282 
02283    if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02284       return -1;
02285    }
02286 
02287    /* start at 2, 0 and 1 are reserved */
02288    for (i = 2; i <= IAX_MAX_CALLS; i++) {
02289       struct callno_entry *callno_entry;
02290 
02291       if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02292          return -1;
02293       }
02294 
02295       callno_entry->callno = i;
02296 
02297       if (i < TRUNK_CALL_START) {
02298          ao2_link(callno_pool, callno_entry);
02299       } else {
02300          ao2_link(callno_pool_trunk, callno_entry);
02301       }
02302 
02303       ao2_ref(callno_entry, -1);
02304    }
02305 
02306    return 0;
02307 }

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

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

05408 {
05409    int padding;
05410    unsigned char *workspace;
05411 
05412    workspace = alloca(*datalen);
05413    memset(f, 0, sizeof(*f));
05414    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05415       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05416       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
05417          return -1;
05418       /* Decrypt */
05419       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
05420 
05421       padding = 16 + (workspace[15] & 0x0f);
05422       if (option_debug && iaxdebug)
05423          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
05424       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
05425          return -1;
05426 
05427       *datalen -= padding;
05428       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05429       f->frametype = fh->type;
05430       if (f->frametype == AST_FRAME_VIDEO) {
05431          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
05432       } else {
05433          f->subclass = uncompress_subclass(fh->csub);
05434       }
05435    } else {
05436       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05437       if (option_debug && iaxdebug)
05438          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
05439       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
05440          return -1;
05441       /* Decrypt */
05442       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
05443       padding = 16 + (workspace[15] & 0x0f);
05444       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
05445          return -1;
05446       *datalen -= padding;
05447       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05448    }
05449    return 0;
05450 }

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

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

05494 {
05495    int res=-1;
05496    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
05497       /* Search for possible keys, given secrets */
05498       struct MD5Context md5;
05499       unsigned char digest[16];
05500       char *tmppw, *stringp;
05501       
05502       tmppw = ast_strdupa(iaxs[callno]->secret);
05503       stringp = tmppw;
05504       while ((tmppw = strsep(&stringp, ";"))) {
05505          MD5Init(&md5);
05506          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05507          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05508          MD5Final(digest, &md5);
05509          build_encryption_keys(digest, iaxs[callno]);
05510          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05511          if (!res) {
05512             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
05513             break;
05514          }
05515       }
05516    } else 
05517       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
05518    return res;
05519 }

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

08210 {
08211    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
08212    struct ast_iax2_full_hdr *fh, *cur_fh;
08213 
08214    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
08215       return;
08216 
08217    pkt_buf->len = from_here->buf_len;
08218    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
08219 
08220    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
08221    ast_mutex_lock(&to_here->lock);
08222    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
08223       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
08224       if (fh->oseqno < cur_fh->oseqno) {
08225          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
08226          break;
08227       }
08228    }
08229    AST_LIST_TRAVERSE_SAFE_END
08230 
08231    if (!cur_pkt_buf)
08232       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
08233    
08234    ast_mutex_unlock(&to_here->lock);
08235 }

static void delete_users ( void   )  [static]

Definition at line 11249 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(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.

11250 {
11251    struct iax2_registry *reg;
11252 
11253    ao2_callback(users, 0, user_delme_cb, NULL);
11254 
11255    AST_LIST_LOCK(&registrations);
11256    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
11257       ast_sched_del(sched, reg->expire);
11258       if (reg->callno) {
11259          int callno = reg->callno;
11260          ast_mutex_lock(&iaxsl[callno]);
11261          if (iaxs[callno]) {
11262             iaxs[callno]->reg = NULL;
11263             iax2_destroy(callno);
11264          }
11265          ast_mutex_unlock(&iaxsl[callno]);
11266       }
11267       if (reg->dnsmgr)
11268          ast_dnsmgr_release(reg->dnsmgr);
11269       free(reg);
11270    }
11271    AST_LIST_UNLOCK(&registrations);
11272 
11273    ao2_callback(peers, 0, peer_delme_cb, NULL);
11274 }

static void destroy_firmware ( struct iax_firmware cur  )  [static]

Definition at line 2637 of file chan_iax2.c.

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

Referenced by reload_firmware().

02638 {
02639    /* Close firmware */
02640    if (cur->fwh) {
02641       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02642    }
02643    close(cur->fd);
02644    free(cur);
02645 }

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

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

07982 {
07983    unsigned short dpstatus = 0;
07984    struct iax_ie_data ied1;
07985    int mm;
07986 
07987    memset(&ied1, 0, sizeof(ied1));
07988    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07989    /* Must be started */
07990    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07991       dpstatus = IAX_DPSTATUS_EXISTS;
07992    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07993       dpstatus = IAX_DPSTATUS_CANEXIST;
07994    } else {
07995       dpstatus = IAX_DPSTATUS_NONEXISTENT;
07996    }
07997    if (ast_ignore_pattern(context, callednum))
07998       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07999    if (mm)
08000       dpstatus |= IAX_DPSTATUS_MATCHMORE;
08001    if (!skiplock)
08002       ast_mutex_lock(&iaxsl[callno]);
08003    if (iaxs[callno]) {
08004       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
08005       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
08006       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
08007       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
08008    }
08009    if (!skiplock)
08010       ast_mutex_unlock(&iaxsl[callno]);
08011 }

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

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

08014 {
08015    /* Look up for dpreq */
08016    struct dpreq_data *dpr = data;
08017    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
08018    if (dpr->callerid)
08019       free(dpr->callerid);
08020    free(dpr);
08021    return NULL;
08022 }

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

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

05453 {
05454    int padding;
05455    unsigned char *workspace;
05456    workspace = alloca(*datalen + 32);
05457    if (!workspace)
05458       return -1;
05459    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
05460       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
05461       if (option_debug && iaxdebug)
05462          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
05463       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
05464       padding = 16 + (padding & 0xf);
05465       memcpy(workspace, poo, padding);
05466       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
05467       workspace[15] &= 0xf0;
05468       workspace[15] |= (padding & 0xf);
05469       if (option_debug && iaxdebug)
05470          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]);
05471       *datalen += padding;
05472       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
05473       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
05474          memcpy(poo, workspace + *datalen - 32, 32);
05475    } else {
05476       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
05477       if (option_debug && iaxdebug)
05478          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
05479       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
05480       padding = 16 + (padding & 0xf);
05481       memcpy(workspace, poo, padding);
05482       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
05483       workspace[15] &= 0xf0;
05484       workspace[15] |= (padding & 0x0f);
05485       *datalen += padding;
05486       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
05487       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
05488          memcpy(poo, workspace + *datalen - 32, 32);
05489    }
05490    return 0;
05491 }

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

Definition at line 7410 of file chan_iax2.c.

References __expire_registry(), and schedule_action.

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

07411 {
07412 #ifdef SCHED_MULTITHREADED
07413    if (schedule_action(__expire_registry, data))
07414 #endif      
07415       __expire_registry(data);
07416    return 0;
07417 }

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

11845 {
11846    struct iax2_dpcache *dp, *prev = NULL, *next;
11847    struct timeval tv;
11848    int x;
11849    int com[2];
11850    int timeout;
11851    int old=0;
11852    int outfd;
11853    int abort;
11854    int callno;
11855    struct ast_channel *c;
11856    struct ast_frame *f;
11857    gettimeofday(&tv, NULL);
11858    dp = dpcache;
11859    while(dp) {
11860       next = dp->next;
11861       /* Expire old caches */
11862       if (ast_tvcmp(tv, dp->expiry) > 0) {
11863             /* It's expired, let it disappear */
11864             if (prev)
11865                prev->next = dp->next;
11866             else
11867                dpcache = dp->next;
11868             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
11869                /* Free memory and go again */
11870                free(dp);
11871             } else {
11872                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);
11873             }
11874             dp = next;
11875             continue;
11876       }
11877       /* We found an entry that matches us! */
11878       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
11879          break;
11880       prev = dp;
11881       dp = next;
11882    }
11883    if (!dp) {
11884       /* No matching entry.  Create a new one. */
11885       /* First, can we make a callno? */
11886       callno = cache_get_callno_locked(data);
11887       if (callno < 0) {
11888          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11889          return NULL;
11890       }
11891       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11892          ast_mutex_unlock(&iaxsl[callno]);
11893          return NULL;
11894       }
11895       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11896       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11897       gettimeofday(&dp->expiry, NULL);
11898       dp->orig = dp->expiry;
11899       /* Expires in 30 mins by default */
11900       dp->expiry.tv_sec += iaxdefaultdpcache;
11901       dp->next = dpcache;
11902       dp->flags = CACHE_FLAG_PENDING;
11903       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
11904          dp->waiters[x] = -1;
11905       dpcache = dp;
11906       dp->peer = iaxs[callno]->dpentries;
11907       iaxs[callno]->dpentries = dp;
11908       /* Send the request if we're already up */
11909       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11910          iax2_dprequest(dp, callno);
11911       ast_mutex_unlock(&iaxsl[callno]);
11912    }
11913    /* By here we must have a dp */
11914    if (dp->flags & CACHE_FLAG_PENDING) {
11915       /* Okay, here it starts to get nasty.  We need a pipe now to wait
11916          for a reply to come back so long as it's pending */
11917       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
11918          /* Find an empty slot */
11919          if (dp->waiters[x] < 0)
11920             break;
11921       }
11922       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
11923          ast_log(LOG_WARNING, "No more waiter positions available\n");
11924          return NULL;
11925       }
11926       if (pipe(com)) {
11927          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11928          return NULL;
11929       }
11930       dp->waiters[x] = com[1];
11931       /* Okay, now we wait */
11932       timeout = iaxdefaulttimeout * 1000;
11933       /* Temporarily unlock */
11934       ast_mutex_unlock(&dpcache_lock);
11935       /* Defer any dtmf */
11936       if (chan)
11937          old = ast_channel_defer_dtmf(chan);
11938       abort = 0;
11939       while(timeout) {
11940          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11941          if (outfd > -1) {
11942             break;
11943          }
11944          if (c) {
11945             f = ast_read(c);
11946             if (f)
11947                ast_frfree(f);
11948             else {
11949                /* Got hung up on, abort! */
11950                break;
11951                abort = 1;
11952             }
11953          }
11954       }
11955       if (!timeout) {
11956          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11957       }
11958       ast_mutex_lock(&dpcache_lock);
11959       dp->waiters[x] = -1;
11960       close(com[1]);
11961       close(com[0]);
11962       if (abort) {
11963          /* Don't interpret anything, just abort.  Not sure what th epoint
11964            of undeferring dtmf on a hung up channel is but hey whatever */
11965          if (!old && chan)
11966             ast_channel_undefer_dtmf(chan);
11967          return NULL;
11968       }
11969       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11970          /* Now to do non-independent analysis the results of our wait */
11971          if (dp->flags & CACHE_FLAG_PENDING) {
11972             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
11973                pending.  Don't let it take as long to timeout. */
11974             dp->flags &= ~CACHE_FLAG_PENDING;
11975             dp->flags |= CACHE_FLAG_TIMEOUT;
11976             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
11977                systems without leaving it unavailable once the server comes back online */
11978             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11979             for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11980                if (dp->waiters[x] > -1) {
11981                   if (write(dp->waiters[x], "asdf", 4) < 0) {
11982                      ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11983                   }
11984                }
11985             }
11986          }
11987       }
11988       /* Our caller will obtain the rest */
11989       if (!old && chan)
11990          ast_channel_undefer_dtmf(chan);
11991    }
11992    return dp;  
11993 }

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

References __find_callno().

Referenced by iax2_poke_peer(), and socket_process().

02537                                                                                                                                     {
02538 
02539    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02540 }

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

References __find_callno().

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

02542                                                                                                                                            {
02543 
02544    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02545 }

static struct iax2_thread* find_idle_thread ( void   )  [static]

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

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

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

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

01273 {
01274    struct iax2_peer *peer = NULL;
01275    struct iax2_peer tmp_peer = {
01276       .name = name,
01277    };
01278 
01279    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01280 
01281    /* Now go for realtime if applicable */
01282    if(!peer && realtime)
01283       peer = realtime_peer(name, NULL);
01284 
01285    return peer;
01286 }

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

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

05240 {
05241    struct iax2_trunk_peer *tpeer;
05242    
05243    /* Finds and locks trunk peer */
05244    ast_mutex_lock(&tpeerlock);
05245    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
05246       /* We don't lock here because tpeer->addr *never* changes */
05247       if (!inaddrcmp(&tpeer->addr, sin)) {
05248          ast_mutex_lock(&tpeer->lock);
05249          break;
05250       }
05251    }
05252    if (!tpeer) {
05253       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
05254          ast_mutex_init(&tpeer->lock);
05255          tpeer->lastsent = 9999;
05256          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
05257          tpeer->trunkact = ast_tvnow();
05258          ast_mutex_lock(&tpeer->lock);
05259          tpeer->next = tpeers;
05260          tpeer->sockfd = fd;
05261          tpeers = tpeer;
05262 #ifdef SO_NO_CHECK
05263          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
05264 #endif
05265          if (option_debug)
05266             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
05267       }
05268    }
05269    ast_mutex_unlock(&tpeerlock);
05270    return tpeer;
05271 }

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

Definition at line 1300 of file chan_iax2.c.

References ao2_find(), iax2_user::name, and users.

01301 {
01302    struct iax2_user tmp_user = {
01303       .name = name,
01304    };
01305 
01306    return ao2_find(users, &tmp_user, OBJ_POINTER);
01307 }

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

Definition at line 5051 of file chan_iax2.c.

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

Referenced by socket_process().

05052 {
05053    long ms; /* NOT unsigned */
05054    if (ast_tvzero(iaxs[callno]->rxcore)) {
05055       /* Initialize rxcore time if appropriate */
05056       gettimeofday(&iaxs[callno]->rxcore, NULL);
05057       /* Round to nearest 20ms so traces look pretty */
05058       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05059    }
05060    /* Calculate difference between trunk and channel */
05061    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
05062    /* Return as the sum of trunk time and the difference between trunk and real time */
05063    return ms + ts;
05064 }

static void free_context ( struct iax2_context con  )  [static]

Definition at line 10380 of file chan_iax2.c.

References free, and iax2_context::next.

Referenced by build_user(), and user_destructor().

10381 {
10382    struct iax2_context *conl;
10383    while(con) {
10384       conl = con;
10385       con = con->next;
10386       free(conl);
10387    }
10388 }

static void free_signaling_queue_entry ( struct signaling_queue_entry s  )  [static]

Definition at line 1522 of file chan_iax2.c.

References ast_free, and s.

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

01523 {
01524    ast_free(s->f.data);
01525    ast_free(s);
01526 }

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

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

12118 {
12119    struct iax2_peer *peer;
12120    char *peername, *colname;
12121 
12122    peername = ast_strdupa(data);
12123 
12124    /* if our channel, return the IP address of the endpoint of current channel */
12125    if (!strcmp(peername,"CURRENTCHANNEL")) {
12126            unsigned short callno;
12127       if (chan->tech != &iax2_tech)
12128          return -1;
12129       callno = PTR_TO_CALLNO(chan->tech_pvt);   
12130       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
12131       return 0;
12132    }
12133 
12134    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
12135       *colname++ = '\0';
12136    else if ((colname = strchr(peername, '|')))
12137       *colname++ = '\0';
12138    else
12139       colname = "ip";
12140 
12141    if (!(peer = find_peer(peername, 1)))
12142       return -1;
12143 
12144    if (!strcasecmp(colname, "ip")) {
12145       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
12146    } else  if (!strcasecmp(colname, "status")) {
12147       peer_status(peer, buf, len); 
12148    } else  if (!strcasecmp(colname, "mailbox")) {
12149       ast_copy_string(buf, peer->mailbox, len);
12150    } else  if (!strcasecmp(colname, "context")) {
12151       ast_copy_string(buf, peer->context, len);
12152    } else  if (!strcasecmp(colname, "expire")) {
12153       snprintf(buf, len, "%d", peer->expire);
12154    } else  if (!strcasecmp(colname, "dynamic")) {
12155       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
12156    } else  if (!strcasecmp(colname, "callerid_name")) {
12157       ast_copy_string(buf, peer->cid_name, len);
12158    } else  if (!strcasecmp(colname, "callerid_num")) {
12159       ast_copy_string(buf, peer->cid_num, len);
12160    } else  if (!strcasecmp(colname, "codecs")) {
12161       ast_getformatname_multiple(buf, len -1, peer->capability);
12162    } else  if (!strncasecmp(colname, "codec[", 6)) {
12163       char *codecnum, *ptr;
12164       int index = 0, codec = 0;
12165       
12166       codecnum = strchr(colname, '[');
12167       *codecnum = '\0';
12168       codecnum++;
12169       if ((ptr = strchr(codecnum, ']'))) {
12170          *ptr = '\0';
12171       }
12172       index = atoi(codecnum);
12173       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
12174          ast_copy_string(buf, ast_getformatname(codec), len);
12175       } else {
12176          buf[0] = '\0';
12177       }
12178    } else {
12179       buf[0] = '\0';
12180    }
12181 
12182    peer_unref(peer);
12183 
12184    return 0;
12185 }

static int get_auth_methods ( char *  value  )  [static]

Definition at line 10612 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

10613 {
10614    int methods = 0;
10615    if (strstr(value, "rsa"))
10616       methods |= IAX_AUTH_RSA;
10617    if (strstr(value, "md5"))
10618       methods |= IAX_AUTH_MD5;
10619    if (strstr(value, "plaintext"))
10620       methods |= IAX_AUTH_PLAINTEXT;
10621    return methods;
10622 }

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

Definition at line 1149 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

01150 {
01151    int e;
01152    if (!strcasecmp(s, "aes128"))
01153       e = IAX_ENCRYPT_AES128;
01154    else if (ast_true(s))
01155       e = IAX_ENCRYPT_AES128;
01156    else
01157       e = 0;
01158    return e;
01159 }

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

Definition at line 3561 of file chan_iax2.c.

References __get_from_jb(), and schedule_action.

Referenced by update_jbsched().

03562 {
03563 #ifdef SCHED_MULTITHREADED
03564    if (schedule_action(__get_from_jb, data))
03565 #endif      
03566       __get_from_jb(data);
03567    return 0;
03568 }

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

Definition at line 2208 of file chan_iax2.c.

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

Referenced by __find_callno(), and make_trunk().

02209 {
02210    struct callno_entry *callno_entry = NULL;
02211    if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02212       ast_log(LOG_WARNING, "Out of CallNumbers\n");
02213       /* Minor optimization for the extreme case. */
02214       return NULL;
02215    }
02216 
02217    /* the callno_pool container is locked here primarily to ensure thread
02218     * safety of the total_nonval_callno_used check and increment */
02219    ao2_lock(callno_pool);
02220 
02221    /* only a certain number of nonvalidated call numbers should be allocated.
02222     * If there ever is an attack, this separates the calltoken validating
02223     * users from the non calltoken validating users. */
02224    if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02225       ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02226       ao2_unlock(callno_pool);
02227       return NULL;
02228    }
02229 
02230    /* unlink the object from the container, taking over ownership
02231     * of the reference the container had to the object */
02232    callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02233 
02234    if (callno_entry) {
02235       callno_entry->validated = validated;
02236       if (!validated) {
02237          total_nonval_callno_used++;
02238       }
02239    }
02240 
02241    ao2_unlock(callno_pool);
02242    return callno_entry;
02243 }

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 4254 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(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), t, ast_iax2_full_hdr::ts, and uncompress_subclass().

Referenced by socket_process().

04256 {
04257 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"  /* address + port + ts + randomcalldata */
04258 #define CALLTOKEN_IE_FORMAT   "%u?%s"     /* time + ? + (40 char hash) */
04259    char buf[256] = { 0 };
04260    time_t t = time(NULL);
04261    char hash[41]; /* 40 char sha1 hash */
04262    int subclass = uncompress_subclass(fh->csub);
04263 
04264    /* ----- Case 1 ----- */
04265    if (ies->calltoken && !ies->calltokendata) {  /* empty calltoken is provided, client supports calltokens */
04266       struct iax_ie_data ied = {
04267          .buf = { 0 },
04268          .pos = 0,
04269       };
04270 
04271       /* create the hash with their address data and our timestamp */
04272       snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04273       ast_sha1_hash(hash, buf);
04274 
04275       snprintf(buf, sizeof(buf), CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04276       iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, buf);
04277       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04278 
04279       return 1;
04280 
04281    /* ----- Case 2 ----- */
04282    } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */
04283       char *rec_hash = NULL;    /* the received hash, make sure it matches with ours. */
04284       char *rec_ts = NULL;      /* received timestamp */
04285       unsigned int rec_time;  /* received time_t */
04286 
04287       /* split the timestamp from the hash data */
04288       rec_hash = strchr((char *) ies->calltokendata, '?');
04289       if (rec_hash) {
04290          *rec_hash++ = '\0';
04291          rec_ts = (char *) ies->calltokendata;
04292       }
04293 
04294       /* check that we have valid data before we do any comparisons */
04295       if (!rec_hash || !rec_ts) {
04296          goto reject;
04297       } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04298          goto reject;
04299       }
04300 
04301       /* create a hash with their address and the _TOKEN'S_ timestamp */
04302       snprintf(buf, sizeof(buf), CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04303       ast_sha1_hash(hash, buf);
04304 
04305       /* compare hashes and then check timestamp delay */
04306       if (strcmp(hash, rec_hash)) {
04307          ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04308          goto reject; /* received hash does not match ours, reject */
04309       } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04310          ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04311          goto reject; /* too much delay, reject */
04312       }
04313 
04314       /* at this point the call token is valid, returning 0 
04315        * will allow socket_process to continue as usual */
04316       requirecalltoken_mark_auto(ies->username, subclass);
04317       return 0;
04318 
04319    /* ----- Case 3 ----- */
04320    } else { /* calltokens are not supported for this client, how do we respond? */
04321       if (calltoken_required(sin, ies->username, subclass)) {
04322          ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04323          goto reject;
04324       }
04325       return 0; /* calltoken is not required for this addr, so permit it. */
04326    }
04327 
04328 reject:
04329    /* received frame has failed calltoken inspection, send apathetic reject messages */
04330    if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04331       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04332    } else {
04333       send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04334    }
04335 
04336    return 1;
04337 }

static void handle_deferred_full_frames ( struct iax2_thread thread  )  [static]

Handle any deferred full frames for this thread.

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

08180 {
08181    struct iax2_pkt_buf *pkt_buf;
08182 
08183    ast_mutex_lock(&thread->lock);
08184 
08185    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
08186       ast_mutex_unlock(&thread->lock);
08187 
08188       thread->buf = pkt_buf->buf;
08189       thread->buf_len = pkt_buf->len;
08190       thread->buf_size = pkt_buf->len + 1;
08191       
08192       socket_process(thread);
08193 
08194       thread->buf = NULL;
08195       ast_free(pkt_buf);
08196 
08197       ast_mutex_lock(&thread->lock);
08198    }
08199 
08200    ast_mutex_unlock(&thread->lock);
08201 }

static int handle_error ( void   )  [static]

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

02926 {
02927    /* XXX Ideally we should figure out why an error occured and then abort those
02928       rather than continuing to try.  Unfortunately, the published interface does
02929       not seem to work XXX */
02930 #if 0
02931    struct sockaddr_in *sin;
02932    int res;
02933    struct msghdr m;
02934    struct sock_extended_err e;
02935    m.msg_name = NULL;
02936    m.msg_namelen = 0;
02937    m.msg_iov = NULL;
02938    m.msg_control = &e;
02939    m.msg_controllen = sizeof(e);
02940    m.msg_flags = 0;
02941    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02942    if (res < 0)
02943       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02944    else {
02945       if (m.msg_controllen) {
02946          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02947          if (sin) 
02948             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02949          else
02950             ast_log(LOG_WARNING, "No address detected??\n");
02951       } else {
02952          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02953       }
02954    }
02955 #endif
02956    return 0;
02957 }

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

Acknowledgment received for OUR registration.

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

07230 {
07231    struct iax2_registry *reg;
07232    /* Start pessimistic */
07233    char peer[256] = "";
07234    char msgstatus[60];
07235    int refresh = 60;
07236    char ourip[256] = "<Unspecified>";
07237    struct sockaddr_in oldus;
07238    struct sockaddr_in us;
07239    int oldmsgs;
07240 
07241    memset(&us, 0, sizeof(us));
07242    if (ies->apparent_addr)
07243       bcopy(ies->apparent_addr, &us, sizeof(us));
07244    if (ies->username)
07245       ast_copy_string(peer, ies->username, sizeof(peer));
07246    if (ies->refresh)
07247       refresh = ies->refresh;
07248    if (ies->calling_number) {
07249       /* We don't do anything with it really, but maybe we should */
07250    }
07251    reg = iaxs[callno]->reg;
07252    if (!reg) {
07253       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
07254       return -1;
07255    }
07256    memcpy(&oldus, &reg->us, sizeof(oldus));
07257    oldmsgs = reg->messages;
07258    if (inaddrcmp(&reg->addr, sin)) {
07259       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07260       return -1;
07261    }
07262    memcpy(&reg->us, &us, sizeof(reg->us));
07263    if (ies->msgcount >= 0)
07264       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
07265    /* always refresh the registration at the interval requested by the server
07266       we are registering to
07267    */
07268    reg->refresh = refresh;
07269    AST_SCHED_DEL(sched, reg->expire);
07270    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07271    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
07272       if (option_verbose > 2) {
07273          if (reg->messages > 255)
07274             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
07275          else if (reg->messages > 1)
07276             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
07277          else if (reg->messages > 0)
07278             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
07279          else
07280             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
07281          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07282          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
07283       }
07284       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
07285    }
07286    reg->regstate = REG_STATE_REGISTERED;
07287    return 0;
07288 }

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

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

02347 {
02348    if (frametype != AST_FRAME_IAX) {
02349       return 0;
02350    }
02351    switch (subclass) {
02352    case IAX_COMMAND_NEW:
02353    case IAX_COMMAND_REGREQ:
02354    case IAX_COMMAND_FWDOWNL:
02355    case IAX_COMMAND_REGREL:
02356       return 1;
02357    case IAX_COMMAND_POKE:
02358       if (!inbound) {
02359          return 1;
02360       }
02361       break;
02362    }
02363    return 0;
02364 }

static int iax2_answer ( struct ast_channel c  )  [static]

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

04857 {
04858    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04859    if (option_debug)
04860       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
04861    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04862 }

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

04702 {
04703    struct ast_channel *cs[3];
04704    struct ast_channel *who, *other;
04705    int to = -1;
04706    int res = -1;
04707    int transferstarted=0;
04708    struct ast_frame *f;
04709    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
04710    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
04711    struct timeval waittimer = {0, 0}, tv;
04712 
04713    lock_both(callno0, callno1);
04714    if (!iaxs[callno0] || !iaxs[callno1]) {
04715       unlock_both(callno0, callno1);
04716       return AST_BRIDGE_FAILED;
04717    }
04718    /* Put them in native bridge mode */
04719    if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
04720       iaxs[callno0]->bridgecallno = callno1;
04721       iaxs[callno1]->bridgecallno = callno0;
04722    }
04723    /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */
04724    if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
04725       transferstarted = 1;
04726    }
04727    unlock_both(callno0, callno1);
04728 
04729    /* If not, try to bridge until we can execute a transfer, if we can */
04730    cs[0] = c0;
04731    cs[1] = c1;
04732    for (/* ever */;;) {
04733       /* Check in case we got masqueraded into */
04734       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04735          if (option_verbose > 2)
04736             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
04737          /* Remove from native mode */
04738          if (c0->tech == &iax2_tech) {
04739             ast_mutex_lock(&iaxsl[callno0]);
04740             iaxs[callno0]->bridgecallno = 0;
04741             ast_mutex_unlock(&iaxsl[callno0]);
04742          }
04743          if (c1->tech == &iax2_tech) {
04744             ast_mutex_lock(&iaxsl[callno1]);
04745             iaxs[callno1]->bridgecallno = 0;
04746             ast_mutex_unlock(&iaxsl[callno1]);
04747          }
04748          return AST_BRIDGE_FAILED_NOWARN;
04749       }
04750       if (c0->nativeformats != c1->nativeformats) {
04751          if (option_verbose > 2) {
04752             char buf0[255];
04753             char buf1[255];
04754             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04755             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04756             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04757          }
04758          /* Remove from native mode */
04759          lock_both(callno0, callno1);
04760          if (iaxs[callno0])
04761             iaxs[callno0]->bridgecallno = 0;
04762          if (iaxs[callno1])
04763             iaxs[callno1]->bridgecallno = 0;
04764          unlock_both(callno0, callno1);
04765          return AST_BRIDGE_FAILED_NOWARN;
04766       }
04767       /* check if transfered and if we really want native bridging */
04768       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04769          /* Try the transfer */
04770          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04771                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04772             ast_log(LOG_WARNING, "Unable to start the transfer\n");
04773          transferstarted = 1;
04774       }
04775       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04776          /* Call has been transferred.  We're no longer involved */
04777          gettimeofday(&tv, NULL);
04778          if (ast_tvzero(waittimer)) {
04779             waittimer = tv;
04780          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04781             c0->_softhangup |= AST_SOFTHANGUP_DEV;
04782             c1->_softhangup |= AST_SOFTHANGUP_DEV;
04783             *fo = NULL;
04784             *rc = c0;
04785             res = AST_BRIDGE_COMPLETE;
04786             break;
04787          }
04788       }
04789       to = 1000;
04790       who = ast_waitfor_n(cs, 2, &to);
04791       if (timeoutms > -1) {
04792          timeoutms -= (1000 - to);
04793          if (timeoutms < 0)
04794             timeoutms = 0;
04795       }
04796       if (!who) {
04797          if (!timeoutms) {
04798             res = AST_BRIDGE_RETRY;
04799             break;
04800          }
04801          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04802             res = AST_BRIDGE_FAILED;
04803             break;
04804          }
04805          continue;
04806       }
04807       f = ast_read(who);
04808       if (!f) {
04809          *fo = NULL;
04810          *rc = who;
04811          res = AST_BRIDGE_COMPLETE;
04812          break;
04813       }
04814       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04815          *fo = f;
04816          *rc = who;
04817          res =  AST_BRIDGE_COMPLETE;
04818          break;
04819       }
04820       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
04821       if ((f->frametype == AST_FRAME_VOICE) ||
04822          (f->frametype == AST_FRAME_TEXT) ||
04823          (f->frametype == AST_FRAME_VIDEO) || 
04824          (f->frametype == AST_FRAME_IMAGE) ||
04825          (f->frametype == AST_FRAME_DTMF) ||
04826          (f->frametype == AST_FRAME_CONTROL)) {
04827          /* monitored dtmf take out of the bridge.
04828           * check if we monitor the specific source.
04829           */
04830          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04831          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04832             *rc = who;
04833             *fo = f;
04834             res = AST_BRIDGE_COMPLETE;
04835             /* Remove from native mode */
04836             break;
04837          }
04838          /* everything else goes to the other side */
04839          ast_write(other, f);
04840       }
04841       ast_frfree(f);
04842       /* Swap who gets priority */
04843       cs[2] = cs[0];
04844       cs[0] = cs[1];
04845       cs[1] = cs[2];
04846    }
04847    lock_both(callno0, callno1);
04848    if(iaxs[callno0])
04849       iaxs[callno0]->bridgecallno = 0;
04850    if(iaxs[callno1])
04851       iaxs[callno1]->bridgecallno = 0;
04852    unlock_both(callno0, callno1);
04853    return res;
04854 }

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

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

04398 {
04399    struct sockaddr_in sin;
04400    char *l=NULL, *n=NULL, *tmpstr;
04401    struct iax_ie_data ied;
04402    char *defaultrdest = "s";
04403    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04404    struct parsed_dial_string pds;
04405    struct create_addr_info cai;
04406 
04407    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
04408       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
04409       return -1;
04410    }
04411 
04412    memset(&cai, 0, sizeof(cai));
04413    cai.encmethods = iax2_encryption;
04414 
04415    memset(&pds, 0, sizeof(pds));
04416    tmpstr = ast_strdupa(dest);
04417    parse_dial_string(tmpstr, &pds);
04418 
04419    if (ast_strlen_zero(pds.peer)) {
04420       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
04421       return -1;
04422    }
04423 
04424    if (!pds.exten) {
04425       pds.exten = defaultrdest;
04426    }
04427 
04428    if (create_addr(pds.peer, c, &sin, &cai)) {
04429       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
04430       return -1;
04431    }
04432 
04433    if (!pds.username && !ast_strlen_zero(cai.username))
04434       pds.username = cai.username;
04435    if (!pds.password && !ast_strlen_zero(cai.secret))
04436       pds.password = cai.secret;
04437    if (!pds.key && !ast_strlen_zero(cai.outkey))
04438       pds.key = cai.outkey;
04439    if (!pds.context && !ast_strlen_zero(cai.peercontext))
04440       pds.context = cai.peercontext;
04441 
04442    /* Keep track of the context for outgoing calls too */
04443    ast_copy_string(c->context, cai.context, sizeof(c->context));
04444 
04445    if (pds.port)
04446       sin.sin_port = htons(atoi(pds.port));
04447 
04448    l = c->cid.cid_num;
04449    n = c->cid.cid_name;
04450 
04451    /* Now build request */ 
04452    memset(&ied, 0, sizeof(ied));
04453 
04454    /* On new call, first IE MUST be IAX version of caller */
04455    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
04456    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
04457    if (pds.options && strchr(pds.options, 'a')) {
04458       /* Request auto answer */
04459       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
04460    }
04461 
04462    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
04463 
04464    if (l) {
04465       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
04466       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04467    } else {
04468       if (n)
04469          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
04470       else
04471          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
04472    }
04473 
04474    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
04475    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
04476 
04477    if (n)
04478       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
04479    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
04480       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
04481 
04482    if (!ast_strlen_zero(c->language))
04483       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
04484    if (!ast_strlen_zero(c->cid.cid_dnid))
04485       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
04486    if (!ast_strlen_zero(c->cid.cid_rdnis))
04487       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
04488 
04489    if (pds.context)
04490       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
04491 
04492    if (pds.username)
04493       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
04494 
04495    if (cai.encmethods)
04496       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
04497 
04498    ast_mutex_lock(&iaxsl[callno]);
04499 
04500    if (!ast_strlen_zero(c->context))
04501       ast_string_field_set(iaxs[callno], context, c->context);
04502 
04503    if (pds.username)
04504       ast_string_field_set(iaxs[callno], username, pds.username);
04505 
04506    iaxs[callno]->encmethods = cai.encmethods;
04507 
04508    iaxs[callno]->adsi = cai.adsi;
04509    
04510    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
04511    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
04512 
04513    if (pds.key)
04514       ast_string_field_set(iaxs[callno], outkey, pds.key);
04515    if (pds.password)
04516       ast_string_field_set(iaxs[callno], secret, pds.password);
04517 
04518    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
04519    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
04520    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
04521    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
04522 
04523    if (iaxs[callno]->maxtime) {
04524       /* Initialize pingtime and auto-congest time */
04525       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
04526       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
04527    } else if (autokill) {
04528       iaxs[callno]->pingtime = autokill / 2;
04529       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
04530    }
04531 
04532    /* send the command using the appropriate socket for this peer */
04533    iaxs[callno]->sockfd = cai.sockfd;
04534 
04535    /* Transmit the string in a "NEW" request */
04536    add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
04537    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
04538 
04539    ast_mutex_unlock(&iaxsl[callno]);
04540    ast_setstate(c, AST_STATE_RINGING);
04541    
04542    return 0;
04543 }

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

12020 {
12021    int res = 0;
12022    struct iax2_dpcache *dp;
12023 #if 0
12024    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
12025 #endif
12026    if ((priority != 1) && (priority != 2))
12027       return 0;
12028    ast_mutex_lock(&dpcache_lock);
12029    dp = find_cache(chan, data, context, exten, priority);
12030    if (dp) {
12031       if (dp->flags & CACHE_FLAG_CANEXIST)
12032          res= 1;
12033    }
12034    ast_mutex_unlock(&dpcache_lock);
12035    if (!dp) {
12036       ast_log(LOG_WARNING, "Unable to make DP cache\n");
12037    }
12038    return res;
12039 }

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

Definition at line 4064 of file chan_iax2.c.

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

Referenced by iax2_call(), and update_registry().

04065 {
04066    time_t t;
04067    struct tm tm;
04068    unsigned int tmp;
04069    time(&t);
04070    if (!ast_strlen_zero(tz))
04071       ast_localtime(&t, &tm, tz);
04072    else
04073       ast_localtime(&t, &tm, NULL);
04074    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
04075    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
04076    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
04077    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
04078    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
04079    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
04080    return tmp;
04081 }

static void iax2_destroy ( int  callno  )  [static]

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

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

static void iax2_destroy_helper ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1352 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(), chan_iax2_pvt::username, and users.

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

01353 {
01354    /* Decrement AUTHREQ count if needed */
01355    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01356       struct iax2_user *user;
01357       struct iax2_user tmp_user = {
01358          .name = pvt->username,
01359       };
01360 
01361       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01362       if (user) {
01363          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01364          user = user_unref(user);       
01365       }
01366 
01367       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01368    }
01369 
01370    /* No more pings or lagrq's */
01371    AST_SCHED_DEL(sched, pvt->pingid);
01372    AST_SCHED_DEL(sched, pvt->lagid);
01373    AST_SCHED_DEL(sched, pvt->autoid);
01374    AST_SCHED_DEL(sched, pvt->authid);
01375    AST_SCHED_DEL(sched, pvt->initid);
01376    AST_SCHED_DEL(sched, pvt->jbid);
01377 }

static int iax2_devicestate ( void *  data  )  [static]

Part of the device state notification system ---.

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

12211 {
12212    struct parsed_dial_string pds;
12213    char *tmp = ast_strdupa(data);
12214    struct iax2_peer *p;
12215    int res = AST_DEVICE_INVALID;
12216 
12217    memset(&pds, 0, sizeof(pds));
12218    parse_dial_string(tmp, &pds);
12219 
12220    if (ast_strlen_zero(pds.peer)) {
12221       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12222       return res;
12223    }
12224    
12225    if (option_debug > 2)
12226       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
12227 
12228    /* SLD: FIXME: second call to find_peer during registration */
12229    if (!(p = find_peer(pds.peer, 1)))
12230       return res;
12231 
12232    res = AST_DEVICE_UNAVAILABLE;
12233    if (option_debug > 2) 
12234       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12235          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12236    
12237    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12238        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12239       /* Peer is registered, or have default IP address
12240          and a valid registration */
12241       if (p->historicms == 0 || p->historicms <= p->maxms)
12242          /* let the core figure out whether it is in use or not */
12243          res = AST_DEVICE_UNKNOWN;  
12244    }
12245 
12246    peer_unref(p);
12247 
12248    return res;
12249 }

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

Definition at line 3680 of file chan_iax2.c.

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

03681 {
03682    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03683 }

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

Definition at line 3685 of file chan_iax2.c.

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

03686 {
03687    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03688 }

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

Definition at line 6221 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06222 {
06223    if (argc < 2 || argc > 3)
06224       return RESULT_SHOWUSAGE;
06225    iaxdebug = 1;
06226    ast_cli(fd, "IAX2 Debugging Enabled\n");
06227    return RESULT_SUCCESS;
06228 }

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

Definition at line 6239 of file chan_iax2.c.

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

06240 {
06241    if (argc < 3 || argc > 4)
06242       return RESULT_SHOWUSAGE;
06243    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
06244    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
06245    return RESULT_SUCCESS;
06246 }

static int iax2_do_register ( struct iax2_registry reg  )  [static]

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

10093 {
10094    struct iax_ie_data ied;
10095    if (option_debug && iaxdebug)
10096       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
10097 
10098    if (reg->dnsmgr && 
10099        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
10100       /* Maybe the IP has changed, force DNS refresh */
10101       ast_dnsmgr_refresh(reg->dnsmgr);
10102    }
10103    
10104    /*
10105     * if IP has Changed, free allocated call to create a new one with new IP
10106     * call has the pointer to IP and must be updated to the new one
10107     */
10108    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
10109       int callno = reg->callno;
10110       ast_mutex_lock(&iaxsl[callno]);
10111       iax2_destroy(callno);
10112       ast_mutex_unlock(&iaxsl[callno]);
10113       reg->callno = 0;
10114    }
10115    if (!reg->addr.sin_addr.s_addr) {
10116       if (option_debug && iaxdebug)
10117          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
10118       /* Setup the next registration attempt */
10119       AST_SCHED_DEL(sched, reg->expire);
10120       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10121       return -1;
10122    }
10123 
10124    if (!reg->callno) {
10125       if (option_debug)
10126          ast_log(LOG_DEBUG, "Allocate call number\n");
10127       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
10128       if (reg->callno < 1) {
10129          ast_log(LOG_WARNING, "Unable to create call for registration\n");
10130          return -1;
10131       } else if (option_debug)
10132          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
10133       iaxs[reg->callno]->reg = reg;
10134       ast_mutex_unlock(&iaxsl[reg->callno]);
10135    }
10136    /* Schedule the next registration attempt */
10137    AST_SCHED_DEL(sched, reg->expire);
10138    /* Setup the next registration a little early */
10139    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10140    /* Send the request */
10141    memset(&ied, 0, sizeof(ied));
10142    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10143    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10144    add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */
10145    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10146    reg->regstate = REG_STATE_REGSENT;
10147    return 0;
10148 }

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

Definition at line 7065 of file chan_iax2.c.

References __iax2_do_register_s(), and schedule_action.

Referenced by iax2_ack_registry(), and iax2_do_register().

07066 {
07067 #ifdef SCHED_MULTITHREADED
07068    if (schedule_action(__iax2_do_register_s, data))
07069 #endif      
07070       __iax2_do_register_s(data);
07071    return 0;
07072 }

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

Definition at line 6230 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06231 {
06232    if (argc < 3 || argc > 4)
06233       return RESULT_SHOWUSAGE;
06234    iaxtrunkdebug = 1;
06235    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
06236    return RESULT_SUCCESS;
06237 }

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

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

07791 {
07792    struct iax_ie_data ied;
07793    /* Auto-hangup with 30 seconds of inactivity */
07794    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
07795    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
07796    memset(&ied, 0, sizeof(ied));
07797    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07798    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07799    dp->flags |= CACHE_FLAG_TRANSMITTED;
07800 }

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

12066 {
12067    char odata[256];
12068    char req[256];
12069    char *ncontext;
12070    struct iax2_dpcache *dp;
12071    struct ast_app *dial;
12072 #if 0
12073    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);
12074 #endif
12075    if (priority == 2) {
12076       /* Indicate status, can be overridden in dialplan */
12077       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
12078       if (dialstatus) {
12079          dial = pbx_findapp(dialstatus);
12080          if (dial) 
12081             pbx_exec(chan, dial, "");
12082       }
12083       return -1;
12084    } else if (priority != 1)
12085       return -1;
12086    ast_mutex_lock(&dpcache_lock);
12087    dp = find_cache(chan, data, context, exten, priority);
12088    if (dp) {
12089       if (dp->flags & CACHE_FLAG_EXISTS) {
12090          ast_copy_string(odata, data, sizeof(odata));
12091          ncontext = strchr(odata, '/');
12092          if (ncontext) {
12093             *ncontext = '\0';
12094             ncontext++;
12095             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
12096          } else {
12097             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
12098          }
12099          if (option_verbose > 2)
12100             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
12101       } else {
12102          ast_mutex_unlock(&dpcache_lock);
12103          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
12104          return -1;
12105       }
12106    }
12107    ast_mutex_unlock(&dpcache_lock);
12108    dial = pbx_findapp("Dial");
12109    if (dial) {
12110       return pbx_exec(chan, dial, req);
12111    } else {
12112       ast_log(LOG_WARNING, "No dial application registered\n");
12113    }
12114    return -1;
12115 }

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

11997 {
11998    struct iax2_dpcache *dp;
11999    int res = 0;
12000 #if 0
12001    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
12002 #endif
12003    if ((priority != 1) && (priority != 2))
12004       return 0;
12005    ast_mutex_lock(&dpcache_lock);
12006    dp = find_cache(chan, data, context, exten, priority);
12007    if (dp) {
12008       if (dp->flags & CACHE_FLAG_EXISTS)
12009          res= 1;
12010    }
12011    ast_mutex_unlock(&dpcache_lock);
12012    if (!dp) {
12013       ast_log(LOG_WARNING, "Unable to make DP cache\n");
12014    }
12015    return res;
12016 }

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

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

03708 {
03709    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03710    ast_mutex_lock(&iaxsl[callno]);
03711    if (iaxs[callno])
03712       iaxs[callno]->owner = newchan;
03713    else
03714       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03715    ast_mutex_unlock(&iaxsl[callno]);
03716    return 0;
03717 }

static void iax2_frame_free ( struct iax_frame fr  )  [static]

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

01436 {
01437    AST_SCHED_DEL(sched, fr->retrans);
01438    iax_frame_free(fr);
01439 }

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

Definition at line 1321 of file chan_iax2.c.

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

Referenced by __find_callno().

01322 {
01323    struct iax2_peer *peer = NULL;
01324    int res = 0;
01325    struct ao2_iterator i;
01326 
01327    i = ao2_iterator_init(peers, 0);
01328    while ((peer = ao2_iterator_next(&i))) {
01329       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01330           (peer->addr.sin_port == sin.sin_port)) {
01331          ast_copy_string(host, peer->name, len);
01332          peer_unref(peer);
01333          res = 1;
01334          break;
01335       }
01336       peer_unref(peer);
01337    }
01338    ao2_iterator_destroy(&i);
01339 
01340    if (!peer) {
01341       peer = realtime_peer(NULL, &sin);
01342       if (peer) {
01343          ast_copy_string(host, peer->name, len);
01344          peer_unref(peer);
01345          res = 1;
01346       }
01347    }
01348 
01349    return res;
01350 }

static int iax2_getpeertrunk ( struct sockaddr_in  sin  )  [static]

Definition at line 4923 of file chan_iax2.c.

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

Referenced by check_access().

04924 {
04925    struct iax2_peer *peer;
04926    int res = 0;
04927    struct ao2_iterator i;
04928 
04929    i = ao2_iterator_init(peers, 0);
04930    while ((peer = ao2_iterator_next(&i))) {
04931       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04932           (peer->addr.sin_port == sin.sin_port)) {
04933          res = ast_test_flag(peer, IAX_TRUNK);
04934          peer_unref(peer);
04935          break;
04936       }
04937       peer_unref(peer);
04938    }
04939    ao2_iterator_destroy(&i);
04940 
04941    return res;
04942 }

static int iax2_hangup ( struct ast_channel c  )  [static]

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

04546 {
04547    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04548    struct iax_ie_data ied;
04549    int alreadygone;
04550    memset(&ied, 0, sizeof(ied));
04551    ast_mutex_lock(&iaxsl[callno]);
04552    if (callno && iaxs[callno]) {
04553       if (option_debug)
04554          ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
04555       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
04556       /* Send the hangup unless we have had a transmission error or are already gone */
04557       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
04558       if (!iaxs[callno]->error && !alreadygone) {
04559          if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
04560             ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
04561          }
04562          if (!iaxs[callno]) {
04563             ast_mutex_unlock(&iaxsl[callno]);
04564             return 0;
04565          }
04566       }
04567       /* Explicitly predestroy it */
04568       iax2_predestroy(callno);
04569       /* If we were already gone to begin with, destroy us now */
04570       if (iaxs[callno] && alreadygone) {
04571          if (option_debug)
04572             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
04573          iax2_destroy(callno);
04574       } else if (iaxs[callno]) {
04575          iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
04576       }
04577    } else if (c->tech_pvt) {
04578       /* If this call no longer exists, but the channel still
04579        * references it we need to set the channel's tech_pvt to null
04580        * to avoid ast_channel_free() trying to free it.
04581        */
04582       c->tech_pvt = NULL;
04583    }
04584    ast_mutex_unlock(&iaxsl[callno]);
04585    if (option_verbose > 2) 
04586       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
04587    return 0;
04588 }

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

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

04865 {
04866    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04867    struct chan_iax2_pvt *pvt;
04868    int res = 0;
04869 
04870    if (option_debug && iaxdebug)
04871       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
04872 
04873    ast_mutex_lock(&iaxsl[callno]);
04874    pvt = iaxs[callno];
04875 
04876    if (wait_for_peercallno(pvt)) {
04877       res = -1;
04878       goto done;
04879    }
04880 
04881    switch (condition) {
04882    case AST_CONTROL_HOLD:
04883       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04884          ast_moh_start(c, data, pvt->mohinterpret);
04885          goto done;
04886       }
04887       break;
04888    case AST_CONTROL_UNHOLD:
04889       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04890          ast_moh_stop(c);
04891          goto done;
04892       }
04893    }
04894 
04895    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04896 
04897 done:
04898    ast_mutex_unlock(&iaxsl[callno]);
04899 
04900    return res;
04901 }

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

12043 {
12044    int res = 0;
12045    struct iax2_dpcache *dp;
12046 #if 0
12047    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
12048 #endif
12049    if ((priority != 1) && (priority != 2))
12050       return 0;
12051    ast_mutex_lock(&dpcache_lock);
12052    dp = find_cache(chan, data, context, exten, priority);
12053    if (dp) {
12054       if (dp->flags & CACHE_FLAG_MATCHMORE)
12055          res= 1;
12056    }
12057    ast_mutex_unlock(&dpcache_lock);
12058    if (!dp) {
12059       ast_log(LOG_WARNING, "Unable to make DP cache\n");
12060    }
12061    return res;
12062 }

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

Definition at line 6248 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06249 {
06250    if (argc < 3 || argc > 4)
06251       return RESULT_SHOWUSAGE;
06252    iaxdebug = 0;
06253    ast_cli(fd, "IAX2 Debugging Disabled\n");
06254    return RESULT_SUCCESS;
06255 }

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

Definition at line 6266 of file chan_iax2.c.

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

06267 {
06268    if (argc < 4 || argc > 5)
06269       return RESULT_SHOWUSAGE;
06270    jb_setoutput(jb_error_output, jb_warning_output, NULL);
06271    jb_debug_output("\n");
06272    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
06273    return RESULT_SUCCESS;
06274 }

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

Definition at line 6257 of file chan_iax2.c.

References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.

06258 {
06259    if (argc < 4 || argc > 5)
06260       return RESULT_SHOWUSAGE;
06261    iaxtrunkdebug = 0;
06262    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
06263    return RESULT_SUCCESS;
06264 }

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

Definition at line 10292 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

10293 {
10294    struct iax2_peer *peer = (struct iax2_peer *)data;
10295    peer->pokeexpire = -1;
10296 #ifdef SCHED_MULTITHREADED
10297    if (schedule_action(__iax2_poke_noanswer, data))
10298 #endif      
10299       __iax2_poke_noanswer(data);
10300    peer_unref(peer);
10301    return 0;
10302 }

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

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

10314 {
10315    int callno;
10316    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10317       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
10318         immediately after clearing things out */
10319       peer->lastms = 0;
10320       peer->historicms = 0;
10321       peer->pokeexpire = -1;
10322       peer->callno = 0;
10323       return 0;
10324    }
10325 
10326    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
10327    if ((callno = peer->callno) > 0) {
10328       ast_log(LOG_NOTICE, "Still have a callno...\n");
10329       ast_mutex_lock(&iaxsl[callno]);
10330       iax2_destroy(callno);
10331       ast_mutex_unlock(&iaxsl[callno]);
10332    }
10333    if (heldcall)
10334       ast_mutex_unlock(&iaxsl[heldcall]);
10335    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10336    if (heldcall)
10337       ast_mutex_lock(&iaxsl[heldcall]);
10338    if (peer->callno < 1) {
10339       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10340       return -1;
10341    }
10342 
10343    /* Speed up retransmission times for this qualify call */
10344    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10345    iaxs[peer->callno]->peerpoke = peer;
10346    
10347    /* Remove any pending pokeexpire task */
10348    if (peer->pokeexpire > -1) {
10349       if (!ast_sched_del(sched, peer->pokeexpire)) {
10350          peer->pokeexpire = -1;
10351          peer_unref(peer);
10352       }
10353    }
10354 
10355    /* Queue up a new task to handle no reply */
10356    /* If the host is already unreachable then use the unreachable interval instead */
10357    if (peer->lastms < 0) {
10358       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10359    } else
10360       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10361 
10362    if (peer->pokeexpire == -1)
10363       peer_unref(peer);
10364 
10365    /* And send the poke */
10366    ast_mutex_lock(&iaxsl[callno]);
10367    if (iaxs[callno]) {
10368       struct iax_ie_data ied = {
10369          .buf = { 0 },
10370          .pos = 0,
10371       };
10372       add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
10373       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
10374    }
10375    ast_mutex_unlock(&iaxsl[callno]);
10376 
10377    return 0;
10378 }

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

Definition at line 10304 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by load_module().

10305 {
10306    struct iax2_peer *peer = obj;
10307 
10308    iax2_poke_peer(peer, 0);
10309 
10310    return 0;
10311 }

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

Definition at line 7830 of file chan_iax2.c.

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

Referenced by __iax2_poke_noanswer(), and socket_process().

07831 {
07832    struct iax2_peer *peer = (struct iax2_peer *)data;
07833    peer->pokeexpire = -1;
07834 #ifdef SCHED_MULTITHREADED
07835    if (schedule_action(__iax2_poke_peer_s, data))
07836 #endif      
07837       __iax2_poke_peer_s(data);
07838    return 0;
07839 }

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

03010 {
03011    struct ast_channel *c;
03012    struct chan_iax2_pvt *pvt = iaxs[callno];
03013 
03014    if (!pvt)
03015       return -1;
03016    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
03017       iax2_destroy_helper(pvt);
03018       ast_set_flag(pvt, IAX_ALREADYGONE); 
03019    }
03020    c = pvt->owner;
03021    if (c) {
03022       c->tech_pvt = NULL;
03023       iax2_queue_hangup(callno);
03024       pvt->owner = NULL;
03025       ast_module_unref(ast_module_info->self);
03026    }
03027    return 0;
03028 }

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

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

09968 {
09969    struct iax2_thread *thread = data;
09970    struct timeval tv;
09971    struct timespec ts;
09972    int put_into_idle = 0;
09973 
09974    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09975    pthread_cleanup_push(iax2_process_thread_cleanup, data);
09976    for(;;) {
09977       /* Wait for something to signal us to be awake */
09978       ast_mutex_lock(&thread->lock);
09979 
09980       /* Flag that we're ready to accept signals */
09981       thread->ready_for_signal = 1;
09982       
09983       /* Put into idle list if applicable */
09984       if (put_into_idle)
09985          insert_idle_thread(thread);
09986 
09987       if (thread->type == IAX_TYPE_DYNAMIC) {
09988          struct iax2_thread *t = NULL;
09989          /* Wait to be signalled or time out */
09990          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09991          ts.tv_sec = tv.tv_sec;
09992          ts.tv_nsec = tv.tv_usec * 1000;
09993          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09994             /* This thread was never put back into the available dynamic
09995              * thread list, so just go away. */
09996             if (!put_into_idle) {
09997                ast_mutex_unlock(&thread->lock);
09998                break;
09999             }
10000             AST_LIST_LOCK(&dynamic_list);
10001             /* Account for the case where this thread is acquired *right* after a timeout */
10002             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
10003                iaxdynamicthreadcount--;
10004             AST_LIST_UNLOCK(&dynamic_list);
10005             if (t) {
10006                /* This dynamic thread timed out waiting for a task and was
10007                 * not acquired immediately after the timeout, 
10008                 * so it's time to go away. */
10009                ast_mutex_unlock(&thread->lock);
10010                break;
10011             }
10012             /* Someone grabbed our thread *right* after we timed out.
10013              * Wait for them to set us up with something to do and signal
10014              * us to continue. */
10015             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
10016             ts.tv_sec = tv.tv_sec;
10017             ts.tv_nsec = tv.tv_usec * 1000;
10018             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
10019             {
10020                ast_mutex_unlock(&thread->lock);
10021                break;
10022             }
10023          }
10024       } else {
10025          ast_cond_wait(&thread->cond, &thread->lock);
10026       }
10027 
10028       /* Go back into our respective list */
10029       put_into_idle = 1;
10030 
10031       ast_mutex_unlock(&thread->lock);
10032 
10033       if (thread->iostate == IAX_IOSTATE_IDLE)
10034          continue;
10035 
10036       /* Add ourselves to the active list now */
10037       AST_LIST_LOCK(&active_list);
10038       AST_LIST_INSERT_HEAD(&active_list, thread, list);
10039       AST_LIST_UNLOCK(&active_list);
10040 
10041       /* See what we need to do */
10042       switch(thread->iostate) {
10043       case IAX_IOSTATE_READY:
10044          thread->actions++;
10045          thread->iostate = IAX_IOSTATE_PROCESSING;
10046          socket_process(thread);
10047          handle_deferred_full_frames(thread);
10048          break;
10049       case IAX_IOSTATE_SCHEDREADY:
10050          thread->actions++;
10051          thread->iostate = IAX_IOSTATE_PROCESSING;
10052 #ifdef SCHED_MULTITHREADED
10053          thread->schedfunc(thread->scheddata);
10054 #endif      
10055          break;
10056       }
10057       time(&thread->checktime);
10058       thread->iostate = IAX_IOSTATE_IDLE;
10059 #ifdef DEBUG_SCHED_MULTITHREAD
10060       thread->curfunc[0]='\0';
10061 #endif      
10062 
10063       /* Now... remove ourselves from the active list, and return to the idle list */
10064       AST_LIST_LOCK(&active_list);
10065       AST_LIST_REMOVE(&active_list, thread, list);
10066       AST_LIST_UNLOCK(&active_list);
10067 
10068       /* Make sure another frame didn't sneak in there after we thought we were done. */
10069       handle_deferred_full_frames(thread);
10070    }
10071 
10072    /*!\note For some reason, idle threads are exiting without being removed
10073     * from an idle list, which is causing memory corruption.  Forcibly remove
10074     * it from the list, if it's there.
10075     */
10076    AST_LIST_LOCK(&idle_list);
10077    AST_LIST_REMOVE(&idle_list, thread, list);
10078    AST_LIST_UNLOCK(&idle_list);
10079 
10080    AST_LIST_LOCK(&dynamic_list);
10081    AST_LIST_REMOVE(&dynamic_list, thread, list);
10082    AST_LIST_UNLOCK(&dynamic_list);
10083 
10084    /* I am exiting here on my own volition, I need to clean up my own data structures
10085    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
10086    */
10087    pthread_cleanup_pop(1);
10088 
10089    return NULL;
10090 }

static void iax2_process_thread_cleanup ( void *  data  )  [static]

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

09959 {
09960    struct iax2_thread *thread = data;
09961    ast_mutex_destroy(&thread->lock);
09962    ast_cond_destroy(&thread->cond);
09963    free(thread);
09964    ast_atomic_dec_and_test(&iaxactivethreadcount);
09965 }

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

Definition at line 10247 of file chan_iax2.c.

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

10248 {
10249    int force = 0;
10250    int res;
10251    if (argc < 4)
10252       return RESULT_SHOWUSAGE;
10253    if ((argc > 4)) {
10254       if (!strcasecmp(argv[4], "forced"))
10255          force = 1;
10256       else
10257          return RESULT_SHOWUSAGE;
10258    }
10259    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
10260    if (res < 0)
10261       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
10262    else if (res < 1)
10263       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
10264    else
10265       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
10266    return RESULT_SUCCESS;
10267 }

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

Definition at line 10150 of file chan_iax2.c.

References iax_prov_complete_template().

10151 {
10152    if (pos != 3)
10153       return NULL;
10154    return iax_prov_complete_template(line, word, pos, state);
10155 }

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

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

10158 {
10159    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
10160       is found for template */
10161    struct iax_ie_data provdata;
10162    struct iax_ie_data ied;
10163    unsigned int sig;
10164    struct sockaddr_in sin;
10165    int callno;
10166    struct create_addr_info cai;
10167 
10168    memset(&cai, 0, sizeof(cai));
10169 
10170    if (option_debug)
10171       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
10172 
10173    if (iax_provision_build(&provdata, &sig, template, force)) {
10174       if (option_debug)
10175          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
10176       return 0;
10177    }
10178 
10179    if (end) {
10180       memcpy(&sin, end, sizeof(sin));
10181       cai.sockfd = sockfd;
10182    } else if (create_addr(dest, NULL, &sin, &cai))
10183       return -1;
10184 
10185    /* Build the rest of the message */
10186    memset(&ied, 0, sizeof(ied));
10187    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10188 
10189    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10190    if (!callno)
10191       return -1;
10192 
10193    if (iaxs[callno]) {
10194       /* Schedule autodestruct in case they don't ever give us anything back */
10195       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
10196       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
10197       ast_set_flag(iaxs[callno], IAX_PROVISION);
10198       /* Got a call number now, so go ahead and send the provisioning information */
10199       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10200    }
10201    ast_mutex_unlock(&iaxsl[callno]);
10202 
10203    return 1;
10204 }

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

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

03148 {
03149    struct iax2_peer *peer = NULL;
03150    struct iax2_user *user = NULL;
03151 
03152    if (argc != 4)
03153         return RESULT_SHOWUSAGE;
03154    if (!strcmp(argv[3],"all")) {
03155       prune_users();
03156       prune_peers();
03157       ast_cli(fd, "OK cache is flushed.\n");
03158       return RESULT_SUCCESS;
03159    }
03160    peer = find_peer(argv[3], 0);
03161    user = find_user(argv[3]);
03162    if (peer || user) {
03163       if (peer) {
03164          if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
03165             ast_set_flag(peer, IAX_RTAUTOCLEAR);
03166             expire_registry(peer_ref(peer));
03167             ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]);
03168          } else {
03169             ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]);
03170          }
03171          peer_unref(peer);
03172       }
03173       if (user) {
03174          if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
03175             ast_set_flag(user, IAX_RTAUTOCLEAR);
03176             ast_cli(fd, "User %s was removed from the cache.\n", argv[3]);
03177          } else {
03178             ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]);
03179          }
03180          ao2_unlink(users,user);
03181          user_unref(user);
03182       }
03183    } else {
03184       ast_cli(fd, "%s was not found in the cache.\n", argv[3]);
03185    }
03186 
03187    return RESULT_SUCCESS;
03188 }

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

02621 {
02622    for (;;) {
02623       if (iaxs[callno] && iaxs[callno]->owner) {
02624          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02625             /* Avoid deadlock by pausing and trying again */
02626             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02627          } else {
02628             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02629             ast_mutex_unlock(&iaxs[callno]->owner->lock);
02630             break;
02631          }
02632       } else
02633          break;
02634    }
02635    return 0;
02636 }

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

02558 {
02559    for (;;) {
02560       if (iaxs[callno] && iaxs[callno]->owner) {
02561          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02562             /* Avoid deadlock by pausing and trying again */
02563             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02564          } else {
02565             ast_queue_frame(iaxs[callno]->owner, f);
02566             ast_mutex_unlock(&iaxs[callno]->owner->lock);
02567             break;
02568          }
02569       } else
02570          break;
02571    }
02572    return 0;
02573 }

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

02589 {
02590    for (;;) {
02591       if (iaxs[callno] && iaxs[callno]->owner) {
02592          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
02593             /* Avoid deadlock by pausing and trying again */
02594             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02595          } else {
02596             ast_queue_hangup(iaxs[callno]->owner);
02597             ast_mutex_unlock(&iaxs[callno]->owner->lock);
02598             break;
02599          }
02600       } else
02601          break;
02602    }
02603    return 0;
02604 }

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

Definition at line 4654 of file chan_iax2.c.

References ast_log(), and LOG_NOTICE.

04655 {
04656    ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
04657    return NULL;
04658 }

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

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

07291 {
07292    struct iax2_registry *reg;
07293    char copy[256];
07294    char *username, *hostname, *secret;
07295    char *porta;
07296    char *stringp=NULL;
07297    
07298    if (!value)
07299       return -1;
07300    ast_copy_string(copy, value, sizeof(copy));
07301    stringp=copy;
07302    username = strsep(&stringp, "@");
07303    hostname = strsep(&stringp, "@");
07304    if (!hostname) {
07305       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
07306       return -1;
07307    }
07308    stringp=username;
07309    username = strsep(&stringp, ":");
07310    secret = strsep(&stringp, ":");
07311    stringp=hostname;
07312    hostname = strsep(&stringp, ":");
07313    porta = strsep(&stringp, ":");
07314    
07315    if (porta && !atoi(porta)) {
07316       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07317       return -1;
07318    }
07319    if (!(reg = ast_calloc(1, sizeof(*reg))))
07320       return -1;
07321    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
07322       free(reg);
07323       return -1;
07324    }
07325    ast_copy_string(reg->username, username, sizeof(reg->username));
07326    if (secret)
07327       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
07328    reg->expire = -1;
07329    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
07330    reg->addr.sin_family = AF_INET;
07331    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
07332    AST_LIST_LOCK(&registrations);
07333    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
07334    AST_LIST_UNLOCK(&registrations);
07335    
07336    return 0;
07337 }

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

Definition at line 11760 of file chan_iax2.c.

References reload_config().

11761 {
11762    return reload_config();
11763 }

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

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

10391 {
10392    int callno;
10393    int res;
10394    int fmt, native;
10395    struct sockaddr_in sin;
10396    struct ast_channel *c;
10397    struct parsed_dial_string pds;
10398    struct create_addr_info cai;
10399    char *tmpstr;
10400 
10401    memset(&pds, 0, sizeof(pds));
10402    tmpstr = ast_strdupa(data);
10403    parse_dial_string(tmpstr, &pds);
10404 
10405    if (ast_strlen_zero(pds.peer)) {
10406       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10407       return NULL;
10408    }
10409           
10410    memset(&cai, 0, sizeof(cai));
10411    cai.capability = iax2_capability;
10412 
10413    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10414    
10415    /* Populate our address from the given */
10416    if (create_addr(pds.peer, NULL, &sin, &cai)) {
10417       *cause = AST_CAUSE_UNREGISTERED;
10418       return NULL;
10419    }
10420 
10421    if (pds.port)
10422       sin.sin_port = htons(atoi(pds.port));
10423 
10424    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10425    if (callno < 1) {
10426       ast_log(LOG_WARNING, "Unable to create call\n");
10427       *cause = AST_CAUSE_CONGESTION;
10428       return NULL;
10429    }
10430 
10431    /* If this is a trunk, update it now */
10432    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
10433    if (ast_test_flag(&cai, IAX_TRUNK)) {
10434       int new_callno;
10435       if ((new_callno = make_trunk(callno, 1)) != -1)
10436          callno = new_callno;
10437    }
10438    iaxs[callno]->maxtime = cai.maxtime;
10439    if (cai.found)
10440       ast_string_field_set(iaxs[callno], host, pds.peer);
10441 
10442    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10443 
10444    ast_mutex_unlock(&iaxsl[callno]);
10445 
10446    if (c) {
10447       /* Choose a format we can live with */
10448       if (c->nativeformats & format) 
10449          c->nativeformats &= format;
10450       else {
10451          native = c->nativeformats;
10452          fmt = format;
10453          res = ast_translator_best_choice(&fmt, &native);
10454          if (res < 0) {
10455             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10456                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10457             ast_hangup(c);
10458             return NULL;
10459          }
10460          c->nativeformats = native;
10461       }
10462       c->readformat = ast_best_codec(c->nativeformats);
10463       c->writeformat = c->readformat;
10464    }
10465 
10466    return c;
10467 }

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

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

01105 {
01106    int res;
01107 
01108    ast_mutex_lock(&sched_lock);
01109    res = ast_sched_add(con, when, callback, data);
01110    ast_cond_signal(&sched_cond);
01111    ast_mutex_unlock(&sched_lock);
01112 
01113    return res;
01114 }

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

05522 {
05523    /* Queue a packet for delivery on a given private structure.  Use "ts" for
05524       timestamp, or calculate if ts is 0.  Send immediately without retransmission
05525       or delayed, with retransmission */
05526    struct ast_iax2_full_hdr *fh;
05527    struct ast_iax2_mini_hdr *mh;
05528    struct ast_iax2_video_hdr *vh;
05529    struct {
05530       struct iax_frame fr2;
05531       unsigned char buffer[4096];
05532    } frb;
05533    struct iax_frame *fr;
05534    int res;
05535    int sendmini=0;
05536    unsigned int lastsent;
05537    unsigned int fts;
05538 
05539    frb.fr2.afdatalen = sizeof(frb.buffer);
05540 
05541    if (!pvt) {
05542       ast_log(LOG_WARNING, "No private structure for packet?\n");
05543       return -1;
05544    }
05545    
05546    lastsent = pvt->lastsent;
05547 
05548    /* Calculate actual timestamp */
05549    fts = calc_timestamp(pvt, ts, f);
05550 
05551    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
05552     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
05553     * increment the "predicted timestamps" for voice, if we're predecting */
05554    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
05555        return 0;
05556 
05557 
05558    if ((ast_test_flag(pvt, IAX_TRUNK) || 
05559          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
05560          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
05561       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
05562        (f->frametype == AST_FRAME_VOICE) 
05563       /* is a voice frame */ &&
05564       (f->subclass == pvt->svoiceformat) 
05565       /* is the same type */ ) {
05566          /* Force immediate rather than delayed transmission */
05567          now = 1;
05568          /* Mark that mini-style frame is appropriate */
05569          sendmini = 1;
05570    }
05571    if ( f->frametype == AST_FRAME_VIDEO ) {
05572       /*
05573        * If the lower 15 bits of the timestamp roll over, or if
05574        * the video format changed then send a full frame.
05575        * Otherwise send a mini video frame
05576        */
05577       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
05578           ((f->subclass & ~0x1) == pvt->svideoformat)
05579          ) {
05580          now = 1;
05581          sendmini = 1;
05582       } else {
05583          now = 0;
05584          sendmini = 0;
05585       }
05586       pvt->lastvsent = fts;
05587    }
05588    if (f->frametype == AST_FRAME_IAX) {
05589       /* 0x8000 marks this message as TX:, this bit will be stripped later */
05590       pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
05591       if (!pvt->first_iax_message) {
05592          pvt->first_iax_message = pvt->last_iax_message;
05593       }
05594    }
05595    /* Allocate an iax_frame */
05596    if (now) {
05597       fr = &frb.fr2;
05598    } else
05599       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));
05600    if (!fr) {
05601       ast_log(LOG_WARNING, "Out of memory\n");
05602       return -1;
05603    }
05604    /* Copy our prospective frame into our immediate or retransmitted wrapper */
05605    iax_frame_wrap(fr, f);
05606 
05607    fr->ts = fts;
05608    fr->callno = pvt->callno;
05609    fr->transfer = transfer;
05610    fr->final = final;
05611    fr->encmethods = 0;
05612    if (!sendmini) {
05613       /* We need a full frame */
05614       if (seqno > -1)
05615          fr->oseqno = seqno;
05616       else
05617          fr->oseqno = pvt->oseqno++;
05618       fr->iseqno = pvt->iseqno;
05619       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
05620       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
05621       fh->ts = htonl(fr->ts);
05622       fh->oseqno = fr->oseqno;
05623       if (transfer) {
05624          fh->iseqno = 0;
05625       } else
05626          fh->iseqno = fr->iseqno;
05627       /* Keep track of the last thing we've acknowledged */
05628       if (!transfer)
05629          pvt->aseqno = fr->iseqno;
05630       fh->type = fr->af.frametype & 0xFF;
05631       if (fr->af.frametype == AST_FRAME_VIDEO)
05632          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
05633       else
05634          fh->csub = compress_subclass(fr->af.subclass);
05635       if (transfer) {
05636          fr->dcallno = pvt->transfercallno;
05637       } else
05638          fr->dcallno = pvt->peercallno;
05639       fh->dcallno = htons(fr->dcallno);
05640       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
05641       fr->data = fh;
05642       fr->retries = 0;
05643       /* Retry after 2x the ping time has passed */
05644       fr->retrytime = pvt->pingtime * 2;
05645       if (fr->retrytime < MIN_RETRY_TIME)
05646          fr->retrytime = MIN_RETRY_TIME;
05647       if (fr->retrytime > MAX_RETRY_TIME)
05648          fr->retrytime = MAX_RETRY_TIME;
05649       /* Acks' don't get retried */
05650       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
05651          fr->retries = -1;
05652       else if (f->frametype == AST_FRAME_VOICE)
05653          pvt->svoiceformat = f->subclass;
05654       else if (f->frametype == AST_FRAME_VIDEO)
05655          pvt->svideoformat = f->subclass & ~0x1;
05656       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05657          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05658             if (iaxdebug) {
05659                if (fr->transfer)
05660                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05661                else
05662                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05663             }
05664             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05665             fr->encmethods = pvt->encmethods;
05666             fr->ecx = pvt->ecx;
05667             fr->mydcx = pvt->mydcx;
05668             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05669          } else
05670             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05671       }
05672 
05673       if (now) {
05674          res = send_packet(fr);
05675       } else
05676          res = iax2_transmit(fr);
05677    } else {
05678       if (ast_test_flag(pvt, IAX_TRUNK)) {
05679          iax2_trunk_queue(pvt, fr);
05680          res = 0;
05681       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05682          /* Video frame have no sequence number */
05683          fr->oseqno = -1;
05684          fr->iseqno = -1;
05685          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
05686          vh->zeros = 0;
05687          vh->callno = htons(0x8000 | fr->callno);
05688          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05689          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05690          fr->data = vh;
05691          fr->retries = -1;
05692          res = send_packet(fr);        
05693       } else {
05694          /* Mini-frames have no sequence number */
05695          fr->oseqno = -1;
05696          fr->iseqno = -1;
05697          /* Mini frame will do */
05698          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
05699          mh->callno = htons(fr->callno);
05700          mh->ts = htons(fr->ts & 0xFFFF);
05701          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05702          fr->data = mh;
05703          fr->retries = -1;
05704          if (pvt->transferring == TRANSFER_MEDIAPASS)
05705             fr->transfer = 1;
05706          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05707             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05708                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05709             } else
05710                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05711          }
05712          res = send_packet(fr);
05713       }
05714    }
05715    return res;
05716 }

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

Definition at line 3702 of file chan_iax2.c.

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

03703 {
03704    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03705 }

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

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

03698 {
03699    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
03700 }

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

Definition at line 3690 of file chan_iax2.c.

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

03691 {
03692    
03693    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03694       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03695 }

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

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

04613 {
04614    struct ast_option_header *h;
04615    int res;
04616 
04617    switch (option) {
04618    case AST_OPTION_TXGAIN:
04619    case AST_OPTION_RXGAIN:
04620       /* these two cannot be sent, because they require a result */
04621       errno = ENOSYS;
04622       return -1;
04623    default:
04624    {
04625       unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04626       struct chan_iax2_pvt *pvt;
04627 
04628       ast_mutex_lock(&iaxsl[callno]);
04629       pvt = iaxs[callno];
04630 
04631       if (wait_for_peercallno(pvt)) {
04632          ast_mutex_unlock(&iaxsl[callno]);
04633          return -1;
04634       }
04635 
04636       ast_mutex_unlock(&iaxsl[callno]);
04637 
04638       if (!(h = ast_malloc(datalen + sizeof(*h)))) {
04639          return -1;
04640       }
04641 
04642       h->flag = AST_OPTION_FLAG_REQUEST;
04643       h->option = htons(option);
04644       memcpy(h->data, data, datalen);
04645       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
04646                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
04647                  datalen + sizeof(*h), -1);
04648       free(h);
04649       return res;
04650    }
04651    }
04652 }

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

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

03376 {
03377    struct iax2_dpcache *dp;
03378    char tmp[1024], *pc;
03379    int s;
03380    int x,y;
03381    struct timeval tv;
03382    gettimeofday(&tv, NULL);
03383    ast_mutex_lock(&dpcache_lock);
03384    dp = dpcache;
03385    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03386    while(dp) {
03387       s = dp->expiry.tv_sec - tv.tv_sec;
03388       tmp[0] = '\0';
03389       if (dp->flags & CACHE_FLAG_EXISTS)
03390          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03391       if (dp->flags & CACHE_FLAG_NONEXISTENT)
03392          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03393       if (dp->flags & CACHE_FLAG_CANEXIST)
03394          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03395       if (dp->flags & CACHE_FLAG_PENDING)
03396          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03397       if (dp->flags & CACHE_FLAG_TIMEOUT)
03398          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03399       if (dp->flags & CACHE_FLAG_TRANSMITTED)
03400          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03401       if (dp->flags & CACHE_FLAG_MATCHMORE)
03402          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03403       if (dp->flags & CACHE_FLAG_UNKNOWN)
03404          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03405       /* Trim trailing pipe */
03406       if (!ast_strlen_zero(tmp))
03407          tmp[strlen(tmp) - 1] = '\0';
03408       else
03409          ast_copy_string(tmp, "(none)", sizeof(tmp));
03410       y=0;
03411       pc = strchr(dp->peercontext, '@');
03412       if (!pc)
03413          pc = dp->peercontext;
03414       else
03415          pc++;
03416       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
03417          if (dp->waiters[x] > -1)
03418             y++;
03419       if (s > 0)
03420          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03421       else
03422          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03423       dp = dp->next;
03424    }
03425    ast_mutex_unlock(&dpcache_lock);
03426    return RESULT_SUCCESS;
03427 }

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

Definition at line 2176 of file chan_iax2.c.

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

02177 {
02178    struct ao2_iterator i;
02179    struct peercnt *peercnt;
02180    struct sockaddr_in sin;
02181    int found = 0;
02182 
02183    if (argc < 4 || argc > 5)
02184       return RESULT_SHOWUSAGE;
02185 
02186    ast_cli(fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02187    i = ao2_iterator_init(peercnts, 0);
02188    while ((peercnt = ao2_iterator_next(&i))) {
02189       sin.sin_addr.s_addr = peercnt->addr;
02190       if (argc == 5 && (!strcasecmp(argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02191             ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02192             found = 1;
02193             break;
02194       } else {
02195          ast_cli(fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02196       }
02197       ao2_ref(peercnt, -1);
02198    }
02199    ao2_iterator_destroy(&i);
02200    if (argc == 4) {
02201       ast_cli(fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used);
02202    } else if (argc == 5 && !found) {
02203       ast_cli(fd, "No callnumber table entries for %s found\n", argv[4] );
02204    }
02205    return RESULT_SUCCESS;
02206 }

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

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

06063 {
06064 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s  %s  %9s\n"
06065 #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"
06066 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
06067    int x;
06068    int numchans = 0;
06069    int usedchans = 0;
06070    char first_message[10] = { 0, };
06071    char last_message[10] = { 0, };
06072 
06073    if (argc != 3)
06074       return RESULT_SHOWUSAGE;
06075    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
06076    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
06077       ast_mutex_lock(&iaxsl[x]);
06078       if (iaxs[x]) {
06079          int lag, jitter, localdelay;
06080          jb_info jbinfo;
06081          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
06082             jb_getinfo(iaxs[x]->jb, &jbinfo);
06083             jitter = jbinfo.jitter;
06084             localdelay = jbinfo.current - jbinfo.min;
06085          } else {
06086             jitter = -1;
06087             localdelay = 0;
06088          }
06089 
06090          iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
06091          iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
06092          lag = iaxs[x]->remote_rr.delay;
06093          ast_cli(fd, FORMAT,
06094             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
06095             ast_inet_ntoa(iaxs[x]->addr.sin_addr),
06096             S_OR(iaxs[x]->username, "(None)"),
06097             iaxs[x]->callno, iaxs[x]->peercallno,
06098             iaxs[x]->oseqno, iaxs[x]->iseqno,
06099             lag,
06100             jitter,
06101             localdelay,
06102             ast_getformatname(iaxs[x]->voiceformat),
06103             (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06104             first_message,
06105             (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
06106             last_message);
06107          numchans++;
06108          if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */
06109             usedchans++;
06110          }  
06111       }
06112       ast_mutex_unlock(&iaxsl[x]);
06113    }
06114    ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : "");
06115    ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : "");
06116    return RESULT_SUCCESS;
06117 #undef FORMAT
06118 #undef FORMAT2
06119 #undef FORMATB
06120 }

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

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

05974 {
05975 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
05976 #if !defined(__FreeBSD__)
05977 #define FORMAT "%-15.15s  %-15d %-15d\n"
05978 #else /* __FreeBSD__ */
05979 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
05980 #endif /* __FreeBSD__ */
05981    struct iax_firmware *cur;
05982    if ((argc != 3) && (argc != 4))
05983       return RESULT_SHOWUSAGE;
05984    ast_mutex_lock(&waresl.lock);
05985    
05986    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
05987    for (cur = waresl.wares;cur;cur = cur->next) {
05988       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
05989          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
05990             (int)ntohl(cur->fwh->datalen));
05991    }
05992    ast_mutex_unlock(&waresl.lock);
05993    return RESULT_SUCCESS;
05994 #undef FORMAT
05995 #undef FORMAT2
05996 }

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

Definition at line 6209 of file chan_iax2.c.

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

06210 {
06211    int numchans = 0;
06212    if (argc != 3)
06213       return RESULT_SHOWUSAGE;
06214    ast_cli(fd, "                           -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
06215    ast_cli(fd, "Channel               RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts FirstMsg    LastMsg\n");
06216    numchans = ast_cli_netstats(NULL, fd, 1);
06217    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
06218    return RESULT_SUCCESS;
06219 }

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

Show one peer in detail.

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

03260 {
03261    char status[30];
03262    char cbuf[256];
03263    struct iax2_peer *peer;
03264    char codec_buf[512];
03265    int x = 0, codec = 0, load_realtime = 0;
03266 
03267    if (argc < 4)
03268       return RESULT_SHOWUSAGE;
03269 
03270    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
03271 
03272    peer = find_peer(argv[3], load_realtime);
03273    if (peer) {
03274       ast_cli(fd,"\n\n");
03275       ast_cli(fd, "  * Name       : %s\n", peer->name);
03276       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
03277       ast_cli(fd, "  Context      : %s\n", peer->context);
03278       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
03279       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
03280       ast_cli(fd, "  Callnum limit: %d\n", peer->maxcallno);
03281       ast_cli(fd, "  Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03282 
03283 
03284       ast_cli(fd, "  Trunk        : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
03285       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03286       ast_cli(fd, "  Expire       : %d\n", peer->expire);
03287       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
03288       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));
03289       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03290       ast_cli(fd, "  Username     : %s\n", peer->username);
03291       ast_cli(fd, "  Codecs       : ");
03292       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03293       ast_cli(fd, "%s\n", codec_buf);
03294 
03295       ast_cli(fd, "  Codec Order  : (");
03296       for(x = 0; x < 32 ; x++) {
03297          codec = ast_codec_pref_index(&peer->prefs,x);
03298          if(!codec)
03299             break;
03300          ast_cli(fd, "%s", ast_getformatname(codec));
03301          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03302             ast_cli(fd, "|");
03303       }
03304 
03305       if (!x)
03306          ast_cli(fd, "none");
03307       ast_cli(fd, ")\n");
03308 
03309       ast_cli(fd, "  Status       : ");
03310       peer_status(peer, status, sizeof(status));   
03311       ast_cli(fd, "%s\n",status);
03312       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03313       ast_cli(fd,"\n");
03314       peer_unref(peer);
03315    } else {
03316       ast_cli(fd,"Peer %s not found.\n", argv[3]);
03317       ast_cli(fd,"\n");
03318    }
03319 
03320    return RESULT_SUCCESS;
03321 }

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

Definition at line 5962 of file chan_iax2.c.

References __iax2_show_peers().

05963 {
05964    return __iax2_show_peers(0, fd, NULL, argc, argv);
05965 }

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

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

06035 {
06036 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
06037 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
06038    struct iax2_registry *reg = NULL;
06039 
06040    char host[80];
06041    char perceived[80];
06042    if (argc != 3)
06043       return RESULT_SHOWUSAGE;
06044    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
06045    AST_LIST_LOCK(&registrations);
06046    AST_LIST_TRAVERSE(&registrations, reg, entry) {
06047       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
06048       if (reg->us.sin_addr.s_addr) 
06049          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06050       else
06051          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
06052       ast_cli(fd, FORMAT, host, 
06053                (reg->dnsmgr) ? "Y" : "N", 
06054                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
06055    }
06056    AST_LIST_UNLOCK(&registrations);
06057    return RESULT_SUCCESS;
06058 #undef FORMAT
06059 #undef FORMAT2
06060 }

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

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

03350 {
03351    struct iax_frame *cur;
03352    int cnt = 0, dead=0, final=0;
03353 
03354    if (argc != 3)
03355       return RESULT_SHOWUSAGE;
03356 
03357    AST_LIST_LOCK(&iaxq.queue);
03358    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
03359       if (cur->retries < 0)
03360          dead++;
03361       if (cur->final)
03362          final++;
03363       cnt++;
03364    }
03365    AST_LIST_UNLOCK(&iaxq.queue);
03366 
03367    ast_cli(fd, "    IAX Statistics\n");
03368    ast_cli(fd, "---------------------\n");
03369    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03370    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03371    
03372    return RESULT_SUCCESS;
03373 }

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

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

05904 {
05905    struct iax2_thread *thread = NULL;
05906    time_t t;
05907    int threadcount = 0, dynamiccount = 0;
05908    char type;
05909 
05910    if (argc != 3)
05911       return RESULT_SHOWUSAGE;
05912       
05913    ast_cli(fd, "IAX2 Thread Information\n");
05914    time(&t);
05915    ast_cli(fd, "Idle Threads:\n");
05916    AST_LIST_LOCK(&idle_list);
05917    AST_LIST_TRAVERSE(&idle_list, thread, list) {
05918 #ifdef DEBUG_SCHED_MULTITHREAD
05919       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
05920          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05921 #else
05922       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
05923          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05924 #endif
05925       threadcount++;
05926    }
05927    AST_LIST_UNLOCK(&idle_list);
05928    ast_cli(fd, "Active Threads:\n");
05929    AST_LIST_LOCK(&active_list);
05930    AST_LIST_TRAVERSE(&active_list, thread, list) {
05931       if (thread->type == IAX_TYPE_DYNAMIC)
05932          type = 'D';
05933       else
05934          type = 'P';
05935 #ifdef DEBUG_SCHED_MULTITHREAD
05936       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
05937          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05938 #else
05939       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
05940          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05941 #endif
05942       threadcount++;
05943    }
05944    AST_LIST_UNLOCK(&active_list);
05945    ast_cli(fd, "Dynamic Threads:\n");
05946         AST_LIST_LOCK(&dynamic_list);
05947         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05948 #ifdef DEBUG_SCHED_MULTITHREAD
05949                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
05950                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05951 #else
05952                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05953                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05954 #endif
05955       dynamiccount++;
05956         }
05957         AST_LIST_UNLOCK(&dynamic_list);
05958    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05959    return RESULT_SUCCESS;
05960 }

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

Definition at line 5718 of file chan_iax2.c.

References ao2_iterator_destroy(), 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, user_unref(), and users.

05719 {
05720    regex_t regexbuf;
05721    int havepattern = 0;
05722 
05723 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
05724 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
05725 
05726    struct iax2_user *user = NULL;
05727    char auth[90];
05728    char *pstr = "";
05729    struct ao2_iterator i;
05730 
05731    switch (argc) {
05732    case 5:
05733       if (!strcasecmp(argv[3], "like")) {
05734          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05735             return RESULT_SHOWUSAGE;
05736          havepattern = 1;
05737       } else
05738          return RESULT_SHOWUSAGE;
05739    case 3:
05740       break;
05741    default:
05742       return RESULT_SHOWUSAGE;
05743    }
05744 
05745    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05746    i = ao2_iterator_init(users, 0);
05747    for (user = ao2_iterator_next(&i); user; 
05748       user_unref(user), user = ao2_iterator_next(&i)) {
05749       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
05750          continue;
05751       
05752       if (!ast_strlen_zero(user->secret)) {
05753          ast_copy_string(auth,user->secret,sizeof(auth));
05754       } else if (!ast_strlen_zero(user->inkeys)) {
05755          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05756       } else
05757          ast_copy_string(auth, "-no secret-", sizeof(auth));
05758       
05759       if(ast_test_flag(user,IAX_CODEC_NOCAP))
05760          pstr = "REQ Only";
05761       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05762          pstr = "Disabled";
05763       else
05764          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05765       
05766       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
05767          user->contexts ? user->contexts->context : context,
05768          user->ha ? "Yes" : "No", pstr);
05769    }
05770    ao2_iterator_destroy(&i);
05771 
05772    if (havepattern)
05773       regfree(&regexbuf);
05774 
05775    return RESULT_SUCCESS;
05776 #undef FORMAT
05777 #undef FORMAT2
05778 }

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

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

04661 {
04662    int res;
04663    struct iax_ie_data ied0;
04664    struct iax_ie_data ied1;
04665    unsigned int transferid = (unsigned int)ast_random();
04666    memset(&ied0, 0, sizeof(ied0));
04667    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
04668    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
04669    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
04670 
04671    memset(&ied1, 0, sizeof(ied1));
04672    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
04673    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
04674    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
04675    
04676    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
04677    if (res)
04678       return -1;
04679    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
04680    if (res)
04681       return -1;
04682    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04683    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04684    return 0;
04685 }

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

Definition at line 3190 of file chan_iax2.c.

References RESULT_SHOWUSAGE, and RESULT_SUCCESS.

03191 {
03192        if (argc != 4)
03193                return RESULT_SHOWUSAGE;
03194 
03195        test_losspct = atoi(argv[3]);
03196 
03197        return RESULT_SUCCESS;
03198 }

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

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

04904 {
04905    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04906    struct iax_ie_data ied;
04907    char tmp[256], *context;
04908    ast_copy_string(tmp, dest, sizeof(tmp));
04909    context = strchr(tmp, '@');
04910    if (context) {
04911       *context = '\0';
04912       context++;
04913    }
04914    memset(&ied, 0, sizeof(ied));
04915    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04916    if (context)
04917       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04918    if (option_debug)
04919       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
04920    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04921 }

static int iax2_transmit ( struct iax_frame fr  )  [static]

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

03662 {
03663    /* Lock the queue and place this packet at the end */
03664    /* By setting this to 0, the network thread will send it for us, and
03665       queue retransmission if necessary */
03666    fr->sentyet = 0;
03667    AST_LIST_LOCK(&iaxq.queue);
03668    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
03669    iaxq.count++;
03670    AST_LIST_UNLOCK(&iaxq.queue);
03671    /* Wake up the network and scheduler thread */
03672    if (netthreadid != AST_PTHREADT_NULL)
03673       pthread_kill(netthreadid, SIGURG);
03674    signal_condition(&sched_lock, &sched_cond);
03675    return 0;
03676 }

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

Definition at line 7885 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

07886 {
07887    /* Drop when trunk is about 5 seconds idle */
07888    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
07889       return 1;
07890    return 0;
07891 }

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

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

05274 {
05275    struct ast_frame *f;
05276    struct iax2_trunk_peer *tpeer;
05277    void *tmp, *ptr;
05278    struct ast_iax2_meta_trunk_entry *met;
05279    struct ast_iax2_meta_trunk_mini *mtm;
05280 
05281    f = &fr->af;
05282    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
05283    if (tpeer) {
05284       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
05285          /* Need to reallocate space */
05286          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
05287             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
05288                ast_mutex_unlock(&tpeer->lock);
05289                return -1;
05290             }
05291             
05292             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
05293             tpeer->trunkdata = tmp;
05294             if (option_debug)
05295                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);
05296          } else {
05297             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));
05298             ast_mutex_unlock(&tpeer->lock);
05299             return -1;
05300          }
05301       }
05302 
05303       /* Append to meta frame */
05304       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
05305       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
05306          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
05307          mtm->len = htons(f->datalen);
05308          mtm->mini.callno = htons(pvt->callno);
05309          mtm->mini.ts = htons(0xffff & fr->ts);
05310          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
05311          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
05312       } else {
05313          met = (struct ast_iax2_meta_trunk_entry *)ptr;
05314          /* Store call number and length in meta header */
05315          met->callno = htons(pvt->callno);
05316          met->len = htons(f->datalen);
05317          /* Advance pointers/decrease length past trunk entry header */
05318          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
05319          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
05320       }
05321       /* Copy actual trunk data */
05322       memcpy(ptr, f->data, f->datalen);
05323       tpeer->trunkdatalen += f->datalen;
05324 
05325       tpeer->calls++;
05326       ast_mutex_unlock(&tpeer->lock);
05327    }
05328    return 0;
05329 }

static int iax2_vnak ( int  callno  )  [static]

Definition at line 7802 of file chan_iax2.c.

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

Referenced by socket_process().

07803 {
07804    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07805 }

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

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

06277 {
06278    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
06279    int res = -1;
06280    ast_mutex_lock(&iaxsl[callno]);
06281    if (iaxs[callno]) {
06282    /* If there's an outstanding error, return failure now */
06283       if (!iaxs[callno]->error) {
06284          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
06285             res = 0;
06286             /* Don't waste bandwidth sending null frames */
06287          else if (f->frametype == AST_FRAME_NULL)
06288             res = 0;
06289          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
06290             res = 0;
06291          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
06292             res = 0;
06293          else
06294          /* Simple, just queue for transmission */
06295             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
06296       } else {
06297          if (option_debug)
06298             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
06299       }
06300    }
06301    /* If it's already gone, just return */
06302    ast_mutex_unlock(&iaxsl[callno]);
06303    return res;
06304 }

static int iax_check_version ( char *  dev  )  [static]

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

02793 {
02794    int res = 0;
02795    struct iax_firmware *cur;
02796    if (!ast_strlen_zero(dev)) {
02797       ast_mutex_lock(&waresl.lock);
02798       cur = waresl.wares;
02799       while(cur) {
02800          if (!strcmp(dev, (char *)cur->fwh->devname)) {
02801             res = ntohs(cur->fwh->version);
02802             break;
02803          }
02804          cur = cur->next;
02805       }
02806       ast_mutex_unlock(&waresl.lock);
02807    }
02808    return res;
02809 }

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

Definition at line 868 of file chan_iax2.c.

References ast_verbose().

Referenced by load_module().

00869 {
00870    if (iaxdebug)
00871       ast_verbose("%s", data);
00872 }

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

Definition at line 874 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

00875 {
00876    ast_log(LOG_WARNING, "%s", data);
00877 }

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

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

02812 {
02813    int res = -1;
02814    unsigned int bs = desc & 0xff;
02815    unsigned int start = (desc >> 8) & 0xffffff;
02816    unsigned int bytes;
02817    struct iax_firmware *cur;
02818    if (!ast_strlen_zero((char *)dev) && bs) {
02819       start *= bs;
02820       ast_mutex_lock(&waresl.lock);
02821       cur = waresl.wares;
02822       while(cur) {
02823          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
02824             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02825             if (start < ntohl(cur->fwh->datalen)) {
02826                bytes = ntohl(cur->fwh->datalen) - start;
02827                if (bytes > bs)
02828                   bytes = bs;
02829                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02830             } else {
02831                bytes = 0;
02832                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02833             }
02834             if (bytes == bs)
02835                res = 0;
02836             else
02837                res = 1;
02838             break;
02839          }
02840          cur = cur->next;
02841       }
02842       ast_mutex_unlock(&waresl.lock);
02843    }
02844    return res;
02845 }

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

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

08074 {
08075    struct iax_dual *d;
08076    struct ast_channel *chan1m, *chan2m;
08077    pthread_t th;
08078    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
08079    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
08080    if (chan2m && chan1m) {
08081       /* Make formats okay */
08082       chan1m->readformat = chan1->readformat;
08083       chan1m->writeformat = chan1->writeformat;
08084       ast_channel_masquerade(chan1m, chan1);
08085       /* Setup the extensions and such */
08086       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
08087       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
08088       chan1m->priority = chan1->priority;
08089       
08090       /* We make a clone of the peer channel too, so we can play
08091          back the announcement */
08092       /* Make formats okay */
08093       chan2m->readformat = chan2->readformat;
08094       chan2m->writeformat = chan2->writeformat;
08095       ast_channel_masquerade(chan2m, chan2);
08096       /* Setup the extensions and such */
08097       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
08098       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
08099       chan2m->priority = chan2->priority;
08100       if (ast_do_masquerade(chan2m)) {
08101          ast_log(LOG_WARNING, "Masquerade failed :(\n");
08102          ast_hangup(chan2m);
08103          return -1;
08104       }
08105    } else {
08106       if (chan1m)
08107          ast_hangup(chan1m);
08108       if (chan2m)
08109          ast_hangup(chan2m);
08110       return -1;
08111    }
08112    if ((d = ast_calloc(1, sizeof(*d)))) {
08113       pthread_attr_t attr;
08114 
08115       pthread_attr_init(&attr);
08116       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08117 
08118       d->chan1 = chan1m;
08119       d->chan2 = chan2m;
08120       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
08121          pthread_attr_destroy(&attr);
08122          return 0;
08123       }
08124       pthread_attr_destroy(&attr);
08125       free(d);
08126    }
08127    return -1;
08128 }

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

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

08054 {
08055    struct ast_channel *chan1, *chan2;
08056    struct iax_dual *d;
08057    struct ast_frame *f;
08058    int ext;
08059    int res;
08060    d = stuff;
08061    chan1 = d->chan1;
08062    chan2 = d->chan2;
08063    free(d);
08064    f = ast_read(chan1);
08065    if (f)
08066       ast_frfree(f);
08067    res = ast_park_call(chan1, chan2, 0, &ext);
08068    ast_hangup(chan2);
08069    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
08070    return NULL;
08071 }

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

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

01656 {
01657    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01658    if (new) {
01659       size_t afdatalen = new->afdatalen;
01660       memcpy(new, fr, sizeof(*new));
01661       iax_frame_wrap(new, &fr->af);
01662       new->afdatalen = afdatalen;
01663       new->data = NULL;
01664       new->datalen = 0;
01665       new->direction = DIRECTION_INGRESS;
01666       new->retrans = -1;
01667    }
01668    return new;
01669 }

static void insert_idle_thread ( struct iax2_thread thread  )  [static]

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

01013 {
01014    if (thread->type == IAX_TYPE_DYNAMIC) {
01015       AST_LIST_LOCK(&dynamic_list);
01016       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01017       AST_LIST_UNLOCK(&dynamic_list);
01018    } else {
01019       AST_LIST_LOCK(&idle_list);
01020       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01021       AST_LIST_UNLOCK(&idle_list);
01022    }
01023 
01024    return;
01025 }

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

Definition at line 903 of file chan_iax2.c.

References ast_verbose().

Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().

00904 {
00905    va_list args;
00906    char buf[1024];
00907 
00908    va_start(args, fmt);
00909    vsnprintf(buf, 1024, fmt, args);
00910    va_end(args);
00911 
00912    ast_verbose("%s", buf);
00913 }

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

Definition at line 879 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

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

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

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

Definition at line 891 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

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

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

static int load_module ( void   )  [static]

Load IAX2 module, load configuraiton ---.

Definition at line 12694 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(), peers, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), VERBOSE_PREFIX_2, and waresl.

12695 {
12696    static const char config[] = "iax.conf";
12697    int res = 0;
12698    int x;
12699    struct iax2_registry *reg = NULL;
12700 
12701    if (load_objects()) {
12702       return AST_MODULE_LOAD_FAILURE;
12703    }
12704 
12705    randomcalltokendata = ast_random();
12706    ast_custom_function_register(&iaxpeer_function);
12707 
12708    iax_set_output(iax_debug_output);
12709    iax_set_error(iax_error_output);
12710    jb_setoutput(jb_error_output, jb_warning_output, NULL);
12711    
12712 #ifdef HAVE_DAHDI
12713 #ifdef DAHDI_TIMERACK
12714    timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
12715    if (timingfd < 0)
12716 #endif
12717       timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
12718    if (timingfd < 0) 
12719       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
12720 #endif
12721 
12722    memset(iaxs, 0, sizeof(iaxs));
12723 
12724    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12725       ast_mutex_init(&iaxsl[x]);
12726    }
12727    
12728    ast_cond_init(&sched_cond, NULL);
12729 
12730    io = io_context_create();
12731    sched = sched_context_create();
12732    
12733    if (!io || !sched) {
12734       ast_log(LOG_ERROR, "Out of memory\n");
12735       return -1;
12736    }
12737 
12738    netsock = ast_netsock_list_alloc();
12739    if (!netsock) {
12740       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
12741       return -1;
12742    }
12743    ast_netsock_init(netsock);
12744 
12745    outsock = ast_netsock_list_alloc();
12746    if (!outsock) {
12747       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12748       return -1;
12749    }
12750    ast_netsock_init(outsock);
12751 
12752    ast_mutex_init(&waresl.lock);
12753 
12754    AST_LIST_HEAD_INIT(&iaxq.queue);
12755    
12756    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12757 
12758    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12759    
12760    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
12761    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
12762 
12763    if(set_config(config, 0) == -1)
12764       return AST_MODULE_LOAD_DECLINE;
12765 
12766    if (ast_channel_register(&iax2_tech)) {
12767       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12768       __unload_module();
12769       return -1;
12770    }
12771 
12772    if (ast_register_switch(&iax2_switch)) 
12773       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12774 
12775    res = start_network_thread();
12776    if (!res) {
12777       if (option_verbose > 1) 
12778          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
12779    } else {
12780       ast_log(LOG_ERROR, "Unable to start network thread\n");
12781       ast_netsock_release(netsock);
12782       ast_netsock_release(outsock);
12783    }
12784 
12785    AST_LIST_LOCK(&registrations);
12786    AST_LIST_TRAVERSE(&registrations, reg, entry)
12787       iax2_do_register(reg);
12788    AST_LIST_UNLOCK(&registrations); 
12789 
12790    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12791    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12792 
12793    reload_firmware(0);
12794    iax_provision_reload();
12795    return res;
12796 }

static int load_objects ( void   )  [static]

Definition at line 12637 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, 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, peers, pvt_cmp_cb(), pvt_hash_cb(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.

Referenced by load_module().

12638 {
12639    peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
12640    peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
12641 
12642    if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
12643       goto container_fail;
12644    } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
12645       goto container_fail;
12646    } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
12647       goto container_fail;
12648    } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
12649       goto container_fail;
12650    } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
12651       goto container_fail;
12652    } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
12653       goto container_fail;
12654    } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
12655       goto container_fail;
12656    } else if (create_callno_pools()) {
12657       goto container_fail;
12658    }
12659 
12660    return 0;
12661 
12662 container_fail:
12663    if (peers) {
12664       ao2_ref(peers, -1);
12665    }
12666    if (users) {
12667       ao2_ref(users, -1);
12668    }
12669    if (iax_peercallno_pvts) {
12670       ao2_ref(iax_peercallno_pvts, -1);
12671    }
12672    if (iax_transfercallno_pvts) {
12673       ao2_ref(iax_transfercallno_pvts, -1);
12674    }
12675    if (peercnts) {
12676       ao2_ref(peercnts, -1);
12677    }
12678    if (callno_limits) {
12679       ao2_ref(callno_limits, -1);
12680    }
12681    if (calltoken_ignores) {
12682       ao2_ref(calltoken_ignores, -1);
12683    }
12684    if (callno_pool) {
12685       ao2_ref(callno_pool, -1);
12686    }
12687    if (callno_pool_trunk) {
12688       ao2_ref(callno_pool_trunk, -1);
12689    }
12690    return AST_MODULE_LOAD_FAILURE;
12691 }

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

Definition at line 4687 of file chan_iax2.c.

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

Referenced by iax2_bridge().

04688 {
04689    ast_mutex_lock(&iaxsl[callno0]);
04690    while (ast_mutex_trylock(&iaxsl[callno1])) {
04691       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
04692    }
04693 }

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

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

01720 {
01721    int x;
01722    int res= 0;
01723    struct callno_entry *callno_entry;
01724    if (iaxs[callno]->oseqno) {
01725       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01726       return -1;
01727    }
01728    if (callno & TRUNK_CALL_START) {
01729       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01730       return -1;
01731    }
01732    if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
01733       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01734       return -1;
01735    }
01736 
01737    x = callno_entry->callno;
01738    ast_mutex_lock(&iaxsl[x]);
01739 
01740    /*!
01741     * \note We delete these before switching the slot, because if
01742     * they fire in the meantime, they will generate a warning.
01743     */
01744    AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01745    AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01746    iaxs[x] = iaxs[callno];
01747    iaxs[x]->callno = x;
01748 
01749    /* since we copied over the pvt from a different callno, make sure the old entry is replaced
01750     * before assigning the new one */
01751    if (iaxs[x]->callno_entry) {
01752       iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
01753    }
01754    iaxs[x]->callno_entry = callno_entry;
01755 
01756    iaxs[callno] = NULL;
01757    /* Update the two timers that should have been started */
01758    iaxs[x]->pingid = iax2_sched_add(sched, 
01759       ping_time * 1000, send_ping, (void *)(long)x);
01760    iaxs[x]->lagid = iax2_sched_add(sched, 
01761       lagrq_time * 1000, send_lagrq, (void *)(long)x);
01762 
01763    if (locked)
01764       ast_mutex_unlock(&iaxsl[callno]);
01765    res = x;
01766    if (!locked)
01767       ast_mutex_unlock(&iaxsl[x]);
01768 
01769    if (option_debug)
01770       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01771    /* We move this call from a non-trunked to a trunked call */
01772    update_max_trunk();
01773    update_max_nontrunk();
01774    return res;
01775 }

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

Definition at line 5966 of file chan_iax2.c.

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

Referenced by load_module().

05967 {
05968    ast_cli_netstats(s, -1, 0);
05969    astman_append(s, "\r\n");
05970    return RESULT_SUCCESS;
05971 }

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

Definition at line 5999 of file chan_iax2.c.

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

Referenced by load_module().

06000 {
06001    char *a[] = { "iax2", "show", "users" };
06002    int ret;
06003    const char *id = astman_get_header(m,"ActionID");
06004 
06005    if (!ast_strlen_zero(id))
06006       astman_append(s, "ActionID: %s\r\n",id);
06007    ret = __iax2_show_peers(1, -1, s, 3, a );
06008    astman_append(s, "\r\n\r\n" );
06009    return ret;
06010 } /* /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 1685 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().

01686 {
01687    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01688       (cur->addr.sin_port == sin->sin_port)) {
01689       /* This is the main host */
01690       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01691           (check_dcallno ? dcallno == cur->callno : 1) ) {
01692          /* That's us.  Be sure we keep track of the peer call number */
01693          return 1;
01694       }
01695    }
01696    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01697        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01698       /* We're transferring */
01699       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01700          return 1;
01701    }
01702    return 0;
01703 }

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

Definition at line 5359 of file chan_iax2.c.

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

Referenced by decode_frame().

05360 {
05361 #if 0
05362    /* Debug with "fake encryption" */
05363    int x;
05364    if (len % 16)
05365       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05366    for (x=0;x<len;x++)
05367       dst[x] = src[x] ^ 0xff;
05368 #else 
05369    unsigned char lastblock[16] = { 0 };
05370    int x;
05371    while(len > 0) {
05372       aes_decrypt(src, dst, dcx);
05373       for (x=0;x<16;x++)
05374          dst[x] ^= lastblock[x];
05375       memcpy(lastblock, src, sizeof(lastblock));
05376       dst += 16;
05377       src += 16;
05378       len -= 16;
05379    }
05380 #endif
05381 }

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

Definition at line 5383 of file chan_iax2.c.

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

Referenced by encrypt_frame().

05384 {
05385 #if 0
05386    /* Debug with "fake encryption" */
05387    int x;
05388    if (len % 16)
05389       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
05390    for (x=0;x<len;x++)
05391       dst[x] = src[x] ^ 0xff;
05392 #else
05393    unsigned char curblock[16] = { 0 };
05394    int x;
05395    while(len > 0) {
05396       for (x=0;x<16;x++)
05397          curblock[x] ^= src[x];
05398       aes_encrypt(curblock, dst, ecx);
05399       memcpy(curblock, dst, sizeof(curblock)); 
05400       dst += 16;
05401       src += 16;
05402       len -= 16;
05403    }
05404 #endif
05405 }

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

Definition at line 6616 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.

Referenced by authenticate_reply(), and socket_process().

06617 {
06618    /* Select exactly one common encryption if there are any */
06619    p->encmethods &= enc;
06620    if (p->encmethods) {
06621       if (p->encmethods & IAX_ENCRYPT_AES128)
06622          p->encmethods = IAX_ENCRYPT_AES128;
06623       else
06624          p->encmethods = 0;
06625    }
06626 }

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

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

10505 {
10506    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
10507       from the network, and queue them for delivery to the channels */
10508    int res, count, wakeup;
10509    struct iax_frame *f;
10510 
10511    if (timingfd > -1)
10512       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10513    
10514    for(;;) {
10515       pthread_testcancel();
10516 
10517       /* Go through the queue, sending messages which have not yet been
10518          sent, and scheduling retransmissions if appropriate */
10519       AST_LIST_LOCK(&iaxq.queue);
10520       count = 0;
10521       wakeup = -1;
10522       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
10523          if (f->sentyet)
10524             continue;
10525          
10526          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
10527          if (ast_mutex_trylock(&iaxsl[f->callno])) {
10528             wakeup = 1;
10529             continue;
10530          }
10531 
10532          f->sentyet++;
10533 
10534          if (iaxs[f->callno]) {
10535             send_packet(f);
10536             count++;
10537          } 
10538 
10539          ast_mutex_unlock(&iaxsl[f->callno]);
10540 
10541          if (f->retries < 0) {
10542             /* This is not supposed to be retransmitted */
10543             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
10544             iaxq.count--;
10545             /* Free the iax frame */
10546             iax_frame_free(f);
10547          } else {
10548             /* We need reliable delivery.  Schedule a retransmission */
10549             f->retries++;
10550             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10551          }
10552       }
10553       AST_LIST_TRAVERSE_SAFE_END
10554       AST_LIST_UNLOCK(&iaxq.queue);
10555 
10556       pthread_testcancel();
10557 
10558       if (option_debug && count >= 20)
10559          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10560 
10561       /* Now do the IO, and run scheduled tasks */
10562       res = ast_io_wait(io, wakeup);
10563       if (res >= 0) {
10564          if (option_debug && res >= 20)
10565             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10566       }
10567    }
10568    return NULL;
10569 }

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

Definition at line 1613 of file chan_iax2.c.

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

Referenced by __find_callno().

01614 {
01615    struct chan_iax2_pvt *tmp;
01616    jb_conf jbconf;
01617 
01618    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01619       return NULL;
01620    }
01621 
01622    if (ast_string_field_init(tmp, 32)) {
01623       ao2_ref(tmp, -1);
01624       tmp = NULL;
01625       return NULL;
01626    }
01627       
01628    tmp->prefs = prefs;
01629    tmp->callno = 0;
01630    tmp->peercallno = 0;
01631    tmp->transfercallno = 0;
01632    tmp->bridgecallno = 0;
01633    tmp->pingid = -1;
01634    tmp->lagid = -1;
01635    tmp->autoid = -1;
01636    tmp->authid = -1;
01637    tmp->initid = -1;
01638 
01639    ast_string_field_set(tmp,exten, "s");
01640    ast_string_field_set(tmp,host, host);
01641 
01642    tmp->jb = jb_new();
01643    tmp->jbid = -1;
01644    jbconf.max_jitterbuf = maxjitterbuffer;
01645    jbconf.resync_threshold = resyncthreshold;
01646    jbconf.max_contig_interp = maxjitterinterps;
01647    jb_setconf(tmp->jb,&jbconf);
01648 
01649    tmp->hold_signaling = 1;
01650    AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01651 
01652    return tmp;
01653 }

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

04358 {
04359    if (ast_strlen_zero(data))
04360       return;
04361 
04362    pds->peer = strsep(&data, "/");
04363    pds->exten = strsep(&data, "/");
04364    pds->options = data;
04365 
04366    if (pds->exten) {
04367       data = pds->exten;
04368       pds->exten = strsep(&data, "@");
04369       pds->context = data;
04370    }
04371 
04372    if (strchr(pds->peer, '@')) {
04373       data = pds->peer;
04374       pds->username = strsep(&data, "@");
04375       pds->peer = data;
04376    }
04377 
04378    if (pds->username) {
04379       data = pds->username;
04380       pds->username = strsep(&data, ":");
04381       pds->password = data;
04382    }
04383 
04384    data = pds->peer;
04385    pds->peer = strsep(&data, ":");
04386    pds->port = data;
04387 
04388    /* check for a key name wrapped in [] in the secret position, if found,
04389       move it to the key field instead
04390    */
04391    if (pds->password && (pds->password[0] == '[')) {
04392       pds->key = ast_strip_quoted(pds->password, "[", "]");
04393       pds->password = NULL;
04394    }
04395 }

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

References iax2_peer::name.

Referenced by load_objects().

01242 {
01243    struct iax2_peer *peer = obj, *peer2 = arg;
01244 
01245    return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01246 }

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

Definition at line 11231 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

11232 {
11233    struct iax2_peer *peer = obj;
11234 
11235    ast_set_flag(peer, IAX_DELME);
11236 
11237    return 0;
11238 }

static void peer_destructor ( void *  obj  )  [static]

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

10728 {
10729    struct iax2_peer *peer = obj;
10730    int callno = peer->callno;
10731 
10732    ast_free_ha(peer->ha);
10733 
10734    if (callno > 0) {
10735       ast_mutex_lock(&iaxsl[callno]);
10736       iax2_destroy(callno);
10737       ast_mutex_unlock(&iaxsl[callno]);
10738    }
10739 
10740    register_peer_exten(peer, 0);
10741 
10742    if (peer->dnsmgr)
10743       ast_dnsmgr_release(peer->dnsmgr);
10744 
10745    ast_string_field_free_memory(peer);
10746 }

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

References ast_str_hash(), and iax2_peer::name.

Referenced by load_objects().

01232 {
01233    const struct iax2_peer *peer = obj;
01234 
01235    return ast_str_hash(peer->name);
01236 }

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

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

01289 {
01290    ao2_ref(peer, +1);
01291    return peer;
01292 }

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

Definition at line 12590 of file chan_iax2.c.

References iax2_peer::sockfd.

Referenced by load_module().

12591 {
12592    struct iax2_peer *peer = obj;
12593 
12594    if (peer->sockfd < 0)
12595       peer->sockfd = defaultsockfd;
12596 
12597    return 0;
12598 }

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

10655 {
10656    struct sockaddr_in sin;
10657    int nonlocal = 1;
10658    int port = IAX_DEFAULT_PORTNO;
10659    int sockfd = defaultsockfd;
10660    char *tmp;
10661    char *addr;
10662    char *portstr;
10663 
10664    if (!(tmp = ast_strdupa(srcaddr)))
10665       return -1;
10666 
10667    addr = strsep(&tmp, ":");
10668    portstr = tmp;
10669 
10670    if (portstr) {
10671       port = atoi(portstr);
10672       if (port < 1)
10673          port = IAX_DEFAULT_PORTNO;
10674    }
10675    
10676    if (!ast_get_ip(&sin, addr)) {
10677       struct ast_netsock *sock;
10678       int res;
10679 
10680       sin.sin_port = 0;
10681       sin.sin_family = AF_INET;
10682       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10683       if (res == 0) {
10684          /* ip address valid. */
10685          sin.sin_port = htons(port);
10686          if (!(sock = ast_netsock_find(netsock, &sin)))
10687             sock = ast_netsock_find(outsock, &sin);
10688          if (sock) {
10689             sockfd = ast_netsock_sockfd(sock);
10690             nonlocal = 0;
10691          } else {
10692             unsigned int orig_saddr = sin.sin_addr.s_addr;
10693             /* INADDR_ANY matches anyway! */
10694             sin.sin_addr.s_addr = INADDR_ANY;
10695             if (ast_netsock_find(netsock, &sin)) {
10696                sin.sin_addr.s_addr = orig_saddr;
10697                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
10698                if (sock) {
10699                   sockfd = ast_netsock_sockfd(sock);
10700                   ast_netsock_unref(sock);
10701                   nonlocal = 0;
10702                } else {
10703                   nonlocal = 2;
10704                }
10705             }
10706          }
10707       }
10708    }
10709       
10710    peer->sockfd = sockfd;
10711 
10712    if (nonlocal == 1) {
10713       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10714          srcaddr, peer->name);
10715       return -1;
10716         } else if (nonlocal == 2) {
10717       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10718          srcaddr, peer->name);
10719          return -1;
10720    } else {
10721       if (option_debug)
10722          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10723       return 0;
10724    }
10725 }

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

peer_status: Report Peer status in character string

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

03237 {
03238    int res = 0;
03239    if (peer->maxms) {
03240       if (peer->lastms < 0) {
03241          ast_copy_string(status, "UNREACHABLE", statuslen);
03242       } else if (peer->lastms > peer->maxms) {
03243          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03244          res = 1;
03245       } else if (peer->lastms) {
03246          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03247          res = 1;
03248       } else {
03249          ast_copy_string(status, "UNKNOWN", statuslen);
03250       }
03251    } else { 
03252       ast_copy_string(status, "Unmonitored", statuslen);
03253       res = -1;
03254    }
03255    return res;
03256 }

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

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

01295 {
01296    ao2_ref(peer, -1);
01297    return NULL;
01298 }

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

Definition at line 1970 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

01971 {
01972    struct peercnt *peercnt;
01973    unsigned long addr = sin->sin_addr.s_addr;
01974    int res = 0;
01975    struct peercnt tmp = {
01976       .addr = addr,
01977    };
01978 
01979    /* Reasoning for peercnts container lock:  Two identical ip addresses
01980     * could be added by different threads at the "same time". Without the container
01981     * lock, both threads could alloc space for the same object and attempt
01982     * to link to table.  With the lock, one would create the object and link
01983     * to table while the other would find the already created peercnt object
01984     * rather than creating a new one. */
01985    ao2_lock(peercnts);
01986    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01987       ao2_lock(peercnt);
01988    } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
01989       ao2_lock(peercnt);
01990       /* create and set defaults */
01991       peercnt->addr = addr;
01992       set_peercnt_limit(peercnt);
01993       /* guarantees it does not go away after unlocking table
01994        * ao2_find automatically adds this */
01995       ao2_link(peercnts, peercnt);
01996    } else {
01997       ao2_unlock(peercnts);
01998       return -1;
01999    }
02000 
02001    /* check to see if the address has hit its callno limit.  If not increment cur. */
02002    if (peercnt->limit > peercnt->cur) {
02003       peercnt->cur++;
02004       if (option_debug) {
02005          ast_log(LOG_DEBUG, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02006       }
02007    } else { /* max num call numbers for this peer has been reached! */
02008       ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02009       res = -1;
02010    }
02011 
02012    /* clean up locks and ref count */
02013    ao2_unlock(peercnt);
02014    ao2_unlock(peercnts);
02015    ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */
02016 
02017    return res;
02018 }

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

Definition at line 1804 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

01805 {
01806    struct peercnt *peercnt1 = obj, *peercnt2 = arg;
01807    return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
01808 }

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

Definition at line 1798 of file chan_iax2.c.

References peercnt::addr.

Referenced by load_objects().

01799 {
01800    const struct peercnt *peercnt = obj;
01801    return abs((int) peercnt->addr);
01802 }

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

Definition at line 1940 of file chan_iax2.c.

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

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

01941 {
01942    /* this function turns off and on custom callno limits set by peer registration */
01943    struct peercnt *peercnt;
01944    struct peercnt tmp = {
01945       .addr = sin->sin_addr.s_addr,
01946    };
01947 
01948    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
01949       peercnt->reg = reg;
01950       if (limit) {
01951          peercnt->limit = limit;
01952       } else {
01953          set_peercnt_limit(peercnt);
01954       }
01955       if (option_debug) {
01956          ast_log(LOG_DEBUG, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg);
01957       }
01958       ao2_ref(peercnt, -1); /* decrement ref from find */
01959    }
01960 }

static void peercnt_remove ( struct peercnt peercnt  )  [static]

Definition at line 2024 of file chan_iax2.c.

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

Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().

02025 {
02026    struct sockaddr_in sin = {
02027       .sin_addr.s_addr = peercnt->addr,
02028    };
02029 
02030    if (peercnt) {
02031       /* Container locked here since peercnt may be unlinked from list.  If left unlocked,
02032        * peercnt_add could try and grab this entry from the table and modify it at the
02033        * "same time" this thread attemps to unlink it.*/
02034       ao2_lock(peercnts);
02035       peercnt->cur--;
02036       if (option_debug) {
02037          ast_log(LOG_DEBUG, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02038       }
02039       /* if this was the last connection from the peer remove it from table */
02040       if (peercnt->cur == 0) {
02041          ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */
02042       }
02043       ao2_unlock(peercnts);
02044    }
02045 }

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

Definition at line 2065 of file chan_iax2.c.

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

Referenced by __find_callno(), and complete_transfer().

02066 {
02067    struct peercnt *peercnt;
02068    struct peercnt tmp = {
02069       .addr = sin->sin_addr.s_addr,
02070    };
02071 
02072    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02073       peercnt_remove(peercnt);
02074       ao2_ref(peercnt, -1); /* decrement ref from find */
02075    }
02076    return 0;
02077 }

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

Definition at line 2051 of file chan_iax2.c.

References ao2_ref(), and peercnt_remove().

Referenced by sched_delay_remove().

02052 {
02053    struct peercnt *peercnt = (struct peercnt *) obj;
02054 
02055    peercnt_remove(peercnt);
02056    ao2_ref(peercnt, -1); /* decrement ref from scheduler */
02057 
02058    return 0;
02059 }

static void poke_all_peers ( void   )  [static]

Definition at line 11724 of file chan_iax2.c.

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

Referenced by reload_config().

11725 {
11726    struct ao2_iterator i;
11727    struct iax2_peer *peer;
11728 
11729    i = ao2_iterator_init(peers, 0);
11730    while ((peer = ao2_iterator_next(&i))) {
11731       iax2_poke_peer(peer, 0);
11732       peer_unref(peer);
11733    }
11734    ao2_iterator_destroy(&i);
11735 }

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

Definition at line 1929 of file chan_iax2.c.

References addr_range::delme.

Referenced by reload_config().

01930 {
01931    struct addr_range *addr_range = obj;
01932 
01933    return addr_range->delme ? CMP_MATCH : 0;
01934 }

static void prune_peers ( void   )  [static]

Definition at line 11292 of file chan_iax2.c.

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

11293 {
11294    struct iax2_peer *peer;
11295    struct ao2_iterator i;
11296 
11297    i = ao2_iterator_init(peers, 0);
11298    while ((peer = ao2_iterator_next(&i))) {
11299       if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11300          unlink_peer(peer);
11301       }
11302       peer_unref(peer);
11303    }
11304    ao2_iterator_destroy(&i);
11305 }

static void prune_users ( void   )  [static]

Definition at line 11276 of file chan_iax2.c.

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

Referenced by iax2_prune_realtime(), and reload_config().

11277 {
11278    struct iax2_user *user;
11279    struct ao2_iterator i;
11280 
11281    i = ao2_iterator_init(users, 0);
11282    while ((user = ao2_iterator_next(&i))) {
11283       if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11284          ao2_unlink(users, user);
11285       }
11286       user_unref(user);
11287    }
11288    ao2_iterator_destroy(&i);
11289 }

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

Definition at line 12607 of file chan_iax2.c.

References chan_iax2_pvt::frames_received, and match().

Referenced by load_objects().

12608 {
12609    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12610 
12611    /* The frames_received field is used to hold whether we're matching
12612     * against a full frame or not ... */
12613 
12614    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
12615       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12616 }

static void pvt_destructor ( void *  obj  )  [static]

Definition at line 1567 of file chan_iax2.c.

References chan_iax2_pvt::addr, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, 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, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax2_registry::next, chan_iax2_pvt::owner, ast_iax2_queue::queue, chan_iax2_pvt::reg, iax_frame::retries, s, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.

Referenced by new_iax().

01568 {
01569    struct chan_iax2_pvt *pvt = obj;
01570    struct iax_frame *cur = NULL;
01571    struct signaling_queue_entry *s = NULL;
01572 
01573    iax2_destroy_helper(pvt);
01574    sched_delay_remove(&pvt->addr, pvt->callno_entry);
01575    pvt->callno_entry = NULL;
01576 
01577    /* Already gone */
01578    ast_set_flag(pvt, IAX_ALREADYGONE); 
01579 
01580    AST_LIST_LOCK(&iaxq.queue);
01581    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01582       /* Cancel any pending transmissions */
01583       if (cur->callno == pvt->callno) { 
01584          cur->retries = -1;
01585       }
01586    }
01587    AST_LIST_UNLOCK(&iaxq.queue);
01588 
01589    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01590       free_signaling_queue_entry(s);
01591    }
01592 
01593    if (pvt->reg) {
01594       pvt->reg->callno = 0;
01595    }
01596 
01597    if (!pvt->owner) {
01598       jb_frame frame;
01599       if (pvt->vars) {
01600           ast_variables_destroy(pvt->vars);
01601           pvt->vars = NULL;
01602       }
01603 
01604       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01605          iax2_frame_free(frame.data);
01606       }
01607 
01608       jb_destroy(pvt->jb);
01609       ast_string_field_free_memory(pvt);
01610    }
01611 }

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

Definition at line 12600 of file chan_iax2.c.

References chan_iax2_pvt::peercallno.

Referenced by load_objects().

12601 {
12602    const struct chan_iax2_pvt *pvt = obj;
12603 
12604    return pvt->peercallno;
12605 }

static int queue_signalling ( struct chan_iax2_pvt pvt,
struct ast_frame f 
) [static]

All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.

Definition at line 1543 of file chan_iax2.c.

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

Referenced by __send_command().

01544 {
01545    struct signaling_queue_entry *new;
01546 
01547    if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01548       return 1; /* do not queue this frame */
01549    } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01550       return -1;  /* out of memory */
01551    }
01552 
01553    memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
01554 
01555    if (new->f.datalen) { /* if there is data in this frame copy it over as well */
01556       if (!(new->f.data = ast_calloc(1, new->f.datalen))) {
01557          free_signaling_queue_entry(new);
01558          return -1;
01559       }
01560       memcpy(new->f.data, f->data, sizeof(*new->f.data));
01561    }
01562    AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01563 
01564    return 0;
01565 }

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

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

06599 {
06600    struct ast_iax2_full_hdr fh;
06601    fh.scallno = htons(src | IAX_FLAG_FULL);
06602    fh.dcallno = htons(dst);
06603    fh.ts = 0;
06604    fh.oseqno = 0;
06605    fh.iseqno = 0;
06606    fh.type = AST_FRAME_IAX;
06607    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06608    if (iaxdebug)
06609        iax_showframe(NULL, &fh, 0, sin, 0);
06610    if (option_debug)
06611       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06612          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06613    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06614 }

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

03724 {
03725    struct ast_variable *var = NULL;
03726    struct ast_variable *tmp;
03727    struct iax2_peer *peer=NULL;
03728    time_t regseconds = 0, nowtime;
03729    int dynamic=0;
03730 
03731    if (peername) {
03732       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
03733       if (!var && sin)
03734          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03735    } else if (sin) {
03736       char porta[25];
03737       sprintf(porta, "%d", ntohs(sin->sin_port));
03738       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03739       if (var) {
03740          /* We'll need the peer name in order to build the structure! */
03741          for (tmp = var; tmp; tmp = tmp->next) {
03742             if (!strcasecmp(tmp->name, "name"))
03743                peername = tmp->value;
03744          }
03745       }
03746    }
03747    if (!var && peername) { /* Last ditch effort */
03748       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
03749       /*!\note
03750        * If this one loaded something, then we need to ensure that the host
03751        * field matched.  The only reason why we can't have this as a criteria
03752        * is because we only have the IP address and the host field might be
03753        * set as a name (and the reverse PTR might not match).
03754        */
03755       if (var && sin) {
03756          for (tmp = var; tmp; tmp = tmp->next) {
03757             if (!strcasecmp(tmp->name, "host")) {
03758                struct ast_hostent ahp;
03759                struct hostent *hp;
03760                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03761                   /* No match */
03762                   ast_variables_destroy(var);
03763                   var = NULL;
03764                }
03765                break;
03766             }
03767          }
03768       }
03769    }
03770    if (!var)
03771       return NULL;
03772 
03773    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03774    
03775    if (!peer) {
03776       ast_variables_destroy(var);
03777       return NULL;
03778    }
03779 
03780    for (tmp = var; tmp; tmp = tmp->next) {
03781       /* Make sure it's not a user only... */
03782       if (!strcasecmp(tmp->name, "type")) {
03783          if (strcasecmp(tmp->value, "friend") &&
03784              strcasecmp(tmp->value, "peer")) {
03785             /* Whoops, we weren't supposed to exist! */
03786             peer = peer_unref(peer);
03787             break;
03788          } 
03789       } else if (!strcasecmp(tmp->name, "regseconds")) {
03790          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
03791       } else if (!strcasecmp(tmp->name, "ipaddr")) {
03792          inet_aton(tmp->value, &(peer->addr.sin_addr));
03793       } else if (!strcasecmp(tmp->name, "port")) {
03794          peer->addr.sin_port = htons(atoi(tmp->value));
03795       } else if (!strcasecmp(tmp->name, "host")) {
03796          if (!strcasecmp(tmp->value, "dynamic"))
03797             dynamic = 1;
03798       }
03799    }
03800 
03801    ast_variables_destroy(var);
03802 
03803    if (!peer)
03804       return NULL;
03805 
03806    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03807       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03808       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03809          if (peer->expire > -1) {
03810             if (!ast_sched_del(sched, peer->expire)) {
03811                peer->expire = -1;
03812                peer_unref(peer);
03813             }
03814          }
03815          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03816          if (peer->expire == -1)
03817             peer_unref(peer);
03818       }
03819       ao2_link(peers, peer);
03820       if (ast_test_flag(peer, IAX_DYNAMIC))
03821          reg_source_db(peer);
03822    } else {
03823       ast_set_flag(peer, IAX_TEMPONLY);   
03824    }
03825 
03826    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03827       time(&nowtime);
03828       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03829          memset(&peer->addr, 0, sizeof(peer->addr));
03830          realtime_update_peer(peer->name, &peer->addr, 0);
03831          if (option_debug)
03832             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03833                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03834       }
03835       else {
03836          if (option_debug)
03837             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03838                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03839       }
03840    }
03841 
03842    return peer;
03843 }

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

Definition at line 3916 of file chan_iax2.c.

References ast_inet_ntoa(), and ast_update_realtime().

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

03917 {
03918    char port[10];
03919    char regseconds[20];
03920    
03921    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03922    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03923    ast_update_realtime("iaxpeers", "name", peername, 
03924       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03925       "regseconds", regseconds, NULL);
03926 }

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

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

03846 {
03847    struct ast_variable *var;
03848    struct ast_variable *tmp;
03849    struct iax2_user *user=NULL;
03850 
03851    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03852    if (!var)
03853       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03854    if (!var && sin) {
03855       char porta[6];
03856       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03857       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03858       if (!var)
03859          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03860    }
03861    if (!var) { /* Last ditch effort */
03862       var = ast_load_realtime("iaxusers", "name", username, NULL);
03863       /*!\note
03864        * If this one loaded something, then we need to ensure that the host
03865        * field matched.  The only reason why we can't have this as a criteria
03866        * is because we only have the IP address and the host field might be
03867        * set as a name (and the reverse PTR might not match).
03868        */
03869       if (var) {
03870          for (tmp = var; tmp; tmp = tmp->next) {
03871             if (!strcasecmp(tmp->name, "host")) {
03872                struct ast_hostent ahp;
03873                struct hostent *hp;
03874                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03875                   /* No match */
03876                   ast_variables_destroy(var);
03877                   var = NULL;
03878                }
03879                break;
03880             }
03881          }
03882       }
03883    }
03884    if (!var)
03885       return NULL;
03886 
03887    tmp = var;
03888    while(tmp) {
03889       /* Make sure it's not a peer only... */
03890       if (!strcasecmp(tmp->name, "type")) {
03891          if (strcasecmp(tmp->value, "friend") &&
03892              strcasecmp(tmp->value, "user")) {
03893             return NULL;
03894          } 
03895       }
03896       tmp = tmp->next;
03897    }
03898 
03899    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03900 
03901    ast_variables_destroy(var);
03902 
03903    if (!user)
03904       return NULL;
03905 
03906    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03907       ast_set_flag(user, IAX_RTCACHEFRIENDS);
03908       ao2_link(users, user);
03909    } else {
03910       ast_set_flag(user, IAX_TEMPONLY);   
03911    }
03912 
03913    return user;
03914 }

static void reg_source_db ( struct iax2_peer p  )  [static]

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

07422 {
07423    char data[80];
07424    struct in_addr in;
07425    char *c, *d;
07426    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07427       c = strchr(data, ':');
07428       if (c) {
07429          *c = '\0';
07430          c++;
07431          if (inet_aton(data, &in)) {
07432             d = strchr(c, ':');
07433             if (d) {
07434                *d = '\0';
07435                d++;
07436                if (option_verbose > 2)
07437                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
07438                   ast_inet_ntoa(in), atoi(c), atoi(d));
07439                iax2_poke_peer(p, 0);
07440                p->expiry = atoi(d);
07441                memset(&p->addr, 0, sizeof(p->addr));
07442                p->addr.sin_family = AF_INET;
07443                p->addr.sin_addr = in;
07444                p->addr.sin_port = htons(atoi(c));
07445                if (p->expire > -1) {
07446                   if (!ast_sched_del(sched, p->expire)) {
07447                      p->expire = -1;
07448                      peer_unref(p);
07449                   }
07450                }
07451                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07452                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07453                if (p->expire == -1)
07454                   peer_unref(p);
07455                if (iax2_regfunk)
07456                   iax2_regfunk(p->name, 1);
07457                register_peer_exten(p, 1);
07458             }              
07459                
07460          }
07461       }
07462    }
07463 }

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

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

07340 {
07341    char multi[256];
07342    char *stringp, *ext;
07343    if (!ast_strlen_zero(regcontext)) {
07344       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07345       stringp = multi;
07346       while((ext = strsep(&stringp, "&"))) {
07347          if (onoff) {
07348             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07349                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07350                        "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07351          } else
07352             ast_context_remove_extension(regcontext, ext, 1, NULL);
07353       }
07354    }
07355 }

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

Verify inbound registration.

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

06766 {
06767    char requeststr[256] = "";
06768    char peer[256] = "";
06769    char md5secret[256] = "";
06770    char rsasecret[256] = "";
06771    char secret[256] = "";
06772    struct iax2_peer *p = NULL;
06773    struct ast_key *key;
06774    char *keyn;
06775    int x;
06776    int expire = 0;
06777    int res = -1;
06778 
06779    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06780    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
06781    if (ies->username)
06782       ast_copy_string(peer, ies->username, sizeof(peer));
06783    if (ies->password)
06784       ast_copy_string(secret, ies->password, sizeof(secret));
06785    if (ies->md5_result)
06786       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06787    if (ies->rsa_result)
06788       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06789    if (ies->refresh)
06790       expire = ies->refresh;
06791 
06792    if (ast_strlen_zero(peer)) {
06793       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06794       return -1;
06795    }
06796 
06797    /* SLD: first call to lookup peer during registration */
06798    ast_mutex_unlock(&iaxsl[callno]);
06799    p = find_peer(peer, 1);
06800    ast_mutex_lock(&iaxsl[callno]);
06801    if (!p || !iaxs[callno]) {
06802       if (iaxs[callno]) {
06803          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06804 
06805          ast_string_field_set(iaxs[callno], secret, "badsecret");
06806 
06807          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
06808           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
06809           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
06810           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
06811           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
06812           *
06813           * If none of these cases exist, res will be returned as 0 without authentication indicating
06814           * an AUTHREQ needs to be sent out. */
06815 
06816          if (ast_strlen_zero(iaxs[callno]->challenge) &&
06817             !(!ast_strlen_zero(secret) && plaintext)) {
06818             /* by setting res to 0, an REGAUTH will be sent */
06819             res = 0;
06820          }
06821       }
06822       if (authdebug && !p)
06823          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06824 
06825       goto return_unref;
06826    }
06827 
06828    if (!ast_test_flag(p, IAX_DYNAMIC)) {
06829       if (authdebug)
06830          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06831       goto return_unref;
06832    }
06833 
06834    if (!ast_apply_ha(p->ha, sin)) {
06835       if (authdebug)
06836          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06837       goto return_unref;
06838    }
06839    ast_string_field_set(iaxs[callno], secret, p->secret);
06840    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06841    /* Check secret against what we have on file */
06842    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06843       if (!ast_strlen_zero(p->inkeys)) {
06844          char tmpkeys[256];
06845          char *stringp=NULL;
06846          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06847          stringp=tmpkeys;
06848          keyn = strsep(&stringp, ":");
06849          while(keyn) {
06850             key = ast_key_get(keyn, AST_KEY_PUBLIC);
06851             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06852                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06853                break;
06854             } else if (!key)
06855                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06856             keyn = strsep(&stringp, ":");
06857          }
06858          if (!keyn) {
06859             if (authdebug)
06860                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06861             goto return_unref;
06862          }
06863       } else {
06864          if (authdebug)
06865             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06866          goto return_unref;
06867       }
06868    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06869       struct MD5Context md5;
06870       unsigned char digest[16];
06871       char *tmppw, *stringp;
06872 
06873       tmppw = ast_strdupa(p->secret);
06874       stringp = tmppw;
06875       while((tmppw = strsep(&stringp, ";"))) {
06876          MD5Init(&md5);
06877          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06878          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06879          MD5Final(digest, &md5);
06880          for (x=0;x<16;x++)
06881             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
06882          if (!strcasecmp(requeststr, md5secret))
06883             break;
06884       }
06885       if (tmppw) {
06886          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06887       } else {
06888          if (authdebug)
06889             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06890          goto return_unref;
06891       }
06892    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06893       /* They've provided a plain text password and we support that */
06894       if (strcmp(secret, p->secret)) {
06895          if (authdebug)
06896             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06897          goto return_unref;
06898       } else
06899          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06900    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06901       /* if challenge has been sent, but no challenge response if given, reject. */
06902       goto return_unref;
06903    }
06904    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06905 
06906    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
06907    res = 0;
06908 return_unref:
06909 
06910    if (iaxs[callno]) {
06911       ast_string_field_set(iaxs[callno], peer, peer);
06912 
06913       /* Choose lowest expiry number */
06914       if (expire && (expire < iaxs[callno]->expiry)) {
06915          iaxs[callno]->expiry = expire;
06916       }
06917    }
06918 
06919    if (p) {
06920       peer_unref(p);
06921    }
06922    return res;
06923 }

static int registry_authrequest ( int  callno  )  [static]

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

07611 {
07612    struct iax_ie_data ied;
07613    struct iax2_peer *p;
07614    char challenge[10];
07615    const char *peer_name;
07616    int sentauthmethod;
07617 
07618    peer_name = ast_strdupa(iaxs[callno]->peer);
07619 
07620    /* SLD: third call to find_peer in registration */
07621    ast_mutex_unlock(&iaxsl[callno]);
07622    if ((p = find_peer(peer_name, 1))) {
07623       last_authmethod = p->authmethods;
07624    }
07625 
07626    ast_mutex_lock(&iaxsl[callno]);
07627    if (!iaxs[callno])
07628       goto return_unref;
07629 
07630    memset(&ied, 0, sizeof(ied));
07631    /* The selection of which delayed reject is sent may leak information,
07632     * if it sets a static response.  For example, if a host is known to only
07633     * use MD5 authentication, then an RSA response would indicate that the
07634     * peer does not exist, and vice-versa.
07635     * Therefore, we use whatever the last peer used (which may vary over the
07636     * course of a server, which should leak minimal information). */
07637    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07638    if (!p) {
07639       iaxs[callno]->authmethods = sentauthmethod;
07640    }
07641    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07642    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07643       /* Build the challenge */
07644       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07645       ast_string_field_set(iaxs[callno], challenge, challenge);
07646       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07647    }
07648    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07649 
07650 return_unref:
07651    if (p) {
07652       peer_unref(p);
07653    }
07654 
07655    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07656 }

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

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

07659 {
07660    struct iax2_registry *reg;
07661    /* Start pessimistic */
07662    struct iax_ie_data ied;
07663    char peer[256] = "";
07664    char challenge[256] = "";
07665    int res;
07666    int authmethods = 0;
07667    if (ies->authmethods)
07668       authmethods = ies->authmethods;
07669    if (ies->username)
07670       ast_copy_string(peer, ies->username, sizeof(peer));
07671    if (ies->challenge)
07672       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07673    memset(&ied, 0, sizeof(ied));
07674    reg = iaxs[callno]->reg;
07675    if (reg) {
07676          if (inaddrcmp(&reg->addr, sin)) {
07677             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07678             return -1;
07679          }
07680          if (ast_strlen_zero(reg->secret)) {
07681             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07682             reg->regstate = REG_STATE_NOAUTH;
07683             return -1;
07684          }
07685          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07686          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07687          if (reg->secret[0] == '[') {
07688             char tmpkey[256];
07689             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07690             tmpkey[strlen(tmpkey) - 1] = '\0';
07691             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07692          } else
07693             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07694          if (!res) {
07695             reg->regstate = REG_STATE_AUTHSENT;
07696             add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */
07697             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07698          } else
07699             return -1;
07700          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07701    } else   
07702       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07703    return -1;
07704 }

static char* regstate2str ( int  regstate  )  [static]

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

06013 {
06014    switch(regstate) {
06015    case REG_STATE_UNREGISTERED:
06016       return "Unregistered";
06017    case REG_STATE_REGSENT:
06018       return "Request Sent";
06019    case REG_STATE_AUTHSENT:
06020       return "Auth. Sent";
06021    case REG_STATE_REGISTERED:
06022       return "Registered";
06023    case REG_STATE_REJECTED:
06024       return "Rejected";
06025    case REG_STATE_TIMEOUT:
06026       return "Timeout";
06027    case REG_STATE_NOAUTH:
06028       return "No Authentication";
06029    default:
06030       return "Unknown";
06031    }
06032 }

static int reload ( void   )  [static]

Definition at line 11765 of file chan_iax2.c.

References reload_config().

11766 {
11767    return reload_config();
11768 }

static int reload_config ( void   )  [static]

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

11737 {
11738    static const char config[] = "iax.conf";
11739    struct iax2_registry *reg;
11740 
11741    if (set_config(config, 1) > 0) {
11742       prune_peers();
11743       prune_users();
11744       ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
11745       ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
11746       ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
11747       AST_LIST_LOCK(&registrations);
11748       AST_LIST_TRAVERSE(&registrations, reg, entry)
11749          iax2_do_register(reg);
11750       AST_LIST_UNLOCK(&registrations);
11751       /* Qualify hosts, too */
11752       poke_all_peers();
11753    }
11754    reload_firmware(0);
11755    iax_provision_reload();
11756 
11757    return 0;
11758 }

static void reload_firmware ( int  unload  )  [static]

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

02849 {
02850    struct iax_firmware *cur, *curl, *curp;
02851    DIR *fwd;
02852    struct dirent *de;
02853    char dir[256];
02854    char fn[256];
02855    /* Mark all as dead */
02856    ast_mutex_lock(&waresl.lock);
02857    cur = waresl.wares;
02858    while(cur) {
02859       cur->dead = 1;
02860       cur = cur->next;
02861    }
02862 
02863    /* Now that we've freed them, load the new ones */
02864    if (!unload) {
02865       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02866       fwd = opendir(dir);
02867       if (fwd) {
02868          while((de = readdir(fwd))) {
02869             if (de->d_name[0] != '.') {
02870                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02871                if (!try_firmware(fn)) {
02872                   if (option_verbose > 1)
02873                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02874                }
02875             }
02876          }
02877          closedir(fwd);
02878       } else 
02879          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02880    }
02881 
02882    /* Clean up leftovers */
02883    cur = waresl.wares;
02884    curp = NULL;
02885    while(cur) {
02886       curl = cur;
02887       cur = cur->next;
02888       if (curl->dead) {
02889          if (curp) {
02890             curp->next = cur;
02891          } else {
02892             waresl.wares = cur;
02893          }
02894          destroy_firmware(curl);
02895       } else {
02896          curp = cur;
02897       }
02898    }
02899    ast_mutex_unlock(&waresl.lock);
02900 }

static void remove_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

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

01409 {
01410    if (!pvt->peercallno) {
01411       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01412       return;
01413    }
01414 
01415    ao2_unlink(iax_peercallno_pvts, pvt);
01416 }

static void remove_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

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

01390 {
01391    if (!pvt->transfercallno) {
01392       ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01393       return;
01394    }
01395 
01396    ao2_unlink(iax_transfercallno_pvts, pvt);
01397 }

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

Definition at line 2245 of file chan_iax2.c.

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

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

02246 {
02247    struct callno_entry *callno_entry = (struct callno_entry *) obj;
02248 
02249    /* the callno_pool container is locked here primarily to ensure thread
02250     * safety of the total_nonval_callno_used check and decrement */
02251    ao2_lock(callno_pool);
02252 
02253    if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02254       total_nonval_callno_used--;
02255    } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02256       ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02257    }
02258 
02259    if (callno_entry->callno < TRUNK_CALL_START) {
02260       ao2_link(callno_pool, callno_entry);
02261    } else {
02262       ao2_link(callno_pool_trunk, callno_entry);
02263    }
02264    ao2_ref(callno_entry, -1); /* only container ref remains */
02265 
02266    ao2_unlock(callno_pool);
02267    return 0;
02268 }

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

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

04215 {
04216    struct iax2_user *user = NULL;
04217    struct iax2_peer *peer = NULL;
04218 
04219    if (ast_strlen_zero(name)) {
04220       return; /* no username given */
04221    }
04222 
04223    if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04224       user->calltoken_required = CALLTOKEN_YES;
04225    } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04226       peer->calltoken_required = CALLTOKEN_YES;
04227    }
04228 
04229    if (peer) {
04230       peer_unref(peer);
04231    }
04232    if (user) {
04233       user_unref(user);
04234    }
04235 }

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

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

04131 {
04132    struct chan_iax2_pvt *pvt = iaxs[callno];
04133    int frametype = f->af.frametype;
04134    int subclass = f->af.subclass;
04135    struct {
04136       struct ast_iax2_full_hdr fh;
04137       struct iax_ie_data ied;
04138    } data = {
04139       .ied.buf = { 0 },
04140       .ied.pos = 0,
04141    };
04142    /* total len - header len gives us the frame's IE len */
04143    int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04144 
04145    if (!pvt) {
04146       return;  /* this should not be possible if called from socket_process() */
04147    }
04148 
04149    /* 
04150     * Check to make sure last frame sent is valid for call token resend
04151     * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 
04152     * 2. Frame should _NOT_ already have a destination callno
04153     * 3. Frame must be a valid iax_frame subclass capable of starting dialog
04154     * 4. Pvt must have a calltoken_ie_len which represents the number of
04155     *    bytes at the end of the frame used for the previous calltoken ie.
04156     * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length
04157     * 6. Total length of f->data must be _LESS_ than size of our data struct
04158     *    because f->data must be able to fit within data. 
04159     */
04160    if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04161       || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04162       (f->datalen > sizeof(data))) {
04163 
04164       return;  /* ignore resend, token was not valid for the dialog */
04165    }
04166 
04167    /* token is valid
04168     * 1. Copy frame data over
04169     * 2. Redo calltoken IE, it will always be the last ie in the frame.
04170     *    NOTE: Having the ie always be last is not protocol specified,
04171     *    it is only an implementation choice.  Since we only expect the ie to
04172     *    be last for frames we have sent, this can no way be affected by
04173     *    another end point.
04174     * 3. Remove frame from queue
04175     * 4. Free old frame
04176     * 5. Clear previous seqnos
04177     * 6. Resend with CALLTOKEN ie.
04178     */
04179 
04180    /* ---1.--- */
04181    memcpy(&data, f->data, f->datalen);
04182    data.ied.pos = ie_data_pos;
04183 
04184    /* ---2.--- */
04185    /* move to the beginning of the calltoken ie so we can write over it */
04186    data.ied.pos -= pvt->calltoken_ie_len;
04187    iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04188 
04189    /* make sure to update token length incase it ever has to be stripped off again */
04190    pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */
04191 
04192    /* ---3.--- */
04193    AST_LIST_LOCK(&iaxq.queue);
04194    AST_LIST_REMOVE(&iaxq.queue, f, list);
04195    AST_LIST_UNLOCK(&iaxq.queue);
04196 
04197    /* ---4.--- */
04198    iax2_frame_free(f);
04199 
04200    /* ---5.--- */
04201    pvt->oseqno = 0;
04202    pvt->rseqno = 0;
04203    pvt->iseqno = 0;
04204    pvt->aseqno = 0;
04205    if (pvt->peercallno) {
04206       remove_by_peercallno(pvt);
04207       pvt->peercallno = 0;
04208    }
04209 
04210    /* ---6.--- */
04211    send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04212 }

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

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

08164 {
08165    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
08166    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
08167    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
08168    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
08169    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
08170    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
08171    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
08172 }

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

Definition at line 2317 of file chan_iax2.c.

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

Referenced by pvt_destructor().

02318 {
02319    int i;
02320    struct peercnt *peercnt;
02321    struct peercnt tmp = {
02322       .addr = sin->sin_addr.s_addr,
02323    };
02324 
02325    if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02326       /* refcount is incremented with ao2_find.  keep that ref for the scheduler */
02327       if (option_debug) {
02328          ast_log(LOG_DEBUG, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02329       }
02330       i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02331       if (i == -1) {
02332          ao2_ref(peercnt, -1);
02333       }
02334    }
02335 
02336    iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02337 }

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

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

10470 {
10471    for (;;) {
10472       int ms, count;
10473       struct timespec ts;
10474 
10475       pthread_testcancel();
10476 
10477       ast_mutex_lock(&sched_lock);
10478 
10479       ms = ast_sched_wait(sched);
10480 
10481       if (ms == -1) {
10482          ast_cond_wait(&sched_cond, &sched_lock);
10483       } else {
10484          struct timeval tv;
10485          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000));
10486          ts.tv_sec = tv.tv_sec;
10487          ts.tv_nsec = tv.tv_usec * 1000;
10488          ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10489       }
10490 
10491       ast_mutex_unlock(&sched_lock);
10492 
10493       pthread_testcancel();
10494 
10495       count = ast_sched_runq(sched);
10496       if (option_debug && count >= 20) {
10497          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10498       }
10499    }
10500 
10501    return NULL;
10502 }

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

03577 {
03578    int type, len;
03579    int ret;
03580    int needfree = 0;
03581    struct ast_channel *owner = NULL;
03582    struct ast_channel *bridge = NULL;
03583    
03584    /* Attempt to recover wrapped timestamps */
03585    unwrap_timestamp(fr);
03586 
03587    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
03588    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03589       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03590    else {
03591 #if 0
03592       if (option_debug)
03593          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03594 #endif
03595       fr->af.delivery = ast_tv(0,0);
03596    }
03597 
03598    type = JB_TYPE_CONTROL;
03599    len = 0;
03600 
03601    if(fr->af.frametype == AST_FRAME_VOICE) {
03602       type = JB_TYPE_VOICE;
03603       len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000);
03604    } else if(fr->af.frametype == AST_FRAME_CNG) {
03605       type = JB_TYPE_SILENCE;
03606    }
03607 
03608    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03609       if (tsout)
03610          *tsout = fr->ts;
03611       __do_deliver(fr);
03612       return -1;
03613    }
03614 
03615    if ((owner = iaxs[fr->callno]->owner))
03616       bridge = ast_bridged_channel(owner);
03617 
03618    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
03619     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
03620    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03621       jb_frame frame;
03622 
03623       /* deliver any frames in the jb */
03624       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03625          __do_deliver(frame.data);
03626          /* __do_deliver() can make the call disappear */
03627          if (!iaxs[fr->callno])
03628             return -1;
03629       }
03630 
03631       jb_reset(iaxs[fr->callno]->jb);
03632 
03633       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03634 
03635       /* deliver this frame now */
03636       if (tsout)
03637          *tsout = fr->ts;
03638       __do_deliver(fr);
03639       return -1;
03640    }
03641 
03642    /* insert into jitterbuffer */
03643    /* TODO: Perhaps we could act immediately if it's not droppable and late */
03644    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03645          calc_rxstamp(iaxs[fr->callno],fr->ts));
03646    if (ret == JB_DROP) {
03647       needfree++;
03648    } else if (ret == JB_SCHED) {
03649       update_jbsched(iaxs[fr->callno]);
03650    }
03651    if (tsout)
03652       *tsout = fr->ts;
03653    if (needfree) {
03654       /* Free our iax frame */
03655       iax2_frame_free(fr);
03656       return -1;
03657    }
03658    return 0;
03659 }

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

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

01509 {
01510    unsigned short callno = PTR_TO_CALLNO(vid);
01511    ast_mutex_lock(&iaxsl[callno]);
01512    if (iaxs[callno]) {
01513       if (option_debug) {
01514          ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01515       }
01516       iax2_destroy(callno);
01517    }
01518    ast_mutex_unlock(&iaxsl[callno]);
01519    return 0;
01520 }

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

04097 {
04098    struct {
04099       struct ast_iax2_full_hdr f;
04100       struct iax_ie_data ied;
04101    } data;
04102    size_t size = sizeof(struct ast_iax2_full_hdr);
04103 
04104    if (ied) {
04105       size += ied->pos;
04106       memcpy(&data.ied, ied->buf, ied->pos);
04107    }
04108 
04109    data.f.scallno = htons(0x8000 | callno);
04110    data.f.dcallno = htons(dcallno);
04111    data.f.ts = htonl(ts);
04112    data.f.iseqno = seqno;
04113    data.f.oseqno = 0;
04114    data.f.type = AST_FRAME_IAX;
04115    data.f.csub = compress_subclass(command);
04116 
04117    return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04118 }

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

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

06324 {
06325    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
06326 }

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

06343 {
06344    int call_num = i->callno;
06345    /* It is assumed that the callno has already been locked */
06346    iax2_predestroy(i->callno);
06347    if (!iaxs[call_num])
06348       return -1;
06349    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
06350 }

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

Definition at line 6352 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_process().

06353 {
06354    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
06355 }

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

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

06329 {
06330    int res;
06331    ast_mutex_lock(&iaxsl[callno]);
06332    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
06333    ast_mutex_unlock(&iaxsl[callno]);
06334    return res;
06335 }

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

Definition at line 6357 of file chan_iax2.c.

References __send_command().

Referenced by socket_process(), and try_transfer().

06358 {
06359    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
06360 }

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

Definition at line 1184 of file chan_iax2.c.

References __send_lagrq(), and schedule_action.

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

01185 {
01186 #ifdef SCHED_MULTITHREADED
01187    if (schedule_action(__send_lagrq, data))
01188 #endif      
01189       __send_lagrq(data);
01190    
01191    return 0;
01192 }

static int send_packet ( struct iax_frame f  )  [static]

Definition at line 2973 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, and chan_iax2_pvt::transfer.

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

02974 {
02975    int res;
02976    int callno = f->callno;
02977 
02978    /* Don't send if there was an error, but return error instead */
02979    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02980        return -1;
02981    
02982    /* Called with iaxsl held */
02983    if (option_debug > 2 && iaxdebug)
02984       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));
02985    if (f->transfer) {
02986       if (iaxdebug)
02987          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02988       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02989                sizeof(iaxs[callno]->transfer));
02990    } else {
02991       if (iaxdebug)
02992          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02993       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02994                sizeof(iaxs[callno]->addr));
02995    }
02996    if (res < 0) {
02997       if (option_debug && iaxdebug)
02998          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02999       handle_error();
03000    } else
03001       res = 0;
03002    return res;
03003 }

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

Definition at line 1139 of file chan_iax2.c.

References __send_ping(), and schedule_action.

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

01140 {
01141 #ifdef SCHED_MULTITHREADED
01142    if (schedule_action(__send_ping, data))
01143 #endif      
01144       __send_ping(data);
01145 
01146    return 0;
01147 }

static void send_signaling ( struct chan_iax2_pvt pvt  )  [static]

This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.

Definition at line 1530 of file chan_iax2.c.

References AST_LIST_REMOVE_HEAD, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), iax2_registry::next, s, and chan_iax2_pvt::signaling_queue.

Referenced by socket_process().

01531 {
01532    struct signaling_queue_entry *s = NULL;
01533 
01534    while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01535       iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01536       free_signaling_queue_entry(s);
01537    }
01538    pvt->hold_signaling = 0;
01539 }

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

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

07842 {
07843    int res = 0;
07844    struct iax_frame *fr;
07845    struct ast_iax2_meta_hdr *meta;
07846    struct ast_iax2_meta_trunk_hdr *mth;
07847    int calls = 0;
07848    
07849    /* Point to frame */
07850    fr = (struct iax_frame *)tpeer->trunkdata;
07851    /* Point to meta data */
07852    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07853    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07854    if (tpeer->trunkdatalen) {
07855       /* We're actually sending a frame, so fill the meta trunk header and meta header */
07856       meta->zeros = 0;
07857       meta->metacmd = IAX_META_TRUNK;
07858       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07859          meta->cmddata = IAX_META_TRUNK_MINI;
07860       else
07861          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07862       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07863       /* And the rest of the ast_iax2 header */
07864       fr->direction = DIRECTION_OUTGRESS;
07865       fr->retrans = -1;
07866       fr->transfer = 0;
07867       /* Any appropriate call will do */
07868       fr->data = fr->afdata;
07869       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07870       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07871       calls = tpeer->calls;
07872 #if 0
07873       if (option_debug)
07874          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));
07875 #endif      
07876       /* Reset transmit trunk side data */
07877       tpeer->trunkdatalen = 0;
07878       tpeer->calls = 0;
07879    }
07880    if (res < 0)
07881       return res;
07882    return calls;
07883 }

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

Load configuration.

Definition at line 11340 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_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_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_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_SHRINKCALLERID, 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(), peers, portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), users, ast_variable::value, and VERBOSE_PREFIX_2.

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

11341 {
11342    struct ast_config *cfg, *ucfg;
11343    int capability=iax2_capability;
11344    struct ast_variable *v;
11345    char *cat;
11346    const char *utype;
11347    const char *tosval;
11348    int format;
11349    int portno = IAX_DEFAULT_PORTNO;
11350    int  x;
11351    struct iax2_user *user;
11352    struct iax2_peer *peer;
11353    struct ast_netsock *ns;
11354 #if 0
11355    static unsigned short int last_port=0;
11356 #endif
11357 
11358    cfg = ast_config_load(config_file);
11359    
11360    if (!cfg) {
11361       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11362       return -1;
11363    }
11364 
11365    if (reload) {
11366       set_config_destroy();
11367    }
11368 
11369    /* Reset global codec prefs */   
11370    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11371    
11372    /* Reset Global Flags */
11373    memset(&globalflags, 0, sizeof(globalflags));
11374    ast_set_flag(&globalflags, IAX_RTUPDATE);
11375    ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
11376 
11377 #ifdef SO_NO_CHECK
11378    nochecksums = 0;
11379 #endif
11380 
11381    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11382    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11383    global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
11384    global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
11385 
11386    maxauthreq = 3;
11387 
11388    v = ast_variable_browse(cfg, "general");
11389 
11390    /* Seed initial tos value */
11391    tosval = ast_variable_retrieve(cfg, "general", "tos");
11392    if (tosval) {
11393       if (ast_str2tos(tosval, &tos))
11394          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
11395    }
11396    while(v) {
11397       if (!strcasecmp(v->name, "bindport")){ 
11398          if (reload)
11399             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11400          else
11401             portno = atoi(v->value);
11402       } else if (!strcasecmp(v->name, "pingtime")) 
11403          ping_time = atoi(v->value);
11404       else if (!strcasecmp(v->name, "iaxthreadcount")) {
11405          if (reload) {
11406             if (atoi(v->value) != iaxthreadcount)
11407                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11408          } else {
11409             iaxthreadcount = atoi(v->value);
11410             if (iaxthreadcount < 1) {
11411                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11412                iaxthreadcount = 1;
11413             } else if (iaxthreadcount > 256) {
11414                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11415                iaxthreadcount = 256;
11416             }
11417          }
11418       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11419          if (reload) {
11420             AST_LIST_LOCK(&dynamic_list);
11421             iaxmaxthreadcount = atoi(v->value);
11422             AST_LIST_UNLOCK(&dynamic_list);
11423          } else {
11424             iaxmaxthreadcount = atoi(v->value);
11425             if (iaxmaxthreadcount < 0) {
11426                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11427                iaxmaxthreadcount = 0;
11428             } else if (iaxmaxthreadcount > 256) {
11429                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11430                iaxmaxthreadcount = 256;
11431             }
11432          }
11433       } else if (!strcasecmp(v->name, "nochecksums")) {
11434 #ifdef SO_NO_CHECK
11435          if (ast_true(v->value))
11436             nochecksums = 1;
11437          else
11438             nochecksums = 0;
11439 #else
11440          if (ast_true(v->value))
11441             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11442 #endif
11443       }
11444       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
11445          maxjitterbuffer = atoi(v->value);
11446       else if (!strcasecmp(v->name, "resyncthreshold")) 
11447          resyncthreshold = atoi(v->value);
11448       else if (!strcasecmp(v->name, "maxjitterinterps")) 
11449          maxjitterinterps = atoi(v->value);
11450       else if (!strcasecmp(v->name, "lagrqtime")) 
11451          lagrq_time = atoi(v->value);
11452       else if (!strcasecmp(v->name, "maxregexpire")) 
11453          max_reg_expire = atoi(v->value);
11454       else if (!strcasecmp(v->name, "minregexpire")) 
11455          min_reg_expire = atoi(v->value);
11456       else if (!strcasecmp(v->name, "bindaddr")) {
11457          if (reload) {
11458             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11459          } else {
11460             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
11461                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11462             } else {
11463                if (option_verbose > 1) {
11464                   if (strchr(v->value, ':'))
11465                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
11466                   else
11467                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
11468                }
11469                if (defaultsockfd < 0) 
11470                   defaultsockfd = ast_netsock_sockfd(ns);
11471                ast_netsock_unref(ns);
11472             }
11473          }
11474       } else if (!strcasecmp(v->name, "authdebug"))
11475          authdebug = ast_true(v->value);
11476       else if (!strcasecmp(v->name, "encryption"))
11477          iax2_encryption = get_encrypt_methods(v->value);
11478       else if (!strcasecmp(v->name, "notransfer")) {
11479          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
11480          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
11481          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
11482       } else if (!strcasecmp(v->name, "transfer")) {
11483          if (!strcasecmp(v->value, "mediaonly")) {
11484             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
11485          } else if (ast_true(v->value)) {
11486             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11487          } else 
11488             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11489       } else if (!strcasecmp(v->name, "codecpriority")) {
11490          if(!strcasecmp(v->value, "caller"))
11491             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11492          else if(!strcasecmp(v->value, "disabled"))
11493             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11494          else if(!strcasecmp(v->value, "reqonly")) {
11495             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11496             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11497          }
11498       } else if (!strcasecmp(v->name, "jitterbuffer"))
11499          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
11500       else if (!strcasecmp(v->name, "forcejitterbuffer"))
11501          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
11502       else if (!strcasecmp(v->name, "delayreject"))
11503          delayreject = ast_true(v->value);
11504       else if (!strcasecmp(v->name, "allowfwdownload"))
11505          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11506       else if (!strcasecmp(v->name, "rtcachefriends"))
11507          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
11508       else if (!strcasecmp(v->name, "rtignoreregexpire"))
11509          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
11510       else if (!strcasecmp(v->name, "rtupdate"))
11511          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11512       else if (!strcasecmp(v->name, "trunktimestamps"))
11513          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11514       else if (!strcasecmp(v->name, "rtautoclear")) {
11515          int i = atoi(v->value);
11516          if(i > 0)
11517             global_rtautoclear = i;
11518          else
11519             i = 0;
11520          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
11521       } else if (!strcasecmp(v->name, "trunkfreq")) {
11522          trunkfreq = atoi(v->value);
11523          if (trunkfreq < 10)
11524             trunkfreq = 10;
11525       } else if (!strcasecmp(v->name, "autokill")) {
11526          if (sscanf(v->value, "%30d", &x) == 1) {
11527             if (x >= 0)
11528                autokill = x;
11529             else
11530                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11531          } else if (ast_true(v->value)) {
11532             autokill = DEFAULT_MAXMS;
11533          } else {
11534             autokill = 0;
11535          }
11536       } else if (!strcasecmp(v->name, "bandwidth")) {
11537          if (!strcasecmp(v->value, "low")) {
11538             capability = IAX_CAPABILITY_LOWBANDWIDTH;
11539          } else if (!strcasecmp(v->value, "medium")) {
11540             capability = IAX_CAPABILITY_MEDBANDWIDTH;
11541          } else if (!strcasecmp(v->value, "high")) {
11542             capability = IAX_CAPABILITY_FULLBANDWIDTH;
11543          } else
11544             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11545       } else if (!strcasecmp(v->name, "allow")) {
11546          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11547       } else if (!strcasecmp(v->name, "disallow")) {
11548          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11549       } else if (!strcasecmp(v->name, "register")) {
11550          iax2_register(v->value, v->lineno);
11551       } else if (!strcasecmp(v->name, "iaxcompat")) {
11552          iaxcompat = ast_true(v->value);
11553       } else if (!strcasecmp(v->name, "regcontext")) {
11554          ast_copy_string(regcontext, v->value, sizeof(regcontext));
11555          /* Create context if it doesn't exist already */
11556          if (!ast_context_find(regcontext))
11557             ast_context_create(NULL, regcontext, "IAX2");
11558       } else if (!strcasecmp(v->name, "tos")) {
11559          if (ast_str2tos(v->value, &tos))
11560             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
11561       } else if (!strcasecmp(v->name, "accountcode")) {
11562          ast_copy_string(accountcode, v->value, sizeof(accountcode));
11563       } else if (!strcasecmp(v->name, "mohinterpret")) {
11564          ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11565       } else if (!strcasecmp(v->name, "mohsuggest")) {
11566          ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11567       } else if (!strcasecmp(v->name, "amaflags")) {
11568          format = ast_cdr_amaflags2int(v->value);
11569          if (format < 0) {
11570             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11571          } else {
11572             amaflags = format;
11573          }
11574       } else if (!strcasecmp(v->name, "language")) {
11575          ast_copy_string(language, v->value, sizeof(language));
11576       } else if (!strcasecmp(v->name, "maxauthreq")) {
11577          maxauthreq = atoi(v->value);
11578          if (maxauthreq < 0)
11579             maxauthreq = 0;
11580       } else if (!strcasecmp(v->name, "adsi")) {
11581          adsi = ast_true(v->value);
11582       } else if (!strcasecmp(v->name, "maxcallnumbers")) {
11583          if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
11584             ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number.  %s is not valid at line %d\n", v->value, v->lineno);
11585          }
11586       } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
11587          if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
11588             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);
11589          }
11590       } else if (!strcasecmp(v->name, "calltokenoptional")) {
11591          if (add_calltoken_ignore(v->value)) {
11592             ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
11593          }
11594       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
11595          if (ast_true(v->value)) {
11596             ast_set_flag((&globalflags), IAX_SHRINKCALLERID);
11597          } else if (ast_false(v->value)) {
11598             ast_clear_flag((&globalflags), IAX_SHRINKCALLERID);
11599          } else {
11600             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
11601          }
11602       }/*else if (strcasecmp(v->name,"type")) */
11603       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
11604       v = v->next;
11605    }
11606    
11607    if (defaultsockfd < 0) {
11608       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
11609          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11610       } else {
11611          if (option_verbose > 1)
11612             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11613          defaultsockfd = ast_netsock_sockfd(ns);
11614          ast_netsock_unref(ns);
11615       }
11616    }
11617    if (reload) {
11618       ast_netsock_release(outsock);
11619       outsock = ast_netsock_list_alloc();
11620       if (!outsock) {
11621          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11622          return -1;
11623       }
11624       ast_netsock_init(outsock);
11625    }
11626 
11627    if (min_reg_expire > max_reg_expire) {
11628       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11629          min_reg_expire, max_reg_expire, max_reg_expire);
11630       min_reg_expire = max_reg_expire;
11631    }
11632    iax2_capability = capability;
11633    
11634    ucfg = ast_config_load("users.conf");
11635    if (ucfg) {
11636       struct ast_variable *gen;
11637       int genhasiax;
11638       int genregisteriax;
11639       const char *hasiax, *registeriax;
11640       
11641       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11642       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11643       gen = ast_variable_browse(ucfg, "general");
11644       cat = ast_category_browse(ucfg, NULL);
11645       while (cat) {
11646          if (strcasecmp(cat, "general")) {
11647             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11648             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11649             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11650                /* Start with general parameters, then specific parameters, user and peer */
11651                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11652                if (user) {
11653                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11654                   user = user_unref(user);
11655                }
11656                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11657                if (peer) {
11658                   if (ast_test_flag(peer, IAX_DYNAMIC))
11659                      reg_source_db(peer);
11660                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11661                   peer = peer_unref(peer);
11662                }
11663             }
11664             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11665                char tmp[256];
11666                const char *host = ast_variable_retrieve(ucfg, cat, "host");
11667                const char *username = ast_variable_retrieve(ucfg, cat, "username");
11668                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11669                if (!host)
11670                   host = ast_variable_retrieve(ucfg, "general", "host");
11671                if (!username)
11672                   username = ast_variable_retrieve(ucfg, "general", "username");
11673                if (!secret)
11674                   secret = ast_variable_retrieve(ucfg, "general", "secret");
11675                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11676                   if (!ast_strlen_zero(secret))
11677                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11678                   else
11679                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11680                   iax2_register(tmp, 0);
11681                }
11682             }
11683          }
11684          cat = ast_category_browse(ucfg, cat);
11685       }
11686       ast_config_destroy(ucfg);
11687    }
11688    
11689    cat = ast_category_browse(cfg, NULL);
11690    while(cat) {
11691       if (strcasecmp(cat, "general")) {
11692          utype = ast_variable_retrieve(cfg, cat, "type");
11693          if (!strcasecmp(cat, "callnumberlimits")) {
11694             build_callno_limits(ast_variable_browse(cfg, cat));
11695          } else if (utype) {
11696             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11697                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11698                if (user) {
11699                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11700                   user = user_unref(user);
11701                }
11702             }
11703             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11704                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11705                if (peer) {
11706                   if (ast_test_flag(peer, IAX_DYNAMIC))
11707                      reg_source_db(peer);
11708                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
11709                   peer = peer_unref(peer);
11710                }
11711             } else if (strcasecmp(utype, "user")) {
11712                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11713             }
11714          } else
11715             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11716       }
11717       cat = ast_category_browse(cfg, cat);
11718    }
11719    ast_config_destroy(cfg);
11720    set_timing();
11721    return 1;
11722 }

static void set_config_destroy ( void   )  [static]

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

11323 {
11324    strcpy(accountcode, "");
11325    strcpy(language, "");
11326    strcpy(mohinterpret, "default");
11327    strcpy(mohsuggest, "");
11328    amaflags = 0;
11329    delayreject = 0;
11330    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
11331    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
11332    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
11333    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
11334    delete_users();
11335    ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
11336    ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
11337 }

static void set_peercnt_limit ( struct peercnt peercnt  )  [static]

Definition at line 1886 of file chan_iax2.c.

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

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

01887 {
01888    uint16_t limit = global_maxcallno;
01889    struct addr_range *addr_range;
01890    struct sockaddr_in sin = {
01891       .sin_addr.s_addr = peercnt->addr,
01892    };
01893 
01894 
01895    if (peercnt->reg && peercnt->limit) {
01896       return; /* this peercnt has a custom limit set by a registration */
01897    }
01898 
01899    if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
01900       limit = addr_range->limit;
01901       if (option_debug) {
01902          ast_log(LOG_DEBUG, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
01903       }
01904       ao2_ref(addr_range, -1);
01905    }
01906 
01907    peercnt->limit = limit;
01908 }

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

Definition at line 1914 of file chan_iax2.c.

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

Referenced by reload_config().

01915 {
01916    struct peercnt *peercnt = obj;
01917 
01918    set_peercnt_limit(peercnt);
01919    if (option_debug) {
01920       ast_log(LOG_DEBUG, "Reset limits for peercnts table\n");
01921    }
01922    return 0;
01923 }

static void set_timing ( void   )  [static]

Definition at line 11307 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by set_config().

11308 {
11309 #ifdef HAVE_DAHDI
11310    int bs = trunkfreq * 8;
11311    if (timingfd > -1) {
11312       if (
11313 #ifdef DAHDI_TIMERACK
11314          ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
11315 #endif         
11316          ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
11317          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
11318    }
11319 #endif
11320 }

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

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

00862 {
00863    ast_mutex_lock(lock);
00864    ast_cond_signal(cond);
00865    ast_mutex_unlock(lock);
00866 }

static int socket_process ( struct iax2_thread thread  )  [static]

Definition at line 8315 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(), send_signaling(), 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().

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

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

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

08238 {
08239    struct iax2_thread *thread;
08240    socklen_t len;
08241    time_t t;
08242    static time_t last_errtime = 0;
08243    struct ast_iax2_full_hdr *fh;
08244 
08245    if (!(thread = find_idle_thread())) {
08246       time(&t);
08247       if (t != last_errtime && option_debug)
08248          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
08249       last_errtime = t;
08250       usleep(1);
08251       return 1;
08252    }
08253 
08254    len = sizeof(thread->iosin);
08255    thread->iofd = fd;
08256    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
08257    thread->buf_size = sizeof(thread->readbuf);
08258    thread->buf = thread->readbuf;
08259    if (thread->buf_len < 0) {
08260       if (errno != ECONNREFUSED && errno != EAGAIN)
08261          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
08262       handle_error();
08263       thread->iostate = IAX_IOSTATE_IDLE;
08264       signal_condition(&thread->lock, &thread->cond);
08265       return 1;
08266    }
08267    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
08268       thread->iostate = IAX_IOSTATE_IDLE;
08269       signal_condition(&thread->lock, &thread->cond);
08270       return 1;
08271    }
08272    
08273    /* Determine if this frame is a full frame; if so, and any thread is currently
08274       processing a full frame for the same callno from this peer, then drop this
08275       frame (and the peer will retransmit it) */
08276    fh = (struct ast_iax2_full_hdr *) thread->buf;
08277    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08278       struct iax2_thread *cur = NULL;
08279       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08280       
08281       AST_LIST_LOCK(&active_list);
08282       AST_LIST_TRAVERSE(&active_list, cur, list) {
08283          if ((cur->ffinfo.callno == callno) &&
08284              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08285             break;
08286       }
08287       if (cur) {
08288          /* we found another thread processing a full frame for this call,
08289             so queue it up for processing later. */
08290          defer_full_frame(thread, cur);
08291          AST_LIST_UNLOCK(&active_list);
08292          thread->iostate = IAX_IOSTATE_IDLE;
08293          signal_condition(&thread->lock, &thread->cond);
08294          return 1;
08295       } else {
08296          /* this thread is going to process this frame, so mark it */
08297          thread->ffinfo.callno = callno;
08298          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08299          thread->ffinfo.type = fh->type;
08300          thread->ffinfo.csub = fh->csub;
08301       }
08302       AST_LIST_UNLOCK(&active_list);
08303    }
08304    
08305    /* Mark as ready and send on its way */
08306    thread->iostate = IAX_IOSTATE_READY;
08307 #ifdef DEBUG_SCHED_MULTITHREAD
08308    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08309 #endif
08310    signal_condition(&thread->lock, &thread->cond);
08311 
08312    return 1;
08313 }

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

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

08025 {
08026    pthread_t newthread;
08027    struct dpreq_data *dpr;
08028    pthread_attr_t attr;
08029    
08030    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
08031       return;
08032 
08033    pthread_attr_init(&attr);
08034    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
08035 
08036    dpr->callno = callno;
08037    ast_copy_string(dpr->context, context, sizeof(dpr->context));
08038    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
08039    if (callerid)
08040       dpr->callerid = ast_strdup(callerid);
08041    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
08042       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
08043    }
08044 
08045    pthread_attr_destroy(&attr);
08046 }

static int start_network_thread ( void   )  [static]

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

10572 {
10573    pthread_attr_t attr;
10574    int threadcount = 0;
10575    int x;
10576    for (x = 0; x < iaxthreadcount; x++) {
10577       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
10578       if (thread) {
10579          thread->type = IAX_TYPE_POOL;
10580          thread->threadnum = ++threadcount;
10581          ast_mutex_init(&thread->lock);
10582          ast_cond_init(&thread->cond, NULL);
10583          pthread_attr_init(&attr);
10584          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
10585          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
10586             ast_log(LOG_WARNING, "Failed to create new thread!\n");
10587             free(thread);
10588             thread = NULL;
10589          }
10590          AST_LIST_LOCK(&idle_list);
10591          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10592          AST_LIST_UNLOCK(&idle_list);
10593       }
10594    }
10595    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10596    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10597    if (option_verbose > 1)
10598       ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
10599    return 0;
10600 }

static void stop_stuff ( int  callno  )  [static]

Definition at line 7706 of file chan_iax2.c.

References iax2_destroy_helper(), and iaxs.

Referenced by socket_process().

07707 {
07708    iax2_destroy_helper(iaxs[callno]);
07709 }

static void store_by_peercallno ( struct chan_iax2_pvt pvt  )  [static]

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

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

static void store_by_transfercallno ( struct chan_iax2_pvt pvt  )  [static]

Definition at line 1379 of file chan_iax2.c.

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

Referenced by try_transfer().

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

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

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

07894 {
07895    char buf[1024];
07896    int res;
07897    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
07898    int processed = 0;
07899    int totalcalls = 0;
07900 #ifdef DAHDI_TIMERACK
07901    int x = 1;
07902 #endif
07903    struct timeval now;
07904    if (iaxtrunkdebug)
07905       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
07906    gettimeofday(&now, NULL);
07907    if (events & AST_IO_PRI) {
07908 #ifdef DAHDI_TIMERACK
07909       /* Great, this is a timing interface, just call the ioctl */
07910       if (ioctl(fd, DAHDI_TIMERACK, &x)) {
07911          ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
07912          usleep(1);
07913          return -1;
07914       }
07915 #endif      
07916    } else {
07917       /* Read and ignore from the pseudo channel for timing */
07918       res = read(fd, buf, sizeof(buf));
07919       if (res < 1) {
07920          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
07921          return 1;
07922       }
07923    }
07924    /* For each peer that supports trunking... */
07925    ast_mutex_lock(&tpeerlock);
07926    tpeer = tpeers;
07927    while(tpeer) {
07928       processed++;
07929       res = 0;
07930       ast_mutex_lock(&tpeer->lock);
07931       /* We can drop a single tpeer per pass.  That makes all this logic
07932          substantially easier */
07933       if (!drop && iax2_trunk_expired(tpeer, &now)) {
07934          /* Take it out of the list, but don't free it yet, because it
07935             could be in use */
07936          if (prev)
07937             prev->next = tpeer->next;
07938          else
07939             tpeers = tpeer->next;
07940          drop = tpeer;
07941       } else {
07942          res = send_trunk(tpeer, &now);
07943          if (iaxtrunkdebug)
07944             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);
07945       }     
07946       totalcalls += res;   
07947       res = 0;
07948       ast_mutex_unlock(&tpeer->lock);
07949       prev = tpeer;
07950       tpeer = tpeer->next;
07951    }
07952    ast_mutex_unlock(&tpeerlock);
07953    if (drop) {
07954       ast_mutex_lock(&drop->lock);
07955       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
07956          because by the time they could get tpeerlock, we've already grabbed it */
07957       if (option_debug)
07958          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07959       if (drop->trunkdata) {
07960          free(drop->trunkdata);
07961          drop->trunkdata = NULL;
07962       }
07963       ast_mutex_unlock(&drop->lock);
07964       ast_mutex_destroy(&drop->lock);
07965       free(drop);
07966       
07967    }
07968    if (iaxtrunkdebug)
07969       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07970    iaxtrunkdebug =0;
07971    return 1;
07972 }

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

Definition at line 12625 of file chan_iax2.c.

References chan_iax2_pvt::frames_received, and match().

Referenced by load_objects().

12626 {
12627    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12628 
12629    /* The frames_received field is used to hold whether we're matching
12630     * against a full frame or not ... */
12631 
12632    return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12633       pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12634 }

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

Definition at line 12618 of file chan_iax2.c.

References chan_iax2_pvt::transfercallno.

Referenced by load_objects().

12619 {
12620    const struct chan_iax2_pvt *pvt = obj;
12621 
12622    return pvt->transfercallno;
12623 }

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

Definition at line 2959 of file chan_iax2.c.

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

Referenced by send_trunk().

02960 {
02961    int res;
02962    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02963                sizeof(*sin));
02964    if (res < 0) {
02965       if (option_debug)
02966          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02967       handle_error();
02968    } else
02969       res = 0;
02970    return res;
02971 }

static int try_firmware ( char *  s  )  [static]

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

02648 {
02649    struct stat stbuf;
02650    struct iax_firmware *cur;
02651    int ifd;
02652    int fd;
02653    int res;
02654    
02655    struct ast_iax2_firmware_header *fwh, fwh2;
02656    struct MD5Context md5;
02657    unsigned char sum[16];
02658    unsigned char buf[1024];
02659    int len, chunk;
02660    char *s2;
02661    char *last;
02662    s2 = alloca(strlen(s) + 100);
02663    if (!s2) {
02664       ast_log(LOG_WARNING, "Alloca failed!\n");
02665       return -1;
02666    }
02667    last = strrchr(s, '/');
02668    if (last)
02669       last++;
02670    else
02671       last = s;
02672    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02673    res = stat(s, &stbuf);
02674    if (res < 0) {
02675       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02676       return -1;
02677    }
02678    /* Make sure it's not a directory */
02679    if (S_ISDIR(stbuf.st_mode))
02680       return -1;
02681    ifd = open(s, O_RDONLY);
02682    if (ifd < 0) {
02683       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02684       return -1;
02685    }
02686    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
02687    if (fd < 0) {
02688       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02689       close(ifd);
02690       return -1;
02691    }
02692    /* Unlink our newly created file */
02693    unlink(s2);
02694    
02695    /* Now copy the firmware into it */
02696    len = stbuf.st_size;
02697    while(len) {
02698       chunk = len;
02699       if (chunk > sizeof(buf))
02700          chunk = sizeof(buf);
02701       res = read(ifd, buf, chunk);
02702       if (res != chunk) {
02703          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02704          close(ifd);
02705          close(fd);
02706          return -1;
02707       }
02708       res = write(fd, buf, chunk);
02709       if (res != chunk) {
02710          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02711          close(ifd);
02712          close(fd);
02713          return -1;
02714       }
02715       len -= chunk;
02716    }
02717    close(ifd);
02718    /* Return to the beginning */
02719    lseek(fd, 0, SEEK_SET);
02720    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02721       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02722       close(fd);
02723       return -1;
02724    }
02725    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02726       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02727       close(fd);
02728       return -1;
02729    }
02730    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02731       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02732       close(fd);
02733       return -1;
02734    }
02735    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02736       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02737       close(fd);
02738       return -1;
02739    }
02740    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
02741    if (fwh == MAP_FAILED) {
02742       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02743       close(fd);
02744       return -1;
02745    }
02746    MD5Init(&md5);
02747    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02748    MD5Final(sum, &md5);
02749    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02750       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02751       munmap((void*)fwh, stbuf.st_size);
02752       close(fd);
02753       return -1;
02754    }
02755    cur = waresl.wares;
02756    while(cur) {
02757       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02758          /* Found a candidate */
02759          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02760             /* The version we have on loaded is older, load this one instead */
02761             break;
02762          /* This version is no newer than what we have.  Don't worry about it.
02763             We'll consider it a proper load anyhow though */
02764          munmap((void*)fwh, stbuf.st_size);
02765          close(fd);
02766          return 0;
02767       }
02768       cur = cur->next;
02769    }
02770    if (!cur) {
02771       /* Allocate a new one and link it */
02772       if ((cur = ast_calloc(1, sizeof(*cur)))) {
02773          cur->fd = -1;
02774          cur->next = waresl.wares;
02775          waresl.wares = cur;
02776       }
02777    }
02778    if (cur) {
02779       if (cur->fwh) {
02780          munmap((void*)cur->fwh, cur->mmaplen);
02781       }
02782       if (cur->fd > -1)
02783          close(cur->fd);
02784       cur->fwh = fwh;
02785       cur->fd = fd;
02786       cur->mmaplen = stbuf.st_size;
02787       cur->dead = 0;
02788    }
02789    return 0;
02790 }

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

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

07075 {
07076    int newcall = 0;
07077    char newip[256];
07078    struct iax_ie_data ied;
07079    struct sockaddr_in new;
07080    
07081    
07082    memset(&ied, 0, sizeof(ied));
07083    if (ies->apparent_addr)
07084       bcopy(ies->apparent_addr, &new, sizeof(new));
07085    if (ies->callno)
07086       newcall = ies->callno;
07087    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
07088       ast_log(LOG_WARNING, "Invalid transfer request\n");
07089       return -1;
07090    }
07091    pvt->transfercallno = newcall;
07092    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
07093    inet_aton(newip, &pvt->transfer.sin_addr);
07094    pvt->transfer.sin_family = AF_INET;
07095    pvt->transferring = TRANSFER_BEGIN;
07096    pvt->transferid = ies->transferid;
07097    store_by_transfercallno(pvt);
07098    if (ies->transferid)
07099       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
07100    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
07101    return 0;
07102 }

static int uncompress_subclass ( unsigned char  csub  )  [static]

Definition at line 1214 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

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

01215 {
01216    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01217    if (csub & IAX_FLAG_SC_LOG) {
01218       /* special case for 'compressed' -1 */
01219       if (csub == 0xff)
01220          return -1;
01221       else
01222          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01223    }
01224    else
01225       return csub;
01226 }

static void unlink_peer ( struct iax2_peer peer  )  [static]

Definition at line 7358 of file chan_iax2.c.

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

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

07359 {
07360    if (peer->expire > -1) {
07361       if (!ast_sched_del(sched, peer->expire)) {
07362          peer->expire = -1;
07363          peer_unref(peer);
07364       }
07365    }
07366 
07367    if (peer->pokeexpire > -1) {
07368       if (!ast_sched_del(sched, peer->pokeexpire)) {
07369          peer->pokeexpire = -1;
07370          peer_unref(peer);
07371       }
07372    }
07373 
07374    ao2_unlink(peers, peer);
07375 }

static int unload_module ( void   )  [static]

Definition at line 12584 of file chan_iax2.c.

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

12585 {
12586    ast_custom_function_unregister(&iaxpeer_function);
12587    return __unload_module();
12588 }

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

Definition at line 4695 of file chan_iax2.c.

References ast_mutex_unlock(), and iaxsl.

Referenced by iax2_bridge().

04696 {
04697    ast_mutex_unlock(&iaxsl[callno1]);
04698    ast_mutex_unlock(&iaxsl[callno0]);
04699 }

static void unwrap_timestamp ( struct iax_frame fr  )  [static]

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

03432 {
03433    /* Video mini frames only encode the lower 15 bits of the session
03434     * timestamp, but other frame types (e.g. audio) encode 16 bits. */
03435    const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03436    const int lower_mask = (1 << ts_shift) - 1;
03437    const int upper_mask = ~lower_mask;
03438    const int last_upper = iaxs[fr->callno]->last & upper_mask;
03439 
03440    if ( (fr->ts & upper_mask) == last_upper ) {
03441       const int x = fr->ts - iaxs[fr->callno]->last;
03442       const int threshold = (ts_shift == 15) ? 25000 : 50000;
03443 
03444       if (x < -threshold) {
03445          /* Sudden big jump backwards in timestamp:
03446             What likely happened here is that miniframe timestamp has circled but we haven't
03447             gotten the update from the main packet.  We'll just pretend that we did, and
03448             update the timestamp appropriately. */
03449          fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
03450          if (option_debug && iaxdebug)
03451             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
03452       } else if (x > threshold) {
03453          /* Sudden apparent big jump forwards in timestamp:
03454             What's likely happened is this is an old miniframe belonging to the previous
03455             top 15 or 16-bit timestamp that has turned up out of order.
03456             Adjust the timestamp appropriately. */
03457          fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03458          if (option_debug && iaxdebug)
03459             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
03460       }
03461    }
03462 }

static void update_jbsched ( struct chan_iax2_pvt pvt  )  [static]

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

03467 {
03468    int when;
03469    
03470    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03471    
03472    when = jb_next(pvt->jb) - when;
03473 
03474    AST_SCHED_DEL(sched, pvt->jbid);
03475 
03476    if(when <= 0) {
03477       /* XXX should really just empty until when > 0.. */
03478       when = 1;
03479    }
03480    
03481    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
03482 }

static void update_max_nontrunk ( void   )  [static]

Definition at line 1705 of file chan_iax2.c.

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

Referenced by __find_callno(), and make_trunk().

01706 {
01707    int max = 1;
01708    int x;
01709    /* XXX Prolly don't need locks here XXX */
01710    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01711       if (iaxs[x])
01712          max = x + 1;
01713    }
01714    maxnontrunkcall = max;
01715    if (option_debug && iaxdebug)
01716       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01717 }

static void update_max_trunk ( void   )  [static]

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

01419 {
01420    int max = TRUNK_CALL_START;
01421    int x;
01422 
01423    /* XXX Prolly don't need locks here XXX */
01424    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01425       if (iaxs[x]) {
01426          max = x + 1;
01427       }
01428    }
01429 
01430    maxtrunkcall = max;
01431    if (option_debug && iaxdebug)
01432       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01433 }

static int update_packet ( struct iax_frame f  )  [static]

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

03031 {
03032    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
03033    struct ast_iax2_full_hdr *fh = f->data;
03034    struct ast_frame af;
03035 
03036    /* if frame is encrypted. decrypt before updating it. */
03037    if (f->encmethods) {
03038       decode_frame(&f->mydcx, fh, &af, &f->datalen);
03039    }
03040    /* Mark this as a retransmission */
03041    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03042    /* Update iseqno */
03043    f->iseqno = iaxs[f->callno]->iseqno;
03044    fh->iseqno = f->iseqno;
03045 
03046    /* Now re-encrypt the frame */
03047    if (f->encmethods) {
03048    /* since this is a retransmit frame, create a new random padding
03049     * before re-encrypting. */
03050       build_rand_pad(f->semirand, sizeof(f->semirand));
03051       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03052    }
03053    return 0;
03054 }

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

07472 {
07473    /* Called from IAX thread only, with proper iaxsl lock */
07474    struct iax_ie_data ied;
07475    struct iax2_peer *p;
07476    int msgcount;
07477    char data[80];
07478    int version;
07479    const char *peer_name;
07480    int res = -1;
07481 
07482    memset(&ied, 0, sizeof(ied));
07483 
07484    peer_name = ast_strdupa(iaxs[callno]->peer);
07485 
07486    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
07487    ast_mutex_unlock(&iaxsl[callno]);
07488    if (!(p = find_peer(peer_name, 1))) {
07489       ast_mutex_lock(&iaxsl[callno]);
07490       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07491       return -1;
07492    }
07493    ast_mutex_lock(&iaxsl[callno]);
07494    if (!iaxs[callno])
07495       goto return_unref;
07496 
07497    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07498       if (sin->sin_addr.s_addr) {
07499          time_t nowtime;
07500          time(&nowtime);
07501          realtime_update_peer(peer_name, sin, nowtime);
07502       } else {
07503          realtime_update_peer(peer_name, sin, 0);
07504       }
07505    }
07506    if (inaddrcmp(&p->addr, sin)) {
07507       if (iax2_regfunk)
07508          iax2_regfunk(p->name, 1);
07509 
07510       /* modify entry in peercnts table as _not_ registered */
07511       peercnt_modify(0, 0, &p->addr);
07512 
07513       /* Stash the IP address from which they registered */
07514       memcpy(&p->addr, sin, sizeof(p->addr));
07515 
07516       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07517       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07518          ast_db_put("IAX/Registry", p->name, data);
07519          if  (option_verbose > 2)
07520             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
07521                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07522          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07523          register_peer_exten(p, 1);
07524          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07525       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07526          if  (option_verbose > 2)
07527             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
07528                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07529          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07530          register_peer_exten(p, 0);
07531          ast_db_del("IAX/Registry", p->name);
07532          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
07533       }
07534       /* Update the host */
07535       /* Verify that the host is really there */
07536       iax2_poke_peer(p, callno);
07537    }
07538 
07539    /* modify entry in peercnts table as registered */
07540    if (p->maxcallno) {
07541       peercnt_modify(1, p->maxcallno, &p->addr);
07542    }
07543 
07544    /* Make sure our call still exists, an INVAL at the right point may make it go away */
07545    if (!iaxs[callno]) {
07546       res = -1;
07547       goto return_unref;
07548    }
07549 
07550    /* Store socket fd */
07551    p->sockfd = fd;
07552    /* Setup the expiry */
07553    if (p->expire > -1) {
07554       if (!ast_sched_del(sched, p->expire)) {
07555          p->expire = -1;
07556          peer_unref(p);
07557       }
07558    }
07559    /* treat an unspecified refresh interval as the minimum */
07560    if (!refresh)
07561       refresh = min_reg_expire;
07562    if (refresh > max_reg_expire) {
07563       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07564          p->name, max_reg_expire, refresh);
07565       p->expiry = max_reg_expire;
07566    } else if (refresh < min_reg_expire) {
07567       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07568          p->name, min_reg_expire, refresh);
07569       p->expiry = min_reg_expire;
07570    } else {
07571       p->expiry = refresh;
07572    }
07573    if (p->expiry && sin->sin_addr.s_addr) {
07574       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07575       if (p->expire == -1)
07576          peer_unref(p);
07577    }
07578    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07579    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07580    if (sin->sin_addr.s_addr) {
07581       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07582       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07583       if (!ast_strlen_zero(p->mailbox)) {
07584          int new, old;
07585          ast_app_inboxcount(p->mailbox, &new, &old);
07586          if (new > 255)
07587             new = 255;
07588          if (old > 255)
07589             old = 255;
07590          msgcount = (old << 8) | new;
07591          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07592       }
07593       if (ast_test_flag(p, IAX_HASCALLERID)) {
07594          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07595          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07596       }
07597    }
07598    version = iax_check_version(devtype);
07599    if (version) 
07600       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07601 
07602    res = 0;
07603 
07604 return_unref:
07605    peer_unref(p);
07606 
07607    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07608 }

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

References iax2_user::name.

Referenced by load_objects().

01262 {
01263    struct iax2_user *user = obj, *user2 = arg;
01264 
01265    return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01266 }

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

Definition at line 11240 of file chan_iax2.c.

References ast_set_flag, and IAX_DELME.

Referenced by delete_users().

11241 {
11242    struct iax2_user *user = obj;
11243 
11244    ast_set_flag(user, IAX_DELME);
11245 
11246    return 0;
11247 }

static void user_destructor ( void *  obj  )  [static]

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

10990 {
10991    struct iax2_user *user = obj;
10992 
10993    ast_free_ha(user->ha);
10994    free_context(user->contexts);
10995    if(user->vars) {
10996       ast_variables_destroy(user->vars);
10997       user->vars = NULL;
10998    }
10999    ast_string_field_free_memory(user);
11000 }

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

References ast_str_hash(), and iax2_user::name.

Referenced by load_objects().

01252 {
01253    const struct iax2_user *user = obj;
01254 
01255    return ast_str_hash(user->name);
01256 }

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

Definition at line 1309 of file chan_iax2.c.

References ao2_ref().

01310 {
01311    ao2_ref(user, +1);
01312    return user;
01313 }

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

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

01316 {
01317    ao2_ref(user, -1);
01318    return NULL;
01319 }

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

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

07808 {
07809    struct iax_frame *f;
07810 
07811    AST_LIST_LOCK(&iaxq.queue);
07812    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
07813       /* Send a copy immediately */
07814       if ((f->callno == callno) && iaxs[f->callno] &&
07815          ((unsigned char ) (f->oseqno - last) < 128) &&
07816          (f->retries >= 0)) {
07817          send_packet(f);
07818       }
07819    }
07820    AST_LIST_UNLOCK(&iaxq.queue);
07821 }

static int wait_for_peercallno ( struct chan_iax2_pvt pvt  )  [static]

Note:
expects the pvt to be locked

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

04594 {
04595    unsigned short callno = pvt->callno;
04596 
04597    if (!pvt->peercallno) {
04598       /* We don't know the remote side's call number, yet.  :( */
04599       int count = 10;
04600       while (count-- && pvt && !pvt->peercallno) {
04601          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
04602          pvt = iaxs[callno];
04603       }
04604       if (!pvt->peercallno) {
04605          return -1;
04606       }
04607    }
04608 
04609    return 0;
04610 }


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 12802 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(), findmeexec(), 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 12802 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 711 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 671 of file chan_iax2.c.

const unsigned int CALLNO_POOL_BUCKETS = 2699 [static]

Definition at line 676 of file chan_iax2.c.

struct ao2_container* callno_pool_trunk [static]

table of available trunk call numbers

Definition at line 674 of file chan_iax2.c.

struct ao2_container* calltoken_ignores [static]

Table containing ip addresses not requiring calltoken validation

Definition at line 714 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 12390 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 12370 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 12375 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 12385 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 12380 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 12365 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 12339 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 12331 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 12323 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static]

Definition at line 716 of file chan_iax2.c.

uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static]

Definition at line 718 of file chan_iax2.c.

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

uint16_t global_maxcallno_nonval [static]

Total num of call numbers allowed to be allocated without calltoken validation

Definition at line 723 of file chan_iax2.c.

int global_rtautoclear = 120 [static]

Definition at line 275 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(), check_access(), 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 12281 of file chan_iax2.c.

enum { ... } iax2_state

struct ast_switch iax2_switch [static]

Definition at line 12251 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

struct ast_channel_tech iax2_tech [static]

Definition at line 984 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 12347 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 928 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 935 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 472 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 470 of file chan_iax2.c.

Referenced by find_idle_thread(), and iax2_process_thread().

int iaxdynamicthreadnum = 0 [static]

Definition at line 471 of file chan_iax2.c.

Referenced by find_idle_thread().

int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static]

Definition at line 469 of file chan_iax2.c.

Referenced by find_idle_thread(), and set_config().

struct ast_custom_function iaxpeer_function

Definition at line 12187 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 916 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 917 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 468 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 685 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 942 of file chan_iax2.c.

int maxtrunkcall = TRUNK_CALL_START [static]

Definition at line 941 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 12343 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 12335 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 12327 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 10206 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 10208 of file chan_iax2.c.

struct ao2_container* peercnts [static]

Table containing peercnt objects for every ip address consuming a callno

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

Referenced by __iax2_show_peers(), __unload_module(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), delete_users(), find_peer(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), poke_all_peers(), prune_peers(), set_config(), and unlink_peer().

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

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

Definition at line 10207 of file chan_iax2.c.

int randomcalltokendata [static]

Definition at line 683 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 12265 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 12273 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 12297 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 12315 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 12301 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 12269 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 12309 of file chan_iax2.c.

char show_prov_usage[] [static]

Definition at line 12285 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 12319 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 12261 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 12305 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 12292 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 725 of file chan_iax2.c.

ast_mutex_t tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

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

Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), iax2_destroy_helper(), iax2_prune_realtime(), iax2_show_users(), load_objects(), prune_users(), and set_config().

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 Sun Aug 15 20:33:35 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7