Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:05 2007

Asterisk developer's documentation :: Codename Pineapple


chan_iax2.c File Reference


Detailed Description

Implementation of Inter-Asterisk eXchange Version 2.

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

Definition in file chan_iax2.c.

#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 "asterisk/zapata.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 "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"

Include dependency graph for chan_iax2.c:

Go to the source code of this file.

Data Structures

struct  chan_iax2_pvt
struct  create_addr_info
struct  dpreq_data
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_registry
struct  iax2_thread
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  parsed_dial_string

Defines

#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#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\n"
#define FORMAT   "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\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
#define IAX_CAPABILITY_LOWBANDWIDTH
#define IAX_CAPABILITY_LOWFREE
#define IAX_CAPABILITY_MEDBANDWIDTH
#define IPTOS_MINCOST   0x02
#define MAX_JITTER_BUFFER   50
#define MAX_RETRY_TIME   10000
#define MAX_TIMESTAMP_SKEW   160
#define MAX_TRUNK_MTU   1240
 Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
#define MAX_TRUNKDATA   640 * 200
#define MEMORY_SIZE   100
#define MIN_JITTER_BUFFER   10
#define MIN_RETRY_TIME   100
#define MIN_REUSE_TIME   60
#define NEW_ALLOW   1
#define NEW_FORCE   2
#define NEW_PREVENT   0
#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   0x4000
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

enum  {
  CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3),
  CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7)
}
enum  iax2_flags {
  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)
}
enum  iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2), IAX_STATE_UNCHANGED = (1 << 3) }
enum  iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY }
enum  iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC }
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED,
  TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS
}

Functions

static void __attempt_transmit (void *data)
static void __auth_reject (void *nothing)
static void __auto_congest (void *nothing)
static void __auto_hangup (void *nothing)
static int __do_deliver (void *data)
static void __expire_registry (void *data)
static void __get_from_jb (void *p)
static void __iax2_do_register_s (void *data)
static void __iax2_poke_noanswer (void *data)
static void __iax2_poke_peer_s (void *data)
static int __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[])
static int __schedule_action (void(*func)(void *data), 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 (void *data)
static void __send_ping (void *data)
static int __unload_module (void)
static int acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *varname, const char *value)
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 AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread)
static AST_LIST_HEAD_STATIC (active_list, iax2_thread)
static AST_LIST_HEAD_STATIC (idle_list, iax2_thread)
static AST_LIST_HEAD_STATIC (dpcache, iax2_dpcache)
static AST_LIST_HEAD_STATIC (firmwares, iax_firmware)
static AST_LIST_HEAD_STATIC (peers, iax2_peer)
static AST_LIST_HEAD_STATIC (users, iax2_user)
static AST_LIST_HEAD_STATIC (queue, iax_frame)
static AST_LIST_HEAD_STATIC (registrations, iax2_registry)
static AST_LIST_HEAD_STATIC (tpeers, iax2_trunk_peer)
 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,)
 AST_MUTEX_DEFINE_STATIC (sched_lock)
static int attempt_transmit (void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (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, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
static int authenticate_request (struct chan_iax2_pvt *p)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (void *data)
static int auto_hangup (void *data)
static struct iax2_contextbuild_context (char *context)
static void build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
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 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 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 sockaddr_in *sin, struct create_addr_info *cai)
static int decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void delete_users (void)
static void destroy_firmware (struct iax_firmware *cur)
static void destroy_peer (struct iax2_peer *peer)
static void destroy_user (struct iax2_user *user)
static void dp_lookup (int callno, 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 (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 lockpeer, int sockfd)
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 unsigned int fix_peerts (struct timeval *tv, int callno, unsigned int ts)
static void free_context (struct iax2_context *con)
static int function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int get_auth_methods (char *value)
static int get_encrypt_methods (const char *s)
static int get_from_jb (void *p)
static int handle_error (void)
static int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
static int iax2_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 (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, int lockpeer)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition, 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 (void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_s (void *data)
static int iax2_predestroy (int callno)
static void * iax2_process_thread (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_frame (int callno, struct ast_frame *f)
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_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
static int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
static int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
static int iax2_sendtext (struct ast_channel *c, const char *text)
static int iax2_set_mtu (int fd, int argc, char *argv[])
 Set trunk MTU from CLI.
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_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 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)
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, int lockpeer, const char *host)
static void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
static int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
 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 void prune_peers (void)
static void prune_users (void)
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)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime)
static struct iax2_userrealtime_user (const char *username)
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 (const char *name, 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 (void)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
static void * sched_thread (void *ignore)
static int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
static int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
static int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
static int send_lagrq (void *data)
static int send_packet (struct iax_frame *f)
static int send_ping (void *data)
static int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int set_config (char *config_file, int reload)
 Load configuration.
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_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr)
static int socket_read (int *id, int fd, short events, void *cbdata)
static void spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid)
static int start_network_thread (void)
static void stop_stuff (int callno)
static void thread_free (struct iax2_thread *thread)
static int timing_read (int *id, int fd, short events, void *cbdata)
static int transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
static int try_firmware (char *s)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static int uncompress_subclass (unsigned char csub)
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 (const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
static void vnak_retransmit (int callno, int last)

Variables

static char accountcode [AST_MAX_ACCOUNT_CODE]
static int adsi = 0
static int amaflags = 0
static int authdebug = 1
static int autokill = 0
static struct ast_cli_entry cli_iax2 []
static char context [80] = "default"
static const char debug_jb_usage []
static const char debug_trunk_usage []
static const char debug_usage []
static int defaultsockfd = -1
static int delayreject = 0
static int global_max_trunk_mtu
static int global_rtautoclear = 120
static struct ast_flags globalflags = { 0 }
static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static int iax2_encryption = 0
int(* iax2_regfunk )(const char *username, int onoff) = NULL
static const char iax2_reload_usage []
static struct ast_switch iax2_switch
static const struct ast_channel_tech iax2_tech
static const char iax2_test_losspct_usage []
static int iaxcompat = 0
static int iaxdebug = 0
static int iaxdefaultdpcache = 10 * 60
static int iaxdefaulttimeout = 5
static int iaxdynamicthreadcount = 0
static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT
ast_custom_function iaxpeer_function
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
 an array of iax2 pvt structures
static ast_mutex_t iaxsl [IAX_MAX_CALLS]
 chan_iax2_pvt structure locks
static int iaxthreadcount = DEFAULT_THREAD_COUNT
static int iaxtrunkdebug = 0
static struct ast_custom_function iaxvar_function
static struct io_contextio
static int jittertargetextra = 40
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static struct timeval lastused [IAX_MAX_CALLS]
 The last time a call number was used.
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 const char no_debug_jb_usage []
static const char no_debug_trunk_usage []
static const char no_debug_usage []
static char * papp = "IAX2Provision"
static char * pdescrip
static int ping_time = 20
static struct ast_codec_pref prefs
static const char prune_realtime_usage []
static char * psyn = "Provision a calling IAXy with a given template"
static char regcontext [AST_MAX_CONTEXT] = ""
static int resyncthreshold = 1000
static struct sched_contextsched
static ast_cond_t sched_cond
static pthread_t schedthreadid = AST_PTHREADT_NULL
static const char set_mtu_usage []
static const char show_cache_usage []
static const char show_channels_usage []
static const char show_firmware_usage []
static const char show_netstats_usage []
static const char show_peer_usage []
static const char show_peers_usage []
static const char show_prov_usage []
static const char show_reg_usage []
static const char show_stats_usage []
static const char show_threads_usage []
static const char show_users_usage []
static int srvlookup = 0
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 int trunk_maxmtu
static int trunk_nmaxmtu
static int trunk_timed
static int trunk_untimed
static int trunkfreq = 20
static int trunkmaxsize = MAX_TRUNKDATA


Define Documentation

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

Definition at line 118 of file chan_iax2.c.

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

#define DEBUG_SCHED_MULTITHREAD
 

Definition at line 106 of file chan_iax2.c.

#define DEBUG_SUPPORT
 

Definition at line 129 of file chan_iax2.c.

#define DEFAULT_DROP   3
 

Definition at line 124 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000
 

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

Referenced by build_peer(), and handle_response_peerpoke().

#define DEFAULT_MAX_THREAD_COUNT   100
 

Definition at line 121 of file chan_iax2.c.

#define DEFAULT_MAXMS   2000
 

Definition at line 210 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME   1000
 

Definition at line 122 of file chan_iax2.c.

Referenced by complete_transfer().

#define DEFAULT_THREAD_COUNT   10
 

Definition at line 120 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10
 

40ms, uncompressed linear * 10 channels

Definition at line 454 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

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

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

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

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

#define FORMAT2   "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\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 134 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 374 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
 

Definition at line 193 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH
 

Value:

Definition at line 201 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE
 

Value:

Definition at line 206 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH
 

Value:

Definition at line 195 of file chan_iax2.c.

Referenced by set_config().

#define IPTOS_MINCOST   0x02
 

Definition at line 109 of file chan_iax2.c.

#define MAX_JITTER_BUFFER   50
 

Definition at line 451 of file chan_iax2.c.

#define MAX_RETRY_TIME   10000
 

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

#define MAX_TRUNK_MTU   1240
 

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

Definition at line 143 of file chan_iax2.c.

Referenced by iax2_set_mtu(), and reload_config().

#define MAX_TRUNKDATA   640 * 200
 

40ms, uncompressed linear * 200 channels

Definition at line 165 of file chan_iax2.c.

Referenced by reload_config(), and set_config().

#define MEMORY_SIZE   100
 

Definition at line 123 of file chan_iax2.c.

#define MIN_JITTER_BUFFER   10
 

Definition at line 452 of file chan_iax2.c.

#define MIN_RETRY_TIME   100
 

Definition at line 448 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60
 

Definition at line 131 of file chan_iax2.c.

Referenced by make_trunk().

#define NEW_ALLOW   1
 

Definition at line 1158 of file chan_iax2.c.

Referenced by find_callno(), and socket_process().

#define NEW_FORCE   2
 

Definition at line 1159 of file chan_iax2.c.

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

#define NEW_PREVENT   0
 

Definition at line 1157 of file chan_iax2.c.

Referenced by socket_process(), and socket_process_meta().

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

Definition at line 117 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(), and iax2_write().

#define SCHED_MULTITHREADED
 

Definition at line 102 of file chan_iax2.c.

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

Definition at line 961 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   0x4000
 

Definition at line 127 of file chan_iax2.c.

Referenced by make_trunk(), update_max_nontrunk(), and update_max_trunk().

#define TS_GAP_FOR_JB_RESYNC   5000
 

Definition at line 459 of file chan_iax2.c.


Enumeration Type Documentation

anonymous enum
 

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

Definition at line 643 of file chan_iax2.c.

00643      {
00644    /*! Extension exists */
00645    CACHE_FLAG_EXISTS      = (1 << 0),
00646    /*! Extension is nonexistent */
00647    CACHE_FLAG_NONEXISTENT = (1 << 1),
00648    /*! Extension can exist */
00649    CACHE_FLAG_CANEXIST    = (1 << 2),
00650    /*! Waiting to hear back response */
00651    CACHE_FLAG_PENDING     = (1 << 3),
00652    /*! Timed out */
00653    CACHE_FLAG_TIMEOUT     = (1 << 4),
00654    /*! Request transmitted */
00655    CACHE_FLAG_TRANSMITTED = (1 << 5),
00656    /*! Timeout */
00657    CACHE_FLAG_UNKNOWN     = (1 << 6),
00658    /*! Matchmore */
00659    CACHE_FLAG_MATCHMORE   = (1 << 7),
00660 };

enum iax2_flags
 

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

Definition at line 258 of file chan_iax2.c.

00258                 {
00259    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00260    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00261    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00262    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00263    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00264    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00265    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00266    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00267         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00268    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00269    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00270    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00271    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00272    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00273    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00274    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00275    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00276    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00277    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00278    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00279    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00280    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00281    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00282    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00283    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00284 };

enum iax2_state
 

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 
IAX_STATE_UNCHANGED 

Definition at line 246 of file chan_iax2.c.

00246                 {
00247    IAX_STATE_STARTED =     (1 << 0),
00248    IAX_STATE_AUTHENTICATED =  (1 << 1),
00249    IAX_STATE_TBD =      (1 << 2),
00250    IAX_STATE_UNCHANGED =      (1 << 3),
00251 };

enum iax2_thread_iostate
 

Enumerator:
IAX_IOSTATE_IDLE 
IAX_IOSTATE_READY 
IAX_IOSTATE_PROCESSING 
IAX_IOSTATE_SCHEDREADY 

Definition at line 682 of file chan_iax2.c.

enum iax2_thread_type
 

Enumerator:
IAX_THREAD_TYPE_POOL 
IAX_THREAD_TYPE_DYNAMIC 

Definition at line 689 of file chan_iax2.c.

00689                       {
00690    IAX_THREAD_TYPE_POOL,
00691    IAX_THREAD_TYPE_DYNAMIC,
00692 };

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


Function Documentation

static void __attempt_transmit void *  data  )  [static]
 

Definition at line 1863 of file chan_iax2.c.

References iax_frame::af, 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(), ast_sched_add(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.

Referenced by attempt_transmit().

01864 {
01865    /* Attempt to transmit the frame to the remote peer...
01866       Called without iaxsl held. */
01867    struct iax_frame *f = data;
01868    int freeme=0;
01869    int callno = f->callno;
01870    /* Make sure this call is still active */
01871    if (callno) 
01872       ast_mutex_lock(&iaxsl[callno]);
01873    if (callno && iaxs[callno]) {
01874       if ((f->retries < 0) /* Already ACK'd */ ||
01875           (f->retries >= max_retries) /* Too many attempts */) {
01876             /* Record an error if we've transmitted too many times */
01877             if (f->retries >= max_retries) {
01878                if (f->transfer) {
01879                   /* Transfer timeout */
01880                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
01881                } else if (f->final) {
01882                   if (f->final) 
01883                      iax2_destroy(callno);
01884                } else {
01885                   if (iaxs[callno]->owner)
01886                      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);
01887                   iaxs[callno]->error = ETIMEDOUT;
01888                   if (iaxs[callno]->owner) {
01889                      struct ast_frame fr = { 0, };
01890                      /* Hangup the fd */
01891                      fr.frametype = AST_FRAME_CONTROL;
01892                      fr.subclass = AST_CONTROL_HANGUP;
01893                      iax2_queue_frame(callno, &fr);
01894                      /* Remember, owner could disappear */
01895                      if (iaxs[callno]->owner)
01896                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01897                   } else {
01898                      if (iaxs[callno]->reg) {
01899                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
01900                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
01901                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
01902                      }
01903                      iax2_destroy(callno);
01904                   }
01905                }
01906 
01907             }
01908             freeme++;
01909       } else {
01910          /* Update it if it needs it */
01911          update_packet(f);
01912          /* Attempt transmission */
01913          send_packet(f);
01914          f->retries++;
01915          /* Try again later after 10 times as long */
01916          f->retrytime *= 10;
01917          if (f->retrytime > MAX_RETRY_TIME)
01918             f->retrytime = MAX_RETRY_TIME;
01919          /* Transfer messages max out at one second */
01920          if (f->transfer && (f->retrytime > 1000))
01921             f->retrytime = 1000;
01922          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
01923       }
01924    } else {
01925       /* Make sure it gets freed */
01926       f->retries = -1;
01927       freeme++;
01928    }
01929    if (callno)
01930       ast_mutex_unlock(&iaxsl[callno]);
01931    /* Do not try again */
01932    if (freeme) {
01933       /* Don't attempt delivery, just remove it from the queue */
01934       AST_LIST_LOCK(&queue);
01935       AST_LIST_REMOVE(&queue, f, list);
01936       AST_LIST_UNLOCK(&queue);
01937       f->retrans = -1;
01938       /* Free the IAX frame */
01939       iax2_frame_free(f);
01940    }
01941 }

static void __auth_reject void *  nothing  )  [static]
 

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

05840 {
05841    /* Called from IAX thread only, without iaxs lock */
05842    int callno = (int)(long)(nothing);
05843    struct iax_ie_data ied;
05844    ast_mutex_lock(&iaxsl[callno]);
05845    if (iaxs[callno]) {
05846       memset(&ied, 0, sizeof(ied));
05847       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05848          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05849          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05850       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05851          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05852          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05853       }
05854       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05855    }
05856    ast_mutex_unlock(&iaxsl[callno]);
05857 }

static void __auto_congest void *  nothing  )  [static]
 

Definition at line 2761 of file chan_iax2.c.

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

Referenced by auto_congest().

02762 {
02763    int callno = PTR_TO_CALLNO(nothing);
02764    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02765    ast_mutex_lock(&iaxsl[callno]);
02766    if (iaxs[callno]) {
02767       iaxs[callno]->initid = -1;
02768       iax2_queue_frame(callno, &f);
02769       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02770    }
02771    ast_mutex_unlock(&iaxsl[callno]);
02772 }

static void __auto_hangup void *  nothing  )  [static]
 

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

05892 {
05893    /* Called from IAX thread only, without iaxs lock */
05894    int callno = (int)(long)(nothing);
05895    struct iax_ie_data ied;
05896    ast_mutex_lock(&iaxsl[callno]);
05897    if (iaxs[callno]) {
05898       memset(&ied, 0, sizeof(ied));
05899       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05900       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05901       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05902    }
05903    ast_mutex_unlock(&iaxsl[callno]);
05904 }

static int __do_deliver void *  data  )  [static]
 

Definition at line 1625 of file chan_iax2.c.

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

Referenced by __get_from_jb(), and schedule_delivery().

01626 {
01627    /* Just deliver the packet by using queueing.  This is called by
01628      the IAX thread with the iaxsl lock held. */
01629    struct iax_frame *fr = data;
01630    fr->retrans = -1;
01631    fr->af.has_timing_info = 0;
01632    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01633       iax2_queue_frame(fr->callno, &fr->af);
01634    /* Free our iax frame */
01635    iax2_frame_free(fr);
01636    /* And don't run again */
01637    return 0;
01638 }

static void __expire_registry void *  data  )  [static]
 

Definition at line 5563 of file chan_iax2.c.

References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), AST_LIST_LOCK, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_set_flag, ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_DELME, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, name, option_debug, prune_peers(), realtime_update_peer(), and register_peer_exten().

Referenced by expire_registry().

05564 {
05565    char *name = data;
05566    struct iax2_peer *p = NULL;
05567 
05568    /* Go through and grab this peer... and if it needs to be removed... then do it */
05569    AST_LIST_LOCK(&peers);
05570    AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) {
05571       if (!strcasecmp(p->name, name)) {
05572          p->expire = -1;
05573          break;
05574       }
05575    }
05576    AST_LIST_TRAVERSE_SAFE_END
05577    AST_LIST_UNLOCK(&peers);
05578 
05579    /* Peer is already gone for whatever reason */
05580    if (!p)
05581       return;
05582 
05583    if (option_debug)
05584       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05585    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05586       realtime_update_peer(p->name, &p->addr, 0);
05587    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name);
05588    /* Reset the address */
05589    memset(&p->addr, 0, sizeof(p->addr));
05590    /* Reset expiry value */
05591    p->expiry = min_reg_expire;
05592    if (!ast_test_flag(p, IAX_TEMPONLY))
05593       ast_db_del("IAX/Registry", p->name);
05594    register_peer_exten(p, 0);
05595    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05596    if (iax2_regfunk)
05597       iax2_regfunk(p->name, 0);
05598 
05599    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05600       ast_set_flag(p, IAX_DELME);
05601       prune_peers();
05602    }
05603 }

static void __get_from_jb void *  p  )  [static]
 

Definition at line 2295 of file chan_iax2.c.

References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), ast_frame::data, jb_frame::data, ast_frame::datalen, 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, ast_frame::mallocd, jb_frame::ms, 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().

02296 {
02297    int callno = PTR_TO_CALLNO(p);
02298    struct chan_iax2_pvt *pvt = NULL;
02299    struct iax_frame *fr;
02300    jb_frame frame;
02301    int ret;
02302    long now;
02303    long next;
02304    struct timeval tv;
02305    
02306    /* Make sure we have a valid private structure before going on */
02307    ast_mutex_lock(&iaxsl[callno]);
02308    pvt = iaxs[callno];
02309    if (!pvt) {
02310       /* No go! */
02311       ast_mutex_unlock(&iaxsl[callno]);
02312       return;
02313    }
02314 
02315    pvt->jbid = -1;
02316    
02317    gettimeofday(&tv,NULL);
02318    /* round up a millisecond since ast_sched_runq does; */
02319    /* prevents us from spinning while waiting for our now */
02320    /* to catch up with runq's now */
02321    tv.tv_usec += 1000;
02322    
02323    now = ast_tvdiff_ms(tv, pvt->rxcore);
02324    
02325    if(now >= (next = jb_next(pvt->jb))) {
02326       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02327       switch(ret) {
02328       case JB_OK:
02329          fr = frame.data;
02330          __do_deliver(fr);
02331          break;
02332       case JB_INTERP:
02333       {
02334          struct ast_frame af;
02335          
02336          /* create an interpolation frame */
02337          af.frametype = AST_FRAME_VOICE;
02338          af.subclass = pvt->voiceformat;
02339          af.datalen  = 0;
02340          af.samples  = frame.ms * 8;
02341          af.mallocd  = 0;
02342          af.src  = "IAX2 JB interpolation";
02343          af.data  = NULL;
02344          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02345          af.offset=AST_FRIENDLY_OFFSET;
02346          
02347          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02348           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02349          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
02350             iax2_queue_frame(callno, &af);
02351       }
02352       break;
02353       case JB_DROP:
02354          iax2_frame_free(frame.data);
02355          break;
02356       case JB_NOFRAME:
02357       case JB_EMPTY:
02358          /* do nothing */
02359          break;
02360       default:
02361          /* shouldn't happen */
02362          break;
02363       }
02364    }
02365    update_jbsched(pvt);
02366    ast_mutex_unlock(&iaxsl[callno]);
02367 }

static void __iax2_do_register_s void *  data  )  [static]
 

Definition at line 5292 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_do_register_s().

05293 {
05294    struct iax2_registry *reg = data;
05295    reg->expire = -1;
05296    iax2_do_register(reg);
05297 }

static void __iax2_poke_noanswer void *  data  )  [static]
 

Definition at line 8005 of file chan_iax2.c.

References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iaxsl, iax2_peer::lastms, manager_event, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.

Referenced by iax2_poke_noanswer().

08006 {
08007    struct iax2_peer *peer = data;
08008    if (peer->lastms > -1) {
08009       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08010       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08011       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08012    }
08013    if (peer->callno > 0) {
08014       ast_mutex_lock(&iaxsl[peer->callno]);
08015       iax2_destroy(peer->callno);
08016       ast_mutex_unlock(&iaxsl[peer->callno]);
08017    }
08018    peer->callno = 0;
08019    peer->lastms = -1;
08020    /* Try again quickly */
08021    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
08022 }

static void __iax2_poke_peer_s void *  data  )  [static]
 

Definition at line 5954 of file chan_iax2.c.

References iax2_poke_peer().

Referenced by iax2_poke_peer_s().

05955 {
05956    struct iax2_peer *peer = data;
05957    iax2_poke_peer(peer, 0);
05958 }

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

Definition at line 4121 of file chan_iax2.c.

References iax2_peer::addr, ast_cli(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and s.

Referenced by iax2_show_peers(), and manager_iax2_show_peers().

04122 {
04123    regex_t regexbuf;
04124    int havepattern = 0;
04125    int total_peers = 0;
04126    int online_peers = 0;
04127    int offline_peers = 0;
04128    int unmonitored_peers = 0;
04129 
04130 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04131 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04132 
04133    struct iax2_peer *peer = NULL;
04134    char name[256];
04135    int registeredonly=0;
04136    char *term = manager ? "\r\n" : "\n";
04137 
04138    switch (argc) {
04139    case 6:
04140       if (!strcasecmp(argv[3], "registered"))
04141          registeredonly = 1;
04142       else
04143          return RESULT_SHOWUSAGE;
04144       if (!strcasecmp(argv[4], "like")) {
04145          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04146             return RESULT_SHOWUSAGE;
04147          havepattern = 1;
04148       } else
04149          return RESULT_SHOWUSAGE;
04150       break;
04151    case 5:
04152       if (!strcasecmp(argv[3], "like")) {
04153          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04154             return RESULT_SHOWUSAGE;
04155          havepattern = 1;
04156       } else
04157          return RESULT_SHOWUSAGE;
04158       break;
04159    case 4:
04160       if (!strcasecmp(argv[3], "registered"))
04161          registeredonly = 1;
04162       else
04163          return RESULT_SHOWUSAGE;
04164       break;
04165    case 3:
04166       break;
04167    default:
04168       return RESULT_SHOWUSAGE;
04169    }
04170 
04171 
04172    if (s)
04173       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04174    else
04175       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04176 
04177    AST_LIST_LOCK(&peers);
04178    AST_LIST_TRAVERSE(&peers, peer, entry) {
04179       char nm[20];
04180       char status[20];
04181       char srch[2000];
04182       int retstatus;
04183 
04184       if (registeredonly && !peer->addr.sin_addr.s_addr)
04185          continue;
04186       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04187          continue;
04188 
04189       if (!ast_strlen_zero(peer->username))
04190          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04191       else
04192          ast_copy_string(name, peer->name, sizeof(name));
04193       
04194       retstatus = peer_status(peer, status, sizeof(status));
04195       if (retstatus > 0)
04196          online_peers++;
04197       else if (!retstatus)
04198          offline_peers++;
04199       else
04200          unmonitored_peers++;
04201       
04202       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04203       
04204       snprintf(srch, sizeof(srch), FORMAT, name, 
04205           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04206           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04207           nm,
04208           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04209           peer->encmethods ? "(E)" : "   ", status, term);
04210       
04211       if (s)
04212          astman_append(s, FORMAT, name, 
04213                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04214                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04215                   nm,
04216                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04217                   peer->encmethods ? "(E)" : "   ", status, term);
04218       else
04219          ast_cli(fd, FORMAT, name, 
04220             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04221             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04222             nm,
04223             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04224             peer->encmethods ? "(E)" : "   ", status, term);
04225       total_peers++;
04226    }
04227    AST_LIST_UNLOCK(&peers);
04228 
04229    if (s)
04230       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04231    else
04232       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04233 
04234    if (havepattern)
04235       regfree(&regexbuf);
04236 
04237    return RESULT_SUCCESS;
04238 #undef FORMAT
04239 #undef FORMAT2
04240 }

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

Definition at line 936 of file chan_iax2.c.

References ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_NOTICE, signal_condition(), and thread.

00937 {
00938    struct iax2_thread *thread = NULL;
00939    static time_t lasterror;
00940    static time_t t;
00941 
00942    thread = find_idle_thread();
00943 
00944    if (thread != NULL) {
00945       thread->schedfunc = func;
00946       thread->scheddata = data;
00947       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00948 #ifdef DEBUG_SCHED_MULTITHREAD
00949       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00950 #endif
00951       signal_condition(&thread->lock, &thread->cond);
00952       return 0;
00953    }
00954    time(&t);
00955    if (t != lasterror) 
00956       ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n");
00957    lasterror = t;
00958 
00959    return -1;
00960 }

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

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

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

04617 {
04618    struct ast_frame f;
04619    f.frametype = type;
04620    f.subclass = command;
04621    f.datalen = datalen;
04622    f.samples = 0;
04623    f.mallocd = 0;
04624    f.offset = 0;
04625    f.src = (char *)__FUNCTION__;
04626    f.data = (char *)data;
04627    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04628 }

static void __send_lagrq void *  data  )  [static]
 

Definition at line 1000 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().

Referenced by send_lagrq().

01001 {
01002    int callno = (long)data;
01003    /* Ping only if it's real not if it's bridged */
01004    ast_mutex_lock(&iaxsl[callno]);
01005    if (iaxs[callno] && iaxs[callno]->lagid != -1) {
01006       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01007       iaxs[callno]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01008    }
01009    ast_mutex_unlock(&iaxsl[callno]);
01010 }

static void __send_ping void *  data  )  [static]
 

Definition at line 966 of file chan_iax2.c.

References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().

Referenced by send_ping().

00967 {
00968    int callno = (long)data;
00969    ast_mutex_lock(&iaxsl[callno]);
00970    if (iaxs[callno] && iaxs[callno]->pingid != -1) {
00971       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00972       iaxs[callno]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, data);
00973    }
00974    ast_mutex_unlock(&iaxsl[callno]);
00975 }

static int __unload_module void   )  [static]
 

Definition at line 10013 of file chan_iax2.c.

References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), 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_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, IAX_MAX_CALLS, iax_provision_unload(), iaxs, netsock, papp, sched, sched_context_destroy(), signal_condition(), thread, and thread_free().

Referenced by load_module(), and unload_module().

10014 {
10015    pthread_t threadid = AST_PTHREADT_NULL;
10016    struct iax2_thread *thread = NULL;
10017    int x;
10018 
10019    /* Cancel the network thread, close the net socket */
10020    if (netthreadid != AST_PTHREADT_NULL) {
10021       pthread_cancel(netthreadid);
10022       pthread_join(netthreadid, NULL);
10023    }
10024    if (schedthreadid != AST_PTHREADT_NULL) {
10025       pthread_cancel(schedthreadid);
10026       ast_mutex_lock(&sched_lock);
10027       ast_cond_signal(&sched_cond);
10028       ast_mutex_unlock(&sched_lock);
10029       pthread_join(schedthreadid, NULL);
10030    }
10031 
10032    /* Call for all threads to halt */
10033    AST_LIST_LOCK(&idle_list);
10034    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10035       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10036       threadid = thread->threadid;
10037       pthread_cancel(threadid);
10038       signal_condition(&thread->lock, &thread->cond);
10039       pthread_join(threadid, NULL);
10040       thread_free(thread);
10041    }
10042    AST_LIST_TRAVERSE_SAFE_END
10043    AST_LIST_UNLOCK(&idle_list);
10044 
10045    AST_LIST_LOCK(&active_list);
10046    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10047       AST_LIST_REMOVE_CURRENT(&active_list, list);
10048       threadid = thread->threadid;
10049       pthread_cancel(threadid);
10050       signal_condition(&thread->lock, &thread->cond);
10051       pthread_join(threadid, NULL);
10052       thread_free(thread);
10053    }
10054    AST_LIST_TRAVERSE_SAFE_END
10055    AST_LIST_UNLOCK(&active_list);
10056 
10057    AST_LIST_LOCK(&dynamic_list);
10058    AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10059       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10060       threadid = thread->threadid;
10061       pthread_cancel(threadid);
10062       signal_condition(&thread->lock, &thread->cond);
10063       pthread_join(threadid, NULL);
10064       thread_free(thread);
10065    }
10066    AST_LIST_TRAVERSE_SAFE_END
10067    AST_LIST_UNLOCK(&dynamic_list);
10068 
10069    ast_netsock_release(netsock);
10070    for (x=0;x<IAX_MAX_CALLS;x++)
10071       if (iaxs[x])
10072          iax2_destroy(x);
10073    ast_manager_unregister( "IAXpeers" );
10074    ast_manager_unregister( "IAXnetstats" );
10075    ast_unregister_application(papp);
10076    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10077    ast_unregister_switch(&iax2_switch);
10078    ast_channel_unregister(&iax2_tech);
10079    delete_users();
10080    iax_provision_unload();
10081    sched_context_destroy(sched);
10082    return 0;
10083 }

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

Definition at line 6462 of file chan_iax2.c.

References pbx_builtin_getvar_helper().

06463 {
06464    const char *value;
06465    char tmp[256];
06466    snprintf(tmp, sizeof(tmp), "~IAX2~%s", data);
06467    value = pbx_builtin_getvar_helper(chan, tmp);
06468    ast_copy_string(buf, value ? value : "", len);
06469    return 0;
06470 }

static int acf_iaxvar_write struct ast_channel chan,
const char *  cmd,
char *  varname,
const char *  value
[static]
 

Definition at line 6472 of file chan_iax2.c.

References pbx_builtin_setvar_helper().

06473 {
06474    char tmp[256];
06475    /* Inherit forever */
06476    snprintf(tmp, sizeof(tmp), "__~IAX2~%s", varname);
06477    pbx_builtin_setvar_helper(chan, tmp, value);
06478    return 0;
06479 }

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

Definition at line 4661 of file chan_iax2.c.

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

Referenced by check_access().

04662 {
04663    while(con) {
04664       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04665          return -1;
04666       con = con->next;
04667    }
04668    return 0;
04669 }

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

Definition at line 4443 of file chan_iax2.c.

References ast_mutex_lock(), ast_test_flag, jb_info::current, fmt, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.

Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().

04444 {
04445    int x;
04446    int numchans = 0;
04447    for (x=0;x<IAX_MAX_CALLS;x++) {
04448       ast_mutex_lock(&iaxsl[x]);
04449       if (iaxs[x]) {
04450          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04451          char *fmt;
04452          jb_info jbinfo;
04453          
04454          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04455             jb_getinfo(iaxs[x]->jb, &jbinfo);
04456             localjitter = jbinfo.jitter;
04457             localdelay = jbinfo.current - jbinfo.min;
04458             locallost = jbinfo.frames_lost;
04459             locallosspct = jbinfo.losspct/1000;
04460             localdropped = jbinfo.frames_dropped;
04461             localooo = jbinfo.frames_ooo;
04462          } else {
04463             localjitter = -1;
04464             localdelay = 0;
04465             locallost = -1;
04466             locallosspct = -1;
04467             localdropped = 0;
04468             localooo = -1;
04469          }
04470          if (limit_fmt)
04471             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04472          else
04473             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04474          if (s)
04475             
04476             astman_append(s, fmt,
04477                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04478                      iaxs[x]->pingtime,
04479                      localjitter, 
04480                      localdelay,
04481                      locallost,
04482                      locallosspct,
04483                      localdropped,
04484                      localooo,
04485                      iaxs[x]->frames_received/1000,
04486                      iaxs[x]->remote_rr.jitter,
04487                      iaxs[x]->remote_rr.delay,
04488                      iaxs[x]->remote_rr.losscnt,
04489                      iaxs[x]->remote_rr.losspct,
04490                      iaxs[x]->remote_rr.dropped,
04491                      iaxs[x]->remote_rr.ooo,
04492                      iaxs[x]->remote_rr.packets/1000);
04493          else
04494             ast_cli(fd, fmt,
04495                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04496                iaxs[x]->pingtime,
04497                localjitter, 
04498                localdelay,
04499                locallost,
04500                locallosspct,
04501                localdropped,
04502                localooo,
04503                iaxs[x]->frames_received/1000,
04504                iaxs[x]->remote_rr.jitter,
04505                iaxs[x]->remote_rr.delay,
04506                iaxs[x]->remote_rr.losscnt,
04507                iaxs[x]->remote_rr.losspct,
04508                iaxs[x]->remote_rr.dropped,
04509                iaxs[x]->remote_rr.ooo,
04510                iaxs[x]->remote_rr.packets/1000
04511                );
04512          numchans++;
04513       }
04514       ast_mutex_unlock(&iaxsl[x]);
04515    }
04516    return numchans;
04517 }

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

References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), 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, 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, ast_channel::exten, iax2_tech, iaxs, iaxsl, 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::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_process().

03344 {
03345    struct ast_channel *tmp;
03346    struct chan_iax2_pvt *i;
03347    struct ast_variable *v = NULL;
03348 
03349    if (!(i = iaxs[callno])) {
03350       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03351       return NULL;
03352    }
03353 
03354    /* Don't hold call lock */
03355    ast_mutex_unlock(&iaxsl[callno]);
03356    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "IAX2/%s-%d", i->host, i->callno);
03357    ast_mutex_lock(&iaxsl[callno]);
03358    if (!tmp)
03359       return NULL;
03360    tmp->tech = &iax2_tech;
03361    /* We can support any format by default, until we get restricted */
03362    tmp->nativeformats = capability;
03363    tmp->readformat = ast_best_codec(capability);
03364    tmp->writeformat = ast_best_codec(capability);
03365    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03366 
03367    /* Don't use ast_set_callerid() here because it will
03368     * generate a NewCallerID event before the NewChannel event */
03369    tmp->cid.cid_num = ast_strdup(i->cid_num);
03370    tmp->cid.cid_name = ast_strdup(i->cid_name);
03371    if (!ast_strlen_zero(i->ani))
03372       tmp->cid.cid_ani = ast_strdup(i->ani);
03373    else
03374       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03375    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03376    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03377    tmp->cid.cid_pres = i->calling_pres;
03378    tmp->cid.cid_ton = i->calling_ton;
03379    tmp->cid.cid_tns = i->calling_tns;
03380    if (!ast_strlen_zero(i->language))
03381       ast_string_field_set(tmp, language, i->language);
03382    if (!ast_strlen_zero(i->accountcode))
03383       ast_string_field_set(tmp, accountcode, i->accountcode);
03384    if (i->amaflags)
03385       tmp->amaflags = i->amaflags;
03386    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03387    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03388    if (i->adsi)
03389       tmp->adsicpe = i->peeradsicpe;
03390    else
03391       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03392    i->owner = tmp;
03393    i->capability = capability;
03394    if (state != AST_STATE_DOWN) {
03395       if (ast_pbx_start(tmp)) {
03396          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03397          ast_hangup(tmp);
03398          i->owner = NULL;
03399          return NULL;
03400       }
03401    }
03402 
03403    for (v = i->vars ; v ; v = v->next)
03404       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03405 
03406    ast_module_ref(ast_module_info->self);
03407    return tmp;
03408 }

static AST_LIST_HEAD_STATIC dynamic_list  ,
iax2_thread 
[static]
 

static AST_LIST_HEAD_STATIC active_list  ,
iax2_thread 
[static]
 

static AST_LIST_HEAD_STATIC idle_list  ,
iax2_thread 
[static]
 

static AST_LIST_HEAD_STATIC dpcache  ,
iax2_dpcache 
[static]
 

static AST_LIST_HEAD_STATIC firmwares  ,
iax_firmware 
[static]
 

static AST_LIST_HEAD_STATIC peers  ,
iax2_peer 
[static]
 

static AST_LIST_HEAD_STATIC users  ,
iax2_user 
[static]
 

static AST_LIST_HEAD_STATIC queue  ,
iax_frame 
[static]
 

static AST_LIST_HEAD_STATIC registrations  ,
iax2_registry 
[static]
 

static AST_LIST_HEAD_STATIC tpeers  ,
iax2_trunk_peer 
[static]
 

AST_MODULE_INFO ASTERISK_GPL_KEY  ,
AST_MODFLAG_DEFAULT  ,
"Inter Asterisk eXchange (Ver 2)"  ,
load = load_module,
unload = unload_module,
reload = reload
 

AST_MUTEX_DEFINE_STATIC sched_lock   ) 
 

static int attempt_transmit void *  data  )  [static]
 

Definition at line 1943 of file chan_iax2.c.

References __attempt_transmit(), and schedule_action.

Referenced by __attempt_transmit(), and network_thread().

01944 {
01945 #ifdef SCHED_MULTITHREADED
01946    if (schedule_action(__attempt_transmit, data))
01947 #endif      
01948       __attempt_transmit(data);
01949    return 0;
01950 }

static int auth_fail int  callno,
int  failcode
[static]
 

Definition at line 5873 of file chan_iax2.c.

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

Referenced by socket_process().

05874 {
05875    /* Schedule sending the authentication failure in one second, to prevent
05876       guessing */
05877    ast_mutex_lock(&iaxsl[callno]);
05878    if (iaxs[callno]) {
05879       iaxs[callno]->authfail = failcode;
05880       if (delayreject) {
05881          if (iaxs[callno]->authid > -1)
05882             ast_sched_del(sched, iaxs[callno]->authid);
05883          iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05884       } else
05885          auth_reject((void *)(long)callno);
05886    }
05887    ast_mutex_unlock(&iaxsl[callno]);
05888    return 0;
05889 }

static int auth_reject void *  data  )  [static]
 

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

05860 {
05861    int callno = (int)(long)(data);
05862    ast_mutex_lock(&iaxsl[callno]);
05863    if (iaxs[callno])
05864       iaxs[callno]->authid = -1;
05865    ast_mutex_unlock(&iaxsl[callno]);
05866 #ifdef SCHED_MULTITHREADED
05867    if (schedule_action(__auth_reject, data))
05868 #endif      
05869       __auth_reject(data);
05870    return 0;
05871 }

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

Definition at line 5179 of file chan_iax2.c.

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

05180 {
05181    int res = -1;
05182    int x;
05183    if (!ast_strlen_zero(keyn)) {
05184       if (!(authmethods & IAX_AUTH_RSA)) {
05185          if (ast_strlen_zero(secret)) 
05186             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));
05187       } else if (ast_strlen_zero(challenge)) {
05188          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05189       } else {
05190          char sig[256];
05191          struct ast_key *key;
05192          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05193          if (!key) {
05194             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05195          } else {
05196             if (ast_sign(key, (char*)challenge, sig)) {
05197                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05198                res = -1;
05199             } else {
05200                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05201                res = 0;
05202             }
05203          }
05204       }
05205    } 
05206    /* Fall back */
05207    if (res && !ast_strlen_zero(secret)) {
05208       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05209          struct MD5Context md5;
05210          unsigned char digest[16];
05211          char digres[128];
05212          MD5Init(&md5);
05213          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05214          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05215          MD5Final(digest, &md5);
05216          /* If they support md5, authenticate with it.  */
05217          for (x=0;x<16;x++)
05218             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05219          if (ecx && dcx)
05220             build_enc_keys(digest, ecx, dcx);
05221          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05222          res = 0;
05223       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05224          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05225          res = 0;
05226       } else
05227          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05228    }
05229    return res;
05230 }

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

Definition at line 5232 of file chan_iax2.c.

References iax2_peer::addr, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, authenticate(), destroy_peer(), IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, IAX_TEMPONLY, ies, iax2_peer::mask, merge_encryption(), realtime_peer(), and send_command().

Referenced by socket_process().

05233 {
05234    struct iax2_peer *peer = NULL;
05235    /* Start pessimistic */
05236    int res = -1;
05237    int authmethods = 0;
05238    struct iax_ie_data ied;
05239    
05240    memset(&ied, 0, sizeof(ied));
05241    
05242    if (ies->username)
05243       ast_string_field_set(p, username, ies->username);
05244    if (ies->challenge)
05245       ast_string_field_set(p, challenge, ies->challenge);
05246    if (ies->authmethods)
05247       authmethods = ies->authmethods;
05248    if (authmethods & IAX_AUTH_MD5)
05249       merge_encryption(p, ies->encmethods);
05250    else
05251       p->encmethods = 0;
05252 
05253    /* Check for override RSA authentication first */
05254    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05255       /* Normal password authentication */
05256       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05257    } else {
05258       AST_LIST_LOCK(&peers);
05259       AST_LIST_TRAVERSE(&peers, peer, entry) {
05260          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05261              /* No peer specified at our end, or this is the peer */
05262              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05263              /* No username specified in peer rule, or this is the right username */
05264              && (!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)))
05265              /* No specified host, or this is our host */
05266             ) {
05267             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05268             if (!res)
05269                break;   
05270          }
05271       }
05272       AST_LIST_UNLOCK(&peers);
05273       if (!peer) {
05274          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05275             that we're trying to authenticate *to* a realtime peer */
05276          if ((peer = realtime_peer(p->peer, NULL))) {
05277             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05278             if (ast_test_flag(peer, IAX_TEMPONLY))
05279                destroy_peer(peer);
05280          }
05281       }
05282    }
05283    if (ies->encmethods)
05284       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05285    if (!res)
05286       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05287    return res;
05288 }

static int authenticate_request struct chan_iax2_pvt p  )  [static]
 

Definition at line 4906 of file chan_iax2.c.

References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, 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, iax2_user::maxauthreq, send_command(), and send_command_final().

Referenced by socket_process().

04907 {
04908    struct iax2_user *user = NULL;
04909    struct iax_ie_data ied;
04910    int res = -1, authreq_restrict = 0;
04911    char challenge[10];
04912 
04913    memset(&ied, 0, sizeof(ied));
04914 
04915    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
04916    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04917       AST_LIST_LOCK(&users);
04918       AST_LIST_TRAVERSE(&users, user, entry) {
04919          if (!strcmp(user->name, p->username)) {
04920             if (user->curauthreq == user->maxauthreq)
04921                authreq_restrict = 1;
04922             else
04923                user->curauthreq++;
04924             break;
04925          }
04926       }
04927       AST_LIST_UNLOCK(&users);
04928    }
04929 
04930    /* If the AUTHREQ limit test failed, send back an error */
04931    if (authreq_restrict) {
04932       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
04933       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
04934       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
04935       return 0;
04936    }
04937 
04938    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
04939    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
04940       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
04941       ast_string_field_set(p, challenge, challenge);
04942       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
04943       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
04944    }
04945    if (p->encmethods)
04946       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
04947 
04948    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
04949 
04950    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
04951 
04952    if (p->encmethods)
04953       ast_set_flag(p, IAX_ENCRYPTED);
04954 
04955    return res;
04956 }

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

Definition at line 4958 of file chan_iax2.c.

References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, key(), LOG_WARNING, MD5Final(), MD5Init(), MD5Update(), chan_iax2_pvt::state, and strsep().

Referenced by socket_process().

04959 {
04960    char requeststr[256];
04961    char md5secret[256] = "";
04962    char secret[256] = "";
04963    char rsasecret[256] = "";
04964    int res = -1; 
04965    int x;
04966    struct iax2_user *user = NULL;
04967 
04968    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04969       AST_LIST_LOCK(&users);
04970       AST_LIST_TRAVERSE(&users, user, entry) {
04971          if (!strcmp(user->name, p->username)) {
04972             user->curauthreq--;
04973             break;
04974          }
04975       }
04976       AST_LIST_UNLOCK(&users);
04977       ast_clear_flag(p, IAX_MAXAUTHREQ);
04978    }
04979 
04980    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
04981       return res;
04982    if (ies->password)
04983       ast_copy_string(secret, ies->password, sizeof(secret));
04984    if (ies->md5_result)
04985       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
04986    if (ies->rsa_result)
04987       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
04988    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
04989       struct ast_key *key;
04990       char *keyn;
04991       char tmpkey[256];
04992       char *stringp=NULL;
04993       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
04994       stringp=tmpkey;
04995       keyn = strsep(&stringp, ":");
04996       while(keyn) {
04997          key = ast_key_get(keyn, AST_KEY_PUBLIC);
04998          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
04999             res = 0;
05000             break;
05001          } else if (!key)
05002             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05003          keyn = strsep(&stringp, ":");
05004       }
05005    } else if (p->authmethods & IAX_AUTH_MD5) {
05006       struct MD5Context md5;
05007       unsigned char digest[16];
05008       char *tmppw, *stringp;
05009       
05010       tmppw = ast_strdupa(p->secret);
05011       stringp = tmppw;
05012       while((tmppw = strsep(&stringp, ";"))) {
05013          MD5Init(&md5);
05014          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05015          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05016          MD5Final(digest, &md5);
05017          /* If they support md5, authenticate with it.  */
05018          for (x=0;x<16;x++)
05019             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05020          if (!strcasecmp(requeststr, md5secret)) {
05021             res = 0;
05022             break;
05023          }
05024       }
05025    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05026       if (!strcmp(secret, p->secret))
05027          res = 0;
05028    }
05029    return res;
05030 }

static int auto_congest void *  data  )  [static]
 

Definition at line 2774 of file chan_iax2.c.

References __auto_congest(), and schedule_action.

Referenced by iax2_call(), and sip_call().

02775 {
02776 #ifdef SCHED_MULTITHREADED
02777    if (schedule_action(__auto_congest, data))
02778 #endif      
02779       __auto_congest(data);
02780    return 0;
02781 }

static int auto_hangup void *  data  )  [static]
 

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

05907 {
05908    int callno = (int)(long)(data);
05909    ast_mutex_lock(&iaxsl[callno]);
05910    if (iaxs[callno]) {
05911       iaxs[callno]->autoid = -1;
05912    }
05913    ast_mutex_unlock(&iaxsl[callno]);
05914 #ifdef SCHED_MULTITHREADED
05915    if (schedule_action(__auto_hangup, data))
05916 #endif      
05917       __auto_hangup(data);
05918    return 0;
05919 }

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

Definition at line 8292 of file chan_iax2.c.

References ast_calloc.

Referenced by build_user().

08293 {
08294    struct iax2_context *con;
08295 
08296    if ((con = ast_calloc(1, sizeof(*con))))
08297       ast_copy_string(con->context, context, sizeof(con->context));
08298    
08299    return con;
08300 }

static void build_enc_keys const unsigned char *  digest,
aes_encrypt_ctx ecx,
aes_decrypt_ctx dcx
[static]
 

Definition at line 3720 of file chan_iax2.c.

References aes_decrypt_key128(), and aes_encrypt_key128().

Referenced by authenticate(), and decrypt_frame().

03721 {
03722    aes_encrypt_key128(digest, ecx);
03723    aes_decrypt_key128(digest, dcx);
03724 }

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

References iax2_peer::addr, iax2_peer::adsi, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_free_pools, ast_string_field_init, ast_string_field_set, ast_test_flag, ast_true(), iax2_peer::authmethods, iax2_peer::capability, cid_name, cid_num, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, free, 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, ast_variable::lineno, LOG_WARNING, mailbox, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, ast_variable::next, peer_set_srcaddr(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, prefs, sched, iax2_peer::smoothing, and ast_variable::value.

08400 {
08401    struct iax2_peer *peer = NULL;
08402    struct ast_ha *oldha = NULL;
08403    int maskfound=0;
08404    int found=0;
08405    int firstpass=1;
08406 
08407    AST_LIST_LOCK(&peers);
08408    if (!temponly) {
08409       AST_LIST_TRAVERSE(&peers, peer, entry) {
08410          if (!strcmp(peer->name, name)) { 
08411             if (!ast_test_flag(peer, IAX_DELME))
08412                firstpass = 0;
08413             break;
08414          }
08415       }
08416    } else
08417       peer = NULL;   
08418    if (peer) {
08419       found++;
08420       if (firstpass) {
08421          oldha = peer->ha;
08422          peer->ha = NULL;
08423       }
08424       AST_LIST_REMOVE(&peers, peer, entry);
08425       AST_LIST_UNLOCK(&peers);
08426    } else {
08427       AST_LIST_UNLOCK(&peers);
08428       if ((peer = ast_calloc(1, sizeof(*peer)))) {
08429          peer->expire = -1;
08430          peer->pokeexpire = -1;
08431          peer->sockfd = defaultsockfd;
08432          if (ast_string_field_init(peer, 32)) {
08433             free(peer);
08434             peer = NULL;
08435          }
08436       }
08437    }
08438    if (peer) {
08439       if (firstpass) {
08440          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08441          peer->encmethods = iax2_encryption;
08442          peer->adsi = adsi;
08443          ast_string_field_set(peer,secret,"");
08444          if (!found) {
08445             ast_string_field_set(peer, name, name);
08446             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08447             peer->expiry = min_reg_expire;
08448          }
08449          peer->prefs = prefs;
08450          peer->capability = iax2_capability;
08451          peer->smoothing = 0;
08452          peer->pokefreqok = DEFAULT_FREQ_OK;
08453          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08454          ast_string_field_set(peer,context,"");
08455          ast_string_field_set(peer,peercontext,"");
08456       }
08457 
08458       if (!v) {
08459          v = alt;
08460          alt = NULL;
08461       }
08462       while(v) {
08463          if (!strcasecmp(v->name, "secret")) {
08464             ast_string_field_set(peer, secret, v->value);
08465          } else if (!strcasecmp(v->name, "mailbox")) {
08466             ast_string_field_set(peer, mailbox, v->value);
08467          } else if (!strcasecmp(v->name, "mohinterpret")) {
08468             ast_string_field_set(peer, mohinterpret, v->value);
08469          } else if (!strcasecmp(v->name, "mohsuggest")) {
08470             ast_string_field_set(peer, mohsuggest, v->value);
08471          } else if (!strcasecmp(v->name, "dbsecret")) {
08472             ast_string_field_set(peer, dbsecret, v->value);
08473          } else if (!strcasecmp(v->name, "trunk")) {
08474             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08475             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08476                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08477                ast_clear_flag(peer, IAX_TRUNK);
08478             }
08479          } else if (!strcasecmp(v->name, "auth")) {
08480             peer->authmethods = get_auth_methods(v->value);
08481          } else if (!strcasecmp(v->name, "encryption")) {
08482             peer->encmethods = get_encrypt_methods(v->value);
08483          } else if (!strcasecmp(v->name, "transfer")) {
08484             if (!strcasecmp(v->value, "mediaonly")) {
08485                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
08486             } else if (ast_true(v->value)) {
08487                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08488             } else 
08489                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08490          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08491             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08492          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08493             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08494          } else if (!strcasecmp(v->name, "host")) {
08495             if (!strcasecmp(v->value, "dynamic")) {
08496                /* They'll register with us */
08497                ast_set_flag(peer, IAX_DYNAMIC); 
08498                if (!found) {
08499                   /* Initialize stuff iff we're not found, otherwise
08500                      we keep going with what we had */
08501                   memset(&peer->addr.sin_addr, 0, 4);
08502                   if (peer->addr.sin_port) {
08503                      /* If we've already got a port, make it the default rather than absolute */
08504                      peer->defaddr.sin_port = peer->addr.sin_port;
08505                      peer->addr.sin_port = 0;
08506                   }
08507                }
08508             } else {
08509                /* Non-dynamic.  Make sure we become that way if we're not */
08510                if (peer->expire > -1)
08511                   ast_sched_del(sched, peer->expire);
08512                peer->expire = -1;
08513                ast_clear_flag(peer, IAX_DYNAMIC);
08514                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08515                   ast_string_field_free_pools(peer);
08516                   free(peer);
08517                   return NULL;
08518                }
08519                if (!peer->addr.sin_port)
08520                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08521             }
08522             if (!maskfound)
08523                inet_aton("255.255.255.255", &peer->mask);
08524          } else if (!strcasecmp(v->name, "defaultip")) {
08525             if (ast_get_ip(&peer->defaddr, v->value)) {
08526                ast_string_field_free_pools(peer);
08527                free(peer);
08528                return NULL;
08529             }
08530          } else if (!strcasecmp(v->name, "sourceaddress")) {
08531             peer_set_srcaddr(peer, v->value);
08532          } else if (!strcasecmp(v->name, "permit") ||
08533                   !strcasecmp(v->name, "deny")) {
08534             peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
08535          } else if (!strcasecmp(v->name, "mask")) {
08536             maskfound++;
08537             inet_aton(v->value, &peer->mask);
08538          } else if (!strcasecmp(v->name, "context")) {
08539             ast_string_field_set(peer, context, v->value);
08540          } else if (!strcasecmp(v->name, "regexten")) {
08541             ast_string_field_set(peer, regexten, v->value);
08542          } else if (!strcasecmp(v->name, "peercontext")) {
08543             ast_string_field_set(peer, peercontext, v->value);
08544          } else if (!strcasecmp(v->name, "port")) {
08545             if (ast_test_flag(peer, IAX_DYNAMIC))
08546                peer->defaddr.sin_port = htons(atoi(v->value));
08547             else
08548                peer->addr.sin_port = htons(atoi(v->value));
08549          } else if (!strcasecmp(v->name, "username")) {
08550             ast_string_field_set(peer, username, v->value);
08551          } else if (!strcasecmp(v->name, "allow")) {
08552             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08553          } else if (!strcasecmp(v->name, "disallow")) {
08554             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08555          } else if (!strcasecmp(v->name, "callerid")) {
08556             char name2[80];
08557             char num2[80];
08558             ast_callerid_split(v->value, name2, 80, num2, 80);
08559             ast_string_field_set(peer, cid_name, name2);
08560             ast_string_field_set(peer, cid_num, num2);
08561             ast_set_flag(peer, IAX_HASCALLERID);   
08562          } else if (!strcasecmp(v->name, "fullname")) {
08563             ast_string_field_set(peer, cid_name, v->value);
08564             ast_set_flag(peer, IAX_HASCALLERID);   
08565          } else if (!strcasecmp(v->name, "cid_number")) {
08566             ast_string_field_set(peer, cid_num, v->value);
08567             ast_set_flag(peer, IAX_HASCALLERID);   
08568          } else if (!strcasecmp(v->name, "sendani")) {
08569             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08570          } else if (!strcasecmp(v->name, "inkeys")) {
08571             ast_string_field_set(peer, inkeys, v->value);
08572          } else if (!strcasecmp(v->name, "outkey")) {
08573             ast_string_field_set(peer, outkey, v->value);
08574          } else if (!strcasecmp(v->name, "qualify")) {
08575             if (!strcasecmp(v->value, "no")) {
08576                peer->maxms = 0;
08577             } else if (!strcasecmp(v->value, "yes")) {
08578                peer->maxms = DEFAULT_MAXMS;
08579             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08580                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);
08581                peer->maxms = 0;
08582             }
08583          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08584             peer->smoothing = ast_true(v->value);
08585          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08586             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08587                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);
08588             }
08589          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08590             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08591                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);
08592             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08593          } else if (!strcasecmp(v->name, "timezone")) {
08594             ast_string_field_set(peer, zonetag, v->value);
08595          } else if (!strcasecmp(v->name, "adsi")) {
08596             peer->adsi = ast_true(v->value);
08597          }/* else if (strcasecmp(v->name,"type")) */
08598          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08599          v = v->next;
08600          if (!v) {
08601             v = alt;
08602             alt = NULL;
08603          }
08604       }
08605       if (!peer->authmethods)
08606          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08607       ast_clear_flag(peer, IAX_DELME); 
08608       /* Make sure these are IPv4 addresses */
08609       peer->addr.sin_family = AF_INET;
08610    }
08611    if (oldha)
08612       ast_free_ha(oldha);
08613    return peer;
08614 }

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

References iax2_user::adsi, iax2_user::amaflags, ast_append_ha(), ast_callerid_split(), ast_calloc, ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, 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_pools, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, cid_name, cid_num, iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free, 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, ast_variable::lineno, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_user::prefs, prefs, ast_variable::value, and iax2_user::vars.

08618 {
08619    struct iax2_user *user = NULL;
08620    struct iax2_context *con, *conl = NULL;
08621    struct ast_ha *oldha = NULL;
08622    struct iax2_context *oldcon = NULL;
08623    int format;
08624    int firstpass=1;
08625    int oldcurauthreq = 0;
08626    char *varname = NULL, *varval = NULL;
08627    struct ast_variable *tmpvar = NULL;
08628    
08629    AST_LIST_LOCK(&users);
08630    if (!temponly) {
08631       AST_LIST_TRAVERSE(&users, user, entry) {
08632          if (!strcmp(user->name, name)) { 
08633             if (!ast_test_flag(user, IAX_DELME))
08634                firstpass = 0;
08635             break;
08636          }
08637       }
08638    } else
08639       user = NULL;
08640 
08641    if (user) {
08642       if (firstpass) {
08643          oldcurauthreq = user->curauthreq;
08644          oldha = user->ha;
08645          oldcon = user->contexts;
08646          user->ha = NULL;
08647          user->contexts = NULL;
08648       }
08649       /* Already in the list, remove it and it will be added back (or FREE'd) */
08650       AST_LIST_REMOVE(&users, user, entry);
08651       AST_LIST_UNLOCK(&users);
08652    } else {
08653       AST_LIST_UNLOCK(&users);
08654       /* This is going to memset'd to 0 in the next block */
08655       user = ast_calloc(sizeof(*user),1);
08656    }
08657    
08658    if (user) {
08659       if (firstpass) {
08660          ast_string_field_free_pools(user);
08661          memset(user, 0, sizeof(struct iax2_user));
08662          if (ast_string_field_init(user, 32)) {
08663             free(user);
08664             user = NULL;
08665          }
08666          user->maxauthreq = maxauthreq;
08667          user->curauthreq = oldcurauthreq;
08668          user->prefs = prefs;
08669          user->capability = iax2_capability;
08670          user->encmethods = iax2_encryption;
08671          user->adsi = adsi;
08672          ast_string_field_set(user, name, name);
08673          ast_string_field_set(user, language, language);
08674          ast_copy_flags(user, &globalflags,