Sat Nov 25 00:45:51 2006

Asterisk developer's documentation


chan_iax2.c File Reference

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

#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "../jitterbuf.h"

Go to the source code of this file.

Data Structures

struct  ast_firmware_list
struct  ast_iax2_queue
struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_user_list
 The user list: Users and friends ---. More...
struct  chan_iax2_pvt
struct  create_addr_info
struct  dpreq_data
struct  iax2_context
struct  iax2_dpcache
struct  iax2_peer
struct  iax2_registry
struct  iax2_trunk_peer
struct  iax2_user
struct  iax_dual
struct  iax_firmware
struct  iax_rr
struct  parsed_dial_string

Defines

#define CACHE_FLAG_CANEXIST   (1 << 2)
#define CACHE_FLAG_EXISTS   (1 << 0)
#define CACHE_FLAG_MATCHMORE   (1 << 7)
#define CACHE_FLAG_NONEXISTENT   (1 << 1)
#define CACHE_FLAG_PENDING   (1 << 3)
#define CACHE_FLAG_TIMEOUT   (1 << 4)
#define CACHE_FLAG_TRANSMITTED   (1 << 5)
#define CACHE_FLAG_UNKNOWN   (1 << 6)
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define DEBUG_SUPPORT
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_TRUNKDATA   640 * 10
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
#define FORMAT   "%-20.20s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15d %-15d\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
#define FORMAT2   "%-20.20s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %-15.15s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define FREE   free
#define GAMMA   (0.01)
#define IAX2_TRUNK_PREFACE   (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
#define IAX_CAPABILITY_LOWBANDWIDTH
#define IAX_CAPABILITY_LOWFREE
#define IAX_CAPABILITY_MEDBANDWIDTH
#define IPTOS_MINCOST   0x02
#define MAX_JITTER_BUFFER   50
#define MAX_RETRY_TIME   10000
#define MAX_TIMESTAMP_SKEW   160
#define MAX_TRUNKDATA   640 * 200
#define MEMORY_SIZE   100
#define MIN_JITTER_BUFFER   10
#define MIN_RETRY_TIME   100
#define MIN_REUSE_TIME   60
#define NEW_ALLOW   1
#define NEW_FORCE   2
#define NEW_PREVENT   0
#define NEWJB
#define PTR_TO_CALLNO(a)   ((unsigned short)(unsigned long)(a))
#define TRUNK_CALL_START   0x4000
#define TS_GAP_FOR_JB_RESYNC   5000

Enumerations

enum  { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) }
enum  {
  IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3),
  IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7),
  IAX_MESSAGEDETAIL = (1 << 8), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11),
  IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15),
  IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19),
  IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_MAXAUTHREQ = (1 << 23)
}
enum  iax_reg_state {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH
}
enum  iax_transfer_state {
  TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED,
  TRANSFER_PASSTHROUGH
}

Functions

static int __do_deliver (void *data)
static int __iax2_show_peers (int manager, int fd, int argc, char *argv[])
static int __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final)
static int __unload_module (void)
static int apply_context (struct iax2_context *con, char *context)
static int ast_cli_netstats (int fd, int limit_fmt)
static struct ast_channelast_iax2_new (int callno, int state, int capability)
 AST_MUTEX_DEFINE_STATIC (dpcache_lock)
 AST_MUTEX_DEFINE_STATIC (tpeerlock)
 AST_MUTEX_DEFINE_STATIC (usecnt_lock)
static int attempt_transmit (void *data)
static int auth_fail (int callno, int failcode)
static int auth_reject (void *nothing)
static int authenticate (char *challenge, char *secret, char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
static int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey)
static int authenticate_request (struct chan_iax2_pvt *p)
static int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
static int auto_congest (void *nothing)
static int auto_hangup (void *nothing)
static 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, int temponly)
static struct iax2_userbuild_user (const char *name, struct ast_variable *v, int temponly)
static int cache_get_callno_locked (const char *data)
static unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
static unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
static unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
static int check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
static int check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
static int check_srcaddr (struct sockaddr *sa, socklen_t salen)
static int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static char * complete_iax2_show_peer (char *line, char *word, int pos, int state)
static int complete_transfer (int callno, struct iax_ies *ies)
static unsigned char compress_subclass (int subclass)
static void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
static int create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
static int decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
static void delete_users (void)
char * description ()
 Provides a description of the module.
static void destroy_firmware (struct iax_firmware *cur)
static void destroy_peer (struct iax2_peer *peer)
static void destroy_user (struct iax2_user *user)
static void dp_lookup (int callno, char *context, char *callednum, char *callerid, int skiplock)
static void * dp_lookup_thread (void *data)
static int encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
static int expire_registry (void *data)
static struct iax2_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_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 char * function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
static int get_auth_methods (char *value)
static int get_encrypt_methods (const char *s)
static int get_from_jb (void *p)
static 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)
static unsigned int iax2_datetime (char *tz)
static void iax2_destroy (int callno)
static void iax2_destroy_nolock (int callno)
static int iax2_devicestate (void *data)
static int iax2_digit (struct ast_channel *c, char digit)
static int iax2_do_debug (int fd, int argc, char *argv[])
static int iax2_do_jb_debug (int fd, int argc, char *argv[])
static int iax2_do_register (struct iax2_registry *reg)
static int iax2_do_register_s (void *data)
static int iax2_do_trunk_debug (int fd, int argc, char *argv[])
static void iax2_dprequest (struct iax2_dpcache *dp, int callno)
static int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
static int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
static void iax2_frame_free (struct iax_frame *fr)
static int iax2_getpeername (struct sockaddr_in sin, char *host, int len, int lockpeer)
static int iax2_getpeertrunk (struct sockaddr_in sin)
static int iax2_hangup (struct ast_channel *c)
static int iax2_indicate (struct ast_channel *c, int condition)
static int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
static int iax2_no_debug (int fd, int argc, char *argv[])
static int iax2_no_jb_debug (int fd, int argc, char *argv[])
static int iax2_no_trunk_debug (int fd, int argc, char *argv[])
static int iax2_poke_noanswer (void *data)
static int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
static int iax2_poke_peer_s (void *data)
static int iax2_predestroy (int callno)
static int iax2_predestroy_nolock (int callno)
static int iax2_prov_app (struct ast_channel *chan, void *data)
static int iax2_prov_cmd (int fd, int argc, char *argv[])
static char * iax2_prov_complete_template_3rd (char *line, char *word, int pos, int state)
static int iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
static int iax2_prune_realtime (int fd, int argc, char *argv[])
static int iax2_queue_frame (int callno, struct ast_frame *f)
static struct ast_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_jitter (int fd, int argc, char *argv[])
static int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
static int iax2_show_cache (int fd, int argc, char *argv[])
static int iax2_show_channels (int fd, int argc, char *argv[])
static int iax2_show_firmware (int fd, int argc, char *argv[])
static int iax2_show_netstats (int fd, int argc, char *argv[])
static int iax2_show_peer (int fd, int argc, char *argv[])
static int iax2_show_peers (int fd, int argc, char *argv[])
static int iax2_show_registry (int fd, int argc, char *argv[])
static int iax2_show_stats (int fd, int argc, char *argv[])
static int iax2_show_users (int fd, int argc, char *argv[])
static int iax2_start_transfer (unsigned short callno0, unsigned short callno1)
static int iax2_test_losspct (int fd, int argc, char *argv[])
static int iax2_transfer (struct ast_channel *c, const char *dest)
static int iax2_transmit (struct iax_frame *fr)
static int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
static int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
static int iax2_vnak (int callno)
static int iax2_write (struct ast_channel *c, struct ast_frame *f)
static int iax_check_version (char *dev)
static void iax_debug_output (const char *data)
static void iax_error_output (const char *data)
static int iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
static int iax_park (struct ast_channel *chan1, struct ast_channel *chan2)
static void * iax_park_thread (void *stuff)
static struct iax_frameiaxfrdup2 (struct iax_frame *fr)
static void jb_debug_output (const char *fmt,...)
static void jb_error_output (const char *fmt,...)
static void jb_warning_output (const char *fmt,...)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static void lock_both (unsigned short callno0, unsigned short callno1)
static int make_trunk (unsigned short callno, int locked)
static int manager_iax2_show_netstats (struct mansession *s, struct message *m)
static int manager_iax2_show_peers (struct mansession *s, struct message *m)
static int match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
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)
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)
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 (char *name, int callno)
static int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
static char * regstate2str (int regstate)
int reload (void)
 Reload stuff.
static int reload_config (void)
static void reload_firmware (void)
static void save_rr (struct iax_frame *fr, struct iax_ies *ies)
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)
static void set_timing (void)
static int socket_read (int *id, int fd, short events, void *cbdata)
static void spawn_dp_lookup (int callno, char *context, char *callednum, char *callerid)
static int start_network_thread (void)
static int stop_stuff (int callno)
static int timing_read (int *id, int fd, short events, void *cbdata)
static int transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
static int try_firmware (char *s)
static int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
static int uncompress_subclass (unsigned char csub)
int unload_module ()
 Cleanup all module structures, sockets, etc.
static void unlock_both (unsigned short callno0, unsigned short callno1)
static void unwrap_timestamp (struct iax_frame *fr)
static void update_jbsched (struct chan_iax2_pvt *pvt)
static void update_max_nontrunk (void)
static void update_max_trunk (void)
static int update_packet (struct iax_frame *f)
static int update_registry (char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
int usecount ()
 Provides a usecount.
static void vnak_retransmit (int callno, int last)

Variables

static char accountcode [AST_MAX_ACCOUNT_CODE]
static int amaflags = 0
static int authdebug = 1
static int autokill = 0
static const char channeltype [] = "IAX2"
static char context [80] = "default"
static char debug_jb_usage []
static char debug_trunk_usage []
static char debug_usage []
static int defaultsockfd = -1
static int delayreject = 0
static const char desc [] = "Inter Asterisk eXchange (Ver 2)"
static struct iax2_dpcachedpcache
static int global_rtautoclear = 120
static struct ast_flags globalflags = { 0 }
static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH
static struct ast_cli_entry iax2_cli []
static int iax2_dropcount = DEFAULT_DROP
static int iax2_encryption = 0
enum { ... }  iax2_flags
int(* iax2_regfunk )(char *username, int onoff) = NULL
static char iax2_reload_usage []
struct {
   int   alarm
   char *   description
   unsigned int   event_log:1
   enum queue_result   id
   char *   name
   char *   name
   char *   name
   rtpPayloadType   payloadType
   unsigned int   queue_log:1
   char *   subtype
   char *   text
   char *   type
   int   val
iax2_state
static struct ast_switch iax2_switch
static const struct ast_channel_tech iax2_tech
static char iax2_test_losspct_usage []
static int iaxcompat = 0
static int iaxdebug = 0
static int iaxdefaultdpcache = 10 * 60
static int iaxdefaulttimeout = 5
ast_custom_function iaxpeer_function
static struct ast_iax2_queue iaxq
static struct chan_iax2_pvtiaxs [IAX_MAX_CALLS]
static ast_mutex_t iaxsl [IAX_MAX_CALLS]
static int iaxtrunkdebug = 0
static struct io_contextio
static char jitter_usage []
static int jittershrinkrate = 2
static int lagrq_time = 10
static char language [MAX_LANGUAGE] = ""
static struct timeval lastused [IAX_MAX_CALLS]
static int max_jitter_buffer = MAX_JITTER_BUFFER
static int max_reg_expire
static int max_retries = 4
static int maxauthreq = 0
static int maxjitterbuffer = 1000
static int maxjitterinterps = 10
static int maxnontrunkcall = 1
static int maxtrunkcall = TRUNK_CALL_START
static int min_jitter_buffer = MIN_JITTER_BUFFER
static int min_reg_expire
static struct ast_netsock_listnetsock
static pthread_t netthreadid = AST_PTHREADT_NULL
static char no_debug_jb_usage []
static char no_debug_trunk_usage []
static char no_debug_usage []
static char * papp = "IAX2Provision"
static char * pdescrip
static struct ast_peer_list peerl
static int ping_time = 20
static struct ast_codec_pref prefs
static char prune_realtime_usage []
static char * psyn = "Provision a calling IAXy with a given template"
static char regcontext [AST_MAX_CONTEXT] = ""
static struct iax2_registryregistrations
static int resyncthreshold = 1000
static struct sched_contextsched
static char show_cache_usage []
static char show_channels_usage []
static char show_firmware_usage []
static char show_netstats_usage []
static char show_peer_usage []
static char show_peers_usage []
static char show_prov_usage []
static char show_reg_usage []
static char show_stats_usage []
static char show_users_usage []
static const char tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)"
static int test_losspct = 0
static int timingfd = -1
static int tos = 0
static struct iax2_trunk_peertpeers
static int trunkfreq = 20
static int usecnt
static struct ast_user_list userl
static struct ast_firmware_list waresl


Detailed Description

Implementation of Inter-Asterisk eXchange Version 2.

See also

Definition in file chan_iax2.c.


Define Documentation

#define CACHE_FLAG_CANEXIST   (1 << 2)
 

Extension can exist

Definition at line 634 of file chan_iax2.c.

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

#define CACHE_FLAG_EXISTS   (1 << 0)
 

Extension exists

Definition at line 630 of file chan_iax2.c.

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

#define CACHE_FLAG_MATCHMORE   (1 << 7)
 

Matchmore

Definition at line 644 of file chan_iax2.c.

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

#define CACHE_FLAG_NONEXISTENT   (1 << 1)
 

Extension is nonexistent

Definition at line 632 of file chan_iax2.c.

Referenced by complete_dpreply(), and iax2_show_cache().

#define CACHE_FLAG_PENDING   (1 << 3)
 

Waiting to hear back response

Definition at line 636 of file chan_iax2.c.

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

#define CACHE_FLAG_TIMEOUT   (1 << 4)
 

Timed out

Definition at line 638 of file chan_iax2.c.

Referenced by find_cache(), and iax2_show_cache().

#define CACHE_FLAG_TRANSMITTED   (1 << 5)
 

Request transmitted

Definition at line 640 of file chan_iax2.c.

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

#define CACHE_FLAG_UNKNOWN   (1 << 6)
 

Timeout

Definition at line 642 of file chan_iax2.c.

Referenced by complete_dpreply(), and iax2_show_cache().

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

Definition at line 123 of file chan_iax2.c.

Referenced by ast_iax2_new(), and iax2_call().

#define DEBUG_SUPPORT
 

Definition at line 132 of file chan_iax2.c.

#define DEFAULT_DROP   3
 

Definition at line 127 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000
 

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

Referenced by build_peer(), and handle_response_peerpoke().

#define DEFAULT_MAXMS   2000
 

Definition at line 202 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME   1000
 

Definition at line 125 of file chan_iax2.c.

Referenced by complete_transfer().

#define DEFAULT_TRUNKDATA   640 * 10
 

40ms, uncompressed linear * 10 channels

Definition at line 421 of file chan_iax2.c.

Referenced by iax2_trunk_queue().

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

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

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

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

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

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

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

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

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

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

#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
 

Referenced by iax2_show_channels().

#define FREE   free
 

Definition at line 672 of file chan_iax2.c.

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

#define GAMMA   (0.01)
 

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

Referenced by iax2_trunk_queue().

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
 

Definition at line 187 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWBANDWIDTH
 

Value:

Definition at line 194 of file chan_iax2.c.

Referenced by set_config().

#define IAX_CAPABILITY_LOWFREE
 

Value:

Definition at line 198 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH
 

Value:

Definition at line 189 of file chan_iax2.c.

Referenced by set_config().

#define IPTOS_MINCOST   0x02
 

Definition at line 106 of file chan_iax2.c.

#define MAX_JITTER_BUFFER   50
 

Definition at line 418 of file chan_iax2.c.

#define MAX_RETRY_TIME   10000
 

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

#define MAX_TRUNKDATA   640 * 200
 

40ms, uncompressed linear * 200 channels

Definition at line 422 of file chan_iax2.c.

Referenced by iax2_trunk_queue(), and timing_read().

#define MEMORY_SIZE   100
 

Definition at line 126 of file chan_iax2.c.

Referenced by schedule_delivery().

#define MIN_JITTER_BUFFER   10
 

Definition at line 419 of file chan_iax2.c.

#define MIN_RETRY_TIME   100
 

Definition at line 415 of file chan_iax2.c.

Referenced by iax2_send().

#define MIN_REUSE_TIME   60
 

Definition at line 134 of file chan_iax2.c.

Referenced by make_trunk().

#define NEW_ALLOW   1
 

Definition at line 958 of file chan_iax2.c.

Referenced by find_callno(), and socket_read().

#define NEW_FORCE   2
 

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

Referenced by socket_read().

#define NEWJB
 

Definition at line 99 of file chan_iax2.c.

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

Definition at line 122 of file chan_iax2.c.

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

#define TRUNK_CALL_START   0x4000
 

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

Referenced by schedule_delivery().


Enumeration Type Documentation

anonymous enum
 

Enumerator:
IAX_STATE_STARTED 
IAX_STATE_AUTHENTICATED 
IAX_STATE_TBD 

Definition at line 234 of file chan_iax2.c.

00234      {
00235    IAX_STATE_STARTED =     (1 << 0),
00236    IAX_STATE_AUTHENTICATED =  (1 << 1),
00237    IAX_STATE_TBD =      (1 << 2)
00238 } iax2_state;

anonymous enum
 

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

Definition at line 245 of file chan_iax2.c.

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

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

enum iax_transfer_state
 

Enumerator:
TRANSFER_NONE 
TRANSFER_BEGIN 
TRANSFER_READY 
TRANSFER_RELEASED 
TRANSFER_PASSTHROUGH 

Definition at line 390 of file chan_iax2.c.

00390                         {
00391    TRANSFER_NONE = 0,
00392    TRANSFER_BEGIN,
00393    TRANSFER_READY,
00394    TRANSFER_RELEASED,
00395    TRANSFER_PASSTHROUGH
00396 };


Function Documentation

static int __do_deliver void *  data  )  [static]
 

Definition at line 1424 of file chan_iax2.c.

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

Referenced by get_from_jb().

01425 {
01426    /* Just deliver the packet by using queueing.  This is called by
01427      the IAX thread with the iaxsl lock held. */
01428    struct iax_frame *fr = data;
01429    fr->retrans = -1;
01430    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01431       iax2_queue_frame(fr->callno, &fr->af);
01432    /* Free our iax frame */
01433    iax2_frame_free(fr);
01434    /* And don't run again */
01435    return 0;
01436 }

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

Definition at line 4214 of file chan_iax2.c.

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

Referenced by iax2_show_peers(), and manager_iax2_show_peers().

04215 {
04216    regex_t regexbuf;
04217    int havepattern = 0;
04218    int total_peers = 0;
04219    int online_peers = 0;
04220    int offline_peers = 0;
04221    int unmonitored_peers = 0;
04222 
04223 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04224 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04225 
04226    struct iax2_peer *peer;
04227    char name[256];
04228    char iabuf[INET_ADDRSTRLEN];
04229    int registeredonly=0;
04230    char *term = manager ? "\r\n" : "\n";
04231 
04232    switch (argc) {
04233    case 6:
04234       if (!strcasecmp(argv[3], "registered"))
04235          registeredonly = 1;
04236       else
04237          return RESULT_SHOWUSAGE;
04238       if (!strcasecmp(argv[4], "like")) {
04239          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04240             return RESULT_SHOWUSAGE;
04241          havepattern = 1;
04242       } else
04243          return RESULT_SHOWUSAGE;
04244       break;
04245    case 5:
04246       if (!strcasecmp(argv[3], "like")) {
04247          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04248             return RESULT_SHOWUSAGE;
04249          havepattern = 1;
04250       } else
04251          return RESULT_SHOWUSAGE;
04252       break;
04253    case 4:
04254       if (!strcasecmp(argv[3], "registered"))
04255          registeredonly = 1;
04256       else
04257          return RESULT_SHOWUSAGE;
04258       break;
04259    case 3:
04260       break;
04261    default:
04262       return RESULT_SHOWUSAGE;
04263    }
04264 
04265    ast_mutex_lock(&peerl.lock);
04266    ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04267    for (peer = peerl.peers;peer;peer = peer->next) {
04268       char nm[20];
04269       char status[20];
04270       char srch[2000];
04271       int retstatus;
04272 
04273       if (registeredonly && !peer->addr.sin_addr.s_addr)
04274          continue;
04275       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04276          continue;
04277 
04278       if (!ast_strlen_zero(peer->username))
04279          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04280       else
04281          ast_copy_string(name, peer->name, sizeof(name));
04282       
04283       retstatus = peer_status(peer, status, sizeof(status));
04284       if (retstatus > 0)
04285          online_peers++;
04286       else if (!retstatus)
04287          offline_peers++;
04288       else
04289          unmonitored_peers++;
04290       
04291       ast_copy_string(nm, ast_inet_ntoa(iabuf, sizeof(iabuf), peer->mask), sizeof(nm));
04292 
04293       snprintf(srch, sizeof(srch), FORMAT, name, 
04294                peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
04295                ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04296                nm,
04297                ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04298                peer->encmethods ? "(E)" : "   ", status, term);
04299 
04300       ast_cli(fd, FORMAT, name, 
04301                peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)",
04302                ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04303                nm,
04304                ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04305                peer->encmethods ? "(E)" : "   ", status, term);
04306       total_peers++;
04307    }
04308    ast_mutex_unlock(&peerl.lock);
04309 
04310    ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04311 
04312    if (havepattern)
04313       regfree(&regexbuf);
04314 
04315    return RESULT_SUCCESS;
04316 #undef FORMAT
04317 #undef FORMAT2
04318 }

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

04682 {
04683    struct ast_frame f;
04684    f.frametype = type;
04685    f.subclass = command;
04686    f.datalen = datalen;
04687    f.samples = 0;
04688    f.mallocd = 0;
04689    f.offset = 0;
04690    f.src = (char *)__FUNCTION__;
04691    f.data = (char *)data;
04692    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04693 }

static int __unload_module void   )  [static]
 

Definition at line 9631 of file chan_iax2.c.

References ast_channel_unregister(), ast_cli_unregister_multiple(), ast_manager_unregister(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_cli, iax2_destroy(), iax2_switch, iax2_tech, IAX_MAX_CALLS, iax_provision_unload(), netsock, netthreadid, and sched_context_destroy().

Referenced by load_module(), and unload_module().

09632 {
09633    int x;
09634    /* Cancel the network thread, close the net socket */
09635    if (netthreadid != AST_PTHREADT_NULL) {
09636       pthread_cancel(netthreadid);
09637       pthread_join(netthreadid, NULL);
09638    }
09639    ast_netsock_release(netsock);
09640    for (x=0;x<IAX_MAX_CALLS;x++)
09641       if (iaxs[x])
09642          iax2_destroy(x);
09643    ast_manager_unregister( "IAXpeers" );
09644    ast_manager_unregister( "IAXnetstats" );
09645    ast_unregister_application(papp);
09646    ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09647    ast_unregister_switch(&iax2_switch);
09648    ast_channel_unregister(&iax2_tech);
09649    delete_users();
09650    iax_provision_unload();
09651    sched_context_destroy(sched);
09652    return 0;
09653 }

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

Definition at line 4733 of file chan_iax2.c.

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

Referenced by check_access().

04734 {
04735    while(con) {
04736       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04737          return -1;
04738       con = con->next;
04739    }
04740    return 0;
04741 }

static int ast_cli_netstats int  fd,
int  limit_fmt
[static]
 

Definition at line 4500 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), IAX_MAX_CALLS, and iaxsl.

Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().

04501 {
04502    int x;
04503    int numchans = 0;
04504    for (x=0;x<IAX_MAX_CALLS;x++) {
04505       ast_mutex_lock(&iaxsl[x]);
04506       if (iaxs[x]) {
04507 #ifdef BRIDGE_OPTIMIZATION
04508          if (iaxs[x]->bridgecallno) {
04509             if (limit_fmt) 
04510                ast_cli(fd, "%-25.25s <NATIVE BRIDGED>",
04511                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)");
04512             else
04513                ast_cli(fd, "%s <NATIVE BRIDGED>",
04514                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)");
04515                         } else
04516 #endif
04517          {
04518             int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04519             char *fmt;
04520 #ifdef NEWJB
04521             jb_info jbinfo;
04522 
04523             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04524                jb_getinfo(iaxs[x]->jb, &jbinfo);
04525                localjitter = jbinfo.jitter;
04526                localdelay = jbinfo.current - jbinfo.min;
04527                locallost = jbinfo.frames_lost;
04528                locallosspct = jbinfo.losspct/1000;
04529                localdropped = jbinfo.frames_dropped;
04530                localooo = jbinfo.frames_ooo;
04531             } else {
04532                localjitter = -1;
04533                localdelay = 0;
04534                locallost = -1;
04535                locallosspct = -1;
04536                localdropped = 0;
04537                localooo = -1;
04538             }
04539 #else
04540             localjitter = iaxs[x]->jitter;
04541             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) 
04542             {
04543                localdelay = jitterbufsize(iaxs[x]);
04544                localdropped = iaxs[x]->frames_dropped;
04545             } else {
04546                localdelay = localdropped = 0;
04547             }
04548             locallost = locallosspct = localooo = -1;
04549 #endif
04550             if (limit_fmt)
04551                fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04552             else
04553                fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04554             ast_cli(fd, fmt,
04555                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04556                   iaxs[x]->pingtime,
04557                   localjitter, 
04558                   localdelay,
04559                   locallost,
04560                   locallosspct,
04561                   localdropped,
04562                   localooo,
04563                   iaxs[x]->frames_received/1000,
04564                   iaxs[x]->remote_rr.jitter,
04565                   iaxs[x]->remote_rr.delay,
04566                   iaxs[x]->remote_rr.losscnt,
04567                   iaxs[x]->remote_rr.losspct,
04568                   iaxs[x]->remote_rr.dropped,
04569                   iaxs[x]->remote_rr.ooo,
04570                   iaxs[x]->remote_rr.packets/1000
04571             );
04572          }
04573          numchans++;
04574       }
04575       ast_mutex_unlock(&iaxsl[x]);
04576    }
04577    return numchans;
04578 }

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

Definition at line 3427 of file chan_iax2.c.

References ast_channel::accountcode, chan_iax2_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), AST_STATE_DOWN, ast_strlen_zero(), ast_update_use_count(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, channeltype, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, chan_iax2_pvt::cid_name, ast_callerid::cid_num, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, chan_iax2_pvt::context, ast_channel::context, chan_iax2_pvt::dnid, chan_iax2_pvt::exten, ast_channel::exten, chan_iax2_pvt::host, iax2_tech, iaxsl, ast_channel::language, chan_iax2_pvt::language, LOG_WARNING, ast_variable::name, ast_channel::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::readformat, strdup, ast_channel::tech, ast_channel::tech_pvt, ast_channel::type, usecnt, usecnt_lock, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_read().

03428 {
03429    struct ast_channel *tmp;
03430    struct chan_iax2_pvt *i;
03431    struct ast_variable *v = NULL;
03432 
03433    /* Don't hold call lock */
03434    ast_mutex_unlock(&iaxsl[callno]);
03435    tmp = ast_channel_alloc(1);
03436    ast_mutex_lock(&iaxsl[callno]);
03437    i = iaxs[callno];
03438    if (i && tmp) {
03439       tmp->tech = &iax2_tech;
03440       snprintf(tmp->name, sizeof(tmp->name), "IAX2/%s-%d", i->host, i->callno);
03441       tmp->type = channeltype;
03442       /* We can support any format by default, until we get restricted */
03443       tmp->nativeformats = capability;
03444       tmp->readformat = ast_best_codec(capability);
03445       tmp->writeformat = ast_best_codec(capability);
03446       tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03447 
03448       if (!ast_strlen_zero(i->cid_num))
03449          tmp->cid.cid_num = strdup(i->cid_num);
03450       if (!ast_strlen_zero(i->cid_name))
03451          tmp->cid.cid_name = strdup(i->cid_name);
03452       if (!ast_strlen_zero(i->ani))
03453          tmp->cid.cid_ani = strdup(i->ani);
03454       tmp->cid.cid_pres = i->calling_pres;
03455       tmp->cid.cid_ton = i->calling_ton;
03456       tmp->cid.cid_tns = i->calling_tns;
03457 
03458       if (!ast_strlen_zero(i->language))
03459          ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
03460       if (!ast_strlen_zero(i->dnid))
03461          tmp->cid.cid_dnid = strdup(i->dnid);
03462       if (!ast_strlen_zero(i->accountcode))
03463          ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
03464       if (i->amaflags)
03465          tmp->amaflags = i->amaflags;
03466       ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03467       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03468       tmp->adsicpe = i->peeradsicpe;
03469       i->owner = tmp;
03470       i->capability = capability;
03471       ast_setstate(tmp, state);
03472       if (state != AST_STATE_DOWN) {
03473          if (ast_pbx_start(tmp)) {
03474             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03475             ast_hangup(tmp);
03476             tmp = NULL;
03477          }
03478       }
03479       for (v = i->vars ; v ; v = v->next)
03480          pbx_builtin_setvar_helper(tmp,v->name,v->value);
03481       
03482       ast_mutex_lock(&usecnt_lock);
03483       usecnt++;
03484       ast_mutex_unlock(&usecnt_lock);
03485       ast_update_use_count();
03486    }
03487    return tmp;
03488 }

AST_MUTEX_DEFINE_STATIC dpcache_lock   ) 
 

AST_MUTEX_DEFINE_STATIC tpeerlock   ) 
 

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

static int attempt_transmit void *  data  )  [static]
 

Definition at line 1736 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_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), iax_frame::callno, ast_iax2_queue::count, chan_iax2_pvt::error, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, ast_iax2_queue::head, iax2_destroy_nolock(), iax2_frame_free(), iax2_queue_frame(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, ast_iax2_queue::lock, LOG_WARNING, max_retries, MAX_RETRY_TIME, iax_frame::next, iax_frame::oseqno, chan_iax2_pvt::owner, iax_frame::prev, REG_STATE_TIMEOUT, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, ast_iax2_queue::tail, iax_frame::transfer, iax_frame::ts, and update_packet().

01737 {
01738    /* Attempt to transmit the frame to the remote peer...
01739       Called without iaxsl held. */
01740    struct iax_frame *f = data;
01741    int freeme=0;
01742    int callno = f->callno;
01743    char iabuf[INET_ADDRSTRLEN];
01744    /* Make sure this call is still active */
01745    if (callno) 
01746       ast_mutex_lock(&iaxsl[callno]);
01747    if ((f->callno) && iaxs[f->callno]) {
01748       if ((f->retries < 0) /* Already ACK'd */ ||
01749           (f->retries >= max_retries) /* Too many attempts */) {
01750             /* Record an error if we've transmitted too many times */
01751             if (f->retries >= max_retries) {
01752                if (f->transfer) {
01753                   /* Transfer timeout */
01754                   send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
01755                } else if (f->final) {
01756                   if (f->final) 
01757                      iax2_destroy_nolock(f->callno);
01758                } else {
01759                   if (iaxs[f->callno]->owner)
01760                      ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
01761                   iaxs[f->callno]->error = ETIMEDOUT;
01762                   if (iaxs[f->callno]->owner) {
01763                      struct ast_frame fr = { 0, };
01764                      /* Hangup the fd */
01765                      fr.frametype = AST_FRAME_CONTROL;
01766                      fr.subclass = AST_CONTROL_HANGUP;
01767                      iax2_queue_frame(f->callno, &fr);
01768                      /* Remember, owner could disappear */
01769                      if (iaxs[f->callno]->owner)
01770                         iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01771                   } else {
01772                      if (iaxs[f->callno]->reg) {
01773                         memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us));
01774                         iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT;
01775                         iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
01776                      }
01777                      iax2_destroy_nolock(f->callno);
01778                   }
01779                }
01780 
01781             }
01782             freeme++;
01783       } else {
01784          /* Update it if it needs it */
01785          update_packet(f);
01786          /* Attempt transmission */
01787          send_packet(f);
01788          f->retries++;
01789          /* Try again later after 10 times as long */
01790          f->retrytime *= 10;
01791          if (f->retrytime > MAX_RETRY_TIME)
01792             f->retrytime = MAX_RETRY_TIME;
01793          /* Transfer messages max out at one second */
01794          if (f->transfer && (f->retrytime > 1000))
01795             f->retrytime = 1000;
01796          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
01797       }
01798    } else {
01799       /* Make sure it gets freed */
01800       f->retries = -1;
01801       freeme++;
01802    }
01803    if (callno)
01804       ast_mutex_unlock(&iaxsl[callno]);
01805    /* Do not try again */
01806    if (freeme) {
01807       /* Don't attempt delivery, just remove it from the queue */
01808       ast_mutex_lock(&iaxq.lock);
01809       if (f->prev) 
01810          f->prev->next = f->next;
01811       else
01812          iaxq.head = f->next;
01813       if (f->next)
01814          f->next->prev = f->prev;
01815       else
01816          iaxq.tail = f->prev;
01817       iaxq.count--;
01818       ast_mutex_unlock(&iaxq.lock);
01819       f->retrans = -1;
01820       /* Free the IAX frame */
01821       iax2_frame_free(f);
01822    }
01823    return 0;
01824 }

static int auth_fail int  callno,
int  failcode
[static]
 

Definition at line 5951 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), auth_reject(), delayreject, and iaxsl.

Referenced by socket_read().

05952 {
05953    /* Schedule sending the authentication failure in one second, to prevent
05954       guessing */
05955    ast_mutex_lock(&iaxsl[callno]);
05956    iaxs[callno]->authfail = failcode;
05957    if (delayreject) {
05958       if (iaxs[callno]->authid > -1)
05959          ast_sched_del(sched, iaxs[callno]->authid);
05960       iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05961    } else
05962       auth_reject((void *)(long)callno);
05963    ast_mutex_unlock(&iaxsl[callno]);
05964    return 0;
05965 }

static int auth_reject void *  nothing  )  [static]
 

Definition at line 5929 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, iaxsl, and send_command_final().

Referenced by auth_fail().

05930 {
05931    /* Called from IAX thread only, without iaxs lock */
05932    int callno = (int)(long)(nothing);
05933    struct iax_ie_data ied;
05934    ast_mutex_lock(&iaxsl[callno]);
05935    if (iaxs[callno]) {
05936       iaxs[callno]->authid = -1;
05937       memset(&ied, 0, sizeof(ied));
05938       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05939          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05940          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05941       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05942          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05943          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05944       }
05945       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05946    }
05947    ast_mutex_unlock(&iaxsl[callno]);
05948    return 0;
05949 }

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

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

05252 {
05253    int res = -1;
05254    int x;
05255    char iabuf[INET_ADDRSTRLEN];
05256    if (!ast_strlen_zero(keyn)) {
05257       if (!(authmethods & IAX_AUTH_RSA)) {
05258          if (ast_strlen_zero(secret)) 
05259             ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05260       } else if (ast_strlen_zero(challenge)) {
05261          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05262       } else {
05263          char sig[256];
05264          struct ast_key *key;
05265          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05266          if (!key) {
05267             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05268          } else {
05269             if (ast_sign(key, challenge, sig)) {
05270                ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n");
05271                res = -1;
05272             } else {
05273                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05274                res = 0;
05275             }
05276          }
05277       }
05278    } 
05279    /* Fall back */
05280    if (res && !ast_strlen_zero(secret)) {
05281       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05282          struct MD5Context md5;
05283          unsigned char digest[16];
05284          char digres[128];
05285          MD5Init(&md5);
05286          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05287          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05288          MD5Final(digest, &md5);
05289          /* If they support md5, authenticate with it.  */
05290          for (x=0;x<16;x++)
05291             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05292          if (ecx && dcx)
05293             build_enc_keys(digest, ecx, dcx);
05294          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05295          res = 0;
05296       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05297          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05298          res = 0;
05299       } else
05300          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), authmethods);
05301    }
05302    return res;
05303 }

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

Definition at line 5305 of file chan_iax2.c.

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

Referenced by socket_read().

05306 {
05307    struct iax2_peer *peer;
05308    /* Start pessimistic */
05309    int res = -1;
05310    int authmethods = 0;
05311    struct iax_ie_data ied;
05312    
05313    memset(&ied, 0, sizeof(ied));
05314    
05315    if (ies->username)
05316       ast_copy_string(p->username, ies->username, sizeof(p->username));
05317    if (ies->challenge)
05318       ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge));
05319    if (ies->authmethods)
05320       authmethods = ies->authmethods;
05321    if (authmethods & IAX_AUTH_MD5)
05322       merge_encryption(p, ies->encmethods);
05323    else
05324       p->encmethods = 0;
05325 
05326    /* Check for override RSA authentication first */
05327    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05328       /* Normal password authentication */
05329       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05330    } else {
05331       ast_mutex_lock(&peerl.lock);
05332       peer = peerl.peers;
05333       while(peer) {
05334          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05335                         /* No peer specified at our end, or this is the peer */
05336           && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05337                         /* No username specified in peer rule, or this is the right username */
05338           && (!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)))
05339                         /* No specified host, or this is our host */
05340          ) {
05341             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05342             if (!res)
05343                break;   
05344          }
05345          peer = peer->next;
05346       }
05347       ast_mutex_unlock(&peerl.lock);
05348       if (!peer) {
05349          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05350             that we're trying to authenticate *to* a realtime peer */
05351          if ((peer = realtime_peer(p->peer, NULL))) {
05352             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05353             if (ast_test_flag(peer, IAX_TEMPONLY))
05354                destroy_peer(peer);
05355          }
05356       }
05357    }
05358    if (ies->encmethods)
05359       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05360    if (!res)
05361       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05362    return res;
05363 }

static int authenticate_request struct chan_iax2_pvt p  )  [static]
 

Definition at line 4975 of file chan_iax2.c.

References AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, ast_user_list::lock, send_command(), send_command_final(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by socket_read().

04976 {
04977    struct iax2_user *user = NULL;
04978    struct iax_ie_data ied;
04979    int res = -1, authreq_restrict = 0;
04980 
04981    memset(&ied, 0, sizeof(ied));
04982 
04983    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
04984    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04985       ast_mutex_lock(&userl.lock);
04986       user = userl.users;
04987       while (user) {
04988          if (!strcmp(user->name, p->username)) {
04989             if (user->curauthreq == user->maxauthreq)
04990                authreq_restrict = 1;
04991             else
04992                user->curauthreq++;
04993             break;
04994          }
04995          user = user->next;
04996       }
04997       ast_mutex_unlock(&userl.lock);
04998    }
04999 
05000    /* If the AUTHREQ limit test failed, send back an error */
05001    if (authreq_restrict) {
05002       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05003       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05004       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05005       return 0;
05006    }
05007 
05008    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05009    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05010       snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
05011       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05012    }
05013    if (p->encmethods)
05014       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05015 
05016    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05017 
05018    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05019 
05020    if (p->encmethods)
05021       ast_set_flag(p, IAX_ENCRYPTED);
05022 
05023    return res;
05024 }

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

Definition at line 5026 of file chan_iax2.c.

References ast_check_signature, ast_clear_flag, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, chan_iax2_pvt::inkeys, key(), ast_user_list::lock, LOG_WARNING, MD5Final(), MD5Init(), MD5Update(), chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by socket_read().

05027 {
05028    char requeststr[256];
05029    char md5secret[256] = "";
05030    char secret[256] = "";
05031    char rsasecret[256] = "";
05032    int res = -1; 
05033    int x;
05034    struct iax2_user *user = NULL;
05035 
05036    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05037       ast_mutex_lock(&userl.lock);
05038       user = userl.users;
05039       while (user) {
05040          if (!strcmp(user->name, p->username)) {
05041             user->curauthreq--;
05042             break;
05043          }
05044          user = user->next;
05045       }
05046       ast_mutex_unlock(&userl.lock);
05047       ast_clear_flag(p, IAX_MAXAUTHREQ);
05048    }
05049 
05050    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05051       return res;
05052    if (ies->password)
05053       ast_copy_string(secret, ies->password, sizeof(secret));
05054    if (ies->md5_result)
05055       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05056    if (ies->rsa_result)
05057       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05058    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05059       struct ast_key *key;
05060       char *keyn;
05061       char tmpkey[256];
05062       char *stringp=NULL;
05063       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05064       stringp=tmpkey;
05065       keyn = strsep(&stringp, ":");
05066       while(keyn) {
05067          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05068          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05069             res = 0;
05070             break;
05071          } else if (!key)
05072             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05073          keyn = strsep(&stringp, ":");
05074       }
05075    } else if (p->authmethods & IAX_AUTH_MD5) {
05076       struct MD5Context md5;
05077       unsigned char digest[16];
05078       char *tmppw, *stringp;
05079       
05080       tmppw = ast_strdupa(p->secret);
05081       stringp = tmppw;
05082       while((tmppw = strsep(&stringp, ";"))) {
05083          MD5Init(&md5);
05084          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05085          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05086          MD5Final(digest, &md5);
05087          /* If they support md5, authenticate with it.  */
05088          for (x=0;x<16;x++)
05089             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05090          if (!strcasecmp(requeststr, md5secret)) {
05091             res = 0;
05092             break;
05093          }
05094       }
05095    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05096       if (!strcmp(secret, p->secret))
05097          res = 0;
05098    }
05099    return res;
05100 }

static int auto_congest void *  nothing  )  [static]
 

Definition at line 2861 of file chan_iax2.c.

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

Referenced by iax2_call(), and sip_call().

02862 {
02863    int callno = PTR_TO_CALLNO(nothing);
02864    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02865    ast_mutex_lock(&iaxsl[callno]);
02866    if (iaxs[callno]) {
02867       iaxs[callno]->initid = -1;
02868       iax2_queue_frame(callno, &f);
02869       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02870    }
02871    ast_mutex_unlock(&iaxsl[callno]);
02872    return 0;
02873 }

static int auto_hangup void *  nothing  )  [static]
 

Definition at line 5967 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, iaxsl, and send_command_final().

Referenced by iax2_dprequest(), and iax2_provision().

05968 {
05969    /* Called from IAX thread only, without iaxs lock */
05970    int callno = (int)(long)(nothing);
05971    struct iax_ie_data ied;
05972    ast_mutex_lock(&iaxsl[callno]);
05973    if (iaxs[callno]) {
05974       iaxs[callno]->autoid = -1;
05975       memset(&ied, 0, sizeof(ied));
05976       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05977       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05978       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05979    }
05980    ast_mutex_unlock(&iaxsl[callno]);
05981    return 0;
05982 }

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

Definition at line 8113 of file chan_iax2.c.

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

Referenced by build_user().

08114 {
08115    struct iax2_context *con = malloc(sizeof(struct iax2_context));
08116    if (con) {
08117       ast_copy_string(con->context, context, sizeof(con->context));
08118       con->next = NULL;
08119    }
08120    return con;
08121 }

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

Definition at line 3815 of file chan_iax2.c.

References aes_decrypt_key128(), and aes_encrypt_key128().

Referenced by authenticate(), and decrypt_frame().

03816 {
03817    aes_encrypt_key128(digest, ecx);
03818    aes_decrypt_key128(digest, dcx);
03819 }

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

Definition at line 8224 of file chan_iax2.c.

References ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_sched_del(), ast_set2_flag, ast_set_flag, ast_strlen_zero(), ast_test_flag, ast_true(), DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, defaultsockfd, free, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, iax2_capability, iax2_encryption, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, ast_peer_list::lock, LOG_WARNING, malloc, min_reg_expire, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::next, peer_set_srcaddr(), peerl, ast_peer_list::peers, prefs, timingfd, and ast_variable::value.

08225 {
08226    struct iax2_peer *peer;
08227    struct iax2_peer *prev;
08228    struct ast_ha *oldha = NULL;
08229    int maskfound=0;
08230    int found=0;
08231    prev = NULL;
08232    ast_mutex_lock(&peerl.lock);
08233    if (!temponly) {
08234       peer = peerl.peers;
08235       while(peer) {
08236          if (!strcmp(peer->name, name)) { 
08237             break;
08238          }
08239          prev = peer;
08240          peer = peer->next;
08241       }
08242    } else
08243       peer = NULL;   
08244    if (peer) {
08245       found++;
08246       oldha = peer->ha;
08247       peer->ha = NULL;
08248       /* Already in the list, remove it and it will be added back (or FREE'd) */
08249       if (prev) {
08250          prev->next = peer->next;
08251       } else {
08252          peerl.peers = peer->next;
08253       }
08254       ast_mutex_unlock(&peerl.lock);
08255    } else {
08256       ast_mutex_unlock(&peerl.lock);
08257       peer = malloc(sizeof(struct iax2_peer));
08258       if (peer) {
08259          memset(peer, 0, sizeof(struct iax2_peer));
08260          peer->expire = -1;
08261          peer->pokeexpire = -1;
08262          peer->sockfd = defaultsockfd;
08263       }
08264    }
08265    if (peer) {
08266       ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08267       peer->encmethods = iax2_encryption;
08268       peer->secret[0] = '\0';
08269       if (!found) {
08270          ast_copy_string(peer->name, name, sizeof(peer->name));
08271          peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08272          peer->expiry = min_reg_expire;
08273       }
08274       peer->prefs = prefs;
08275       peer->capability = iax2_capability;
08276       peer->smoothing = 0;
08277       peer->pokefreqok = DEFAULT_FREQ_OK;
08278       peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08279       peer->context[0] = '\0';
08280       peer->peercontext[0] = '\0';
08281       while(v) {
08282          if (!strcasecmp(v->name, "secret")) {
08283             ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
08284          } else if (!strcasecmp(v->name, "mailbox")) {
08285             ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
08286          } else if (!strcasecmp(v->name, "dbsecret")) {
08287             ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret));
08288          } else if (!strcasecmp(v->name, "mailboxdetail")) {
08289             ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 
08290          } else if (!strcasecmp(v->name, "trunk")) {
08291             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08292             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08293                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08294                ast_clear_flag(peer, IAX_TRUNK);
08295             }
08296          } else if (!strcasecmp(v->name, "auth")) {
08297             peer->authmethods = get_auth_methods(v->value);
08298          } else if (!strcasecmp(v->name, "encryption")) {
08299             peer->encmethods = get_encrypt_methods(v->value);
08300          } else if (!strcasecmp(v->name, "notransfer")) {
08301             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
08302          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08303             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08304          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08305             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08306          } else if (!strcasecmp(v->name, "host")) {
08307             if (!strcasecmp(v->value, "dynamic")) {
08308                /* They'll register with us */
08309                ast_set_flag(peer, IAX_DYNAMIC); 
08310                if (!found) {
08311                   /* Initialize stuff iff we're not found, otherwise
08312                      we keep going with what we had */
08313                   memset(&peer->addr.sin_addr, 0, 4);
08314                   if (peer->addr.sin_port) {
08315                      /* If we've already got a port, make it the default rather than absolute */
08316                      peer->defaddr.sin_port = peer->addr.sin_port;
08317                      peer->addr.sin_port = 0;
08318                   }
08319                }
08320             } else {
08321                /* Non-dynamic.  Make sure we become that way if we're not */
08322                if (peer->expire > -1)
08323                   ast_sched_del(sched, peer->expire);
08324                peer->expire = -1;
08325                ast_clear_flag(peer, IAX_DYNAMIC);
08326                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08327                   free(peer);
08328                   return NULL;
08329                }
08330                if (!peer->addr.sin_port)
08331                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08332             }
08333             if (!maskfound)
08334                inet_aton("255.255.255.255", &peer->mask);
08335          } else if (!strcasecmp(v->name, "defaultip")) {
08336             if (ast_get_ip(&peer->defaddr, v->value)) {
08337                free(peer);
08338                return NULL;
08339             }
08340          } else if (!strcasecmp(v->name, "sourceaddress")) {
08341             peer_set_srcaddr(peer, v->value);
08342          } else if (!strcasecmp(v->name, "permit") ||
08343                   !strcasecmp(v->name, "deny")) {
08344             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08345          } else if (!strcasecmp(v->name, "mask")) {
08346             maskfound++;
08347             inet_aton(v->value, &peer->mask);
08348          } else if (!strcasecmp(v->name, "context")) {
08349             if (ast_strlen_zero(peer->context))
08350                ast_copy_string(peer->context, v->value, sizeof(peer->context));
08351          } else if (!strcasecmp(v->name, "regexten")) {
08352             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
08353          } else if (!strcasecmp(v->name, "peercontext")) {
08354             if (ast_strlen_zero(peer->peercontext))
08355                ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext));
08356          } else if (!strcasecmp(v->name, "port")) {
08357             if (ast_test_flag(peer, IAX_DYNAMIC))
08358                peer->defaddr.sin_port = htons(atoi(v->value));
08359             else
08360                peer->addr.sin_port = htons(atoi(v->value));
08361          } else if (!strcasecmp(v->name, "username")) {
08362             ast_copy_string(peer->username, v->value, sizeof(peer->username));
08363          } else if (!strcasecmp(v->name, "allow")) {
08364             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08365          } else if (!strcasecmp(v->name, "disallow")) {
08366             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08367          } else if (!strcasecmp(v->name, "callerid")) {
08368             ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name),
08369                            peer->cid_num, sizeof(peer->cid_num));
08370             ast_set_flag(peer, IAX_HASCALLERID);   
08371          } else if (!strcasecmp(v->name, "sendani")) {
08372             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08373          } else if (!strcasecmp(v->name, "inkeys")) {
08374             ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys));
08375          } else if (!strcasecmp(v->name, "outkey")) {
08376             ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
08377          } else if (!strcasecmp(v->name, "qualify")) {
08378             if (!strcasecmp(v->value, "no")) {
08379                peer->maxms = 0;
08380             } else if (!strcasecmp(v->value, "yes")) {
08381                peer->maxms = DEFAULT_MAXMS;
08382             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08383                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);
08384                peer->maxms = 0;
08385             }
08386          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08387             peer->smoothing = ast_true(v->value);
08388          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08389             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08390                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);
08391             }
08392          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08393             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08394                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);
08395             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08396          } else if (!strcasecmp(v->name, "timezone")) {
08397             ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag));
08398          }/* else if (strcasecmp(v->name,"type")) */
08399          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08400          v=v->next;
08401       }
08402       if (!peer->authmethods)
08403          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08404       ast_clear_flag(peer, IAX_DELME); 
08405       /* Make sure these are IPv4 addresses */
08406       peer->addr.sin_family = AF_INET;
08407    }
08408    if (oldha)
08409       ast_free_ha(oldha);
08410    return peer;
08411 }

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

Definition at line 8414 of file chan_iax2.c.

References ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), build_context(), format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_capability, iax2_encryption, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRUNK, IAX_USEJITTERBUF, language, ast_variable::lineno, ast_user_list::lock, LOG_WARNING, malloc, maxauthreq, ast_variable::name, ast_variable::next, iax2_user::next, prefs, timingfd, user, userl, ast_user_list::users, and ast_variable::value.

08415 {
08416    struct iax2_user *prev, *user;
08417    struct iax2_context *con, *conl = NULL;
08418    struct ast_ha *oldha = NULL;
08419    struct iax2_context *oldcon = NULL;
08420    int format;
08421    int oldcurauthreq = 0;
08422    char *varname = NULL, *varval = NULL;
08423    struct ast_variable *tmpvar = NULL;
08424    
08425    prev = NULL;
08426    ast_mutex_lock(&userl.lock);
08427    if (!temponly) {
08428       user = userl.users;
08429       while(user) {
08430          if (!strcmp(user->name, name)) { 
08431             break;
08432          }
08433          prev = user;
08434          user = user->next;
08435       }
08436    } else
08437       user = NULL;
08438    
08439    if (user) {
08440       oldcurauthreq = user->curauthreq;
08441       oldha = user->ha;
08442       oldcon = user->contexts;
08443       user->ha = NULL;
08444       user->contexts = NULL;
08445       /* Already in the list, remove it and it will be added back (or FREE'd) */
08446       if (prev) {
08447          prev->next = user->next;
08448       } else {
08449          userl.users = user->next;
08450       }
08451       ast_mutex_unlock(&userl.lock);
08452    } else {
08453       ast_mutex_unlock(&userl.lock);
08454       user = malloc(sizeof(struct iax2_user));
08455       if (user)
08456          memset(user, 0, sizeof(struct iax2_user));
08457    }
08458    
08459    if (user) {
08460       memset(user, 0, sizeof(struct iax2_user));
08461       user->maxauthreq = maxauthreq;
08462       user->curauthreq = oldcurauthreq;
08463       user->prefs = prefs;
08464       user->capability = iax2_capability;
08465       user->encmethods = iax2_encryption;
08466       ast_copy_string(user->name, name, sizeof(user->name));
08467       ast_copy_string(user->language, language, sizeof(user->language));
08468       ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
08469       while(v) {
08470          if (!strcasecmp(v->name, "context")) {
08471             con = build_context(v->value);
08472             if (con) {
08473                if (conl)
08474                   conl->next = con;
08475                else
08476                   user->contexts = con;
08477                conl = con;
08478             }
08479          } else if (!strcasecmp(v->name, "permit") ||
08480                   !strcasecmp(v->name, "deny")) {
08481             user->ha = ast_append_ha(v->name, v->value, user->ha);
08482          } else if (!strcasecmp(v->name, "setvar")) {
08483             varname = ast_strdupa(v->value);
08484             if (varname && (varval = strchr(varname,'='))) {
08485                *varval = '\0';
08486                varval++;
08487                if((tmpvar = ast_variable_new(varname, varval))) {
08488                   tmpvar->next = user->vars; 
08489                   user->vars = tmpvar;
08490                }
08491             }
08492          } else if (!strcasecmp(v->name, "allow")) {
08493             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08494          } else if (!strcasecmp(v->name, "disallow")) {
08495             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08496          } else if (!strcasecmp(v->name, "trunk")) {
08497             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
08498             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08499                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08500                ast_clear_flag(user, IAX_TRUNK);
08501             }
08502          } else if (!strcasecmp(v->name, "auth")) {
08503             user->authmethods = get_auth_methods(v->value);
08504          } else if (!strcasecmp(v->name, "encryption")) {
08505             user->encmethods = get_encrypt_methods(v->value);
08506          } else if (!strcasecmp(v->name, "notransfer")) {
08507             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
08508          } else if (!strcasecmp(v->name, "codecpriority")) {
08509             if(!strcasecmp(v->value, "caller"))
08510                ast_set_flag(user, IAX_CODEC_USER_FIRST);
08511             else if(!strcasecmp(v->value, "disabled"))
08512                ast_set_flag(user, IAX_CODEC_NOPREFS);
08513             else if(!strcasecmp(v->value, "reqonly")) {
08514                ast_set_flag(user, IAX_CODEC_NOCAP);
08515                ast_set_flag(user, IAX_CODEC_NOPREFS);
08516             }
08517          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08518             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);  
08519          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08520             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);   
08521          } else if (!strcasecmp(v->name, "dbsecret")) {
08522             ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret));
08523          } else if (!strcasecmp(v->name, "secret")) {
08524             if (!ast_strlen_zero(user->secret)) {
08525                strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
08526                strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1);
08527             } else
08528                ast_copy_string(user->secret, v->value, sizeof(user->secret));
08529          } else if (!strcasecmp(v->name, "callerid")) {
08530             ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
08531             ast_set_flag(user, IAX_HASCALLERID);   
08532          } else if (!strcasecmp(v->name, "accountcode")) {
08533             ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
08534          } else if (!strcasecmp(v->name, "language")) {
08535             ast_copy_string(user->language, v->value, sizeof(user->language));
08536          } else if (!strcasecmp(v->name, "amaflags")) {
08537             format = ast_cdr_amaflags2int(v->value);
08538             if (format < 0) {
08539                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08540             } else {
08541                user->amaflags = format;
08542             }
08543          } else if (!strcasecmp(v->name, "inkeys")) {
08544             ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
08545          } else if (!strcasecmp(v->name, "maxauthreq")) {
08546             user->maxauthreq = atoi(v->value);
08547             if (user->maxauthreq < 0)
08548                user->maxauthreq = 0;
08549          }/* else if (strcasecmp(v->name,"type")) */
08550          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08551          v = v->next;
08552       }
08553       if (!user->authmethods) {
08554          if (!ast_strlen_zero(user->secret)) {
08555             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08556             if (!ast_strlen_zero(user->inkeys))
08557                user->authmethods |= IAX_AUTH_RSA;
08558          } else if (!ast_strlen_zero(user->inkeys)) {
08559             user->authmethods = IAX_AUTH_RSA;
08560          } else {
08561             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08562          }
08563       }
08564       ast_clear_flag(user, IAX_DELME);
08565    }
08566    if (oldha)
08567       ast_free_ha(oldha);
08568    if (oldcon)
08569       free_context(oldcon);
08570    return user;
08571 }

static int cache_get_callno_locked const char *  data  )  [static]
 

Definition at line 9001 of file chan_iax2.c.

References ast_mutex_trylock(), ast_mutex_unlock(), IAX_MAX_CALLS, and iaxsl.

Referenced by find_cache().

09002 {
09003    struct sockaddr_in sin;
09004    int x;
09005    int callno;
09006    struct iax_ie_data ied;
09007    struct create_addr_info cai;
09008    struct parsed_dial_string pds;
09009    char *tmpstr;
09010 
09011    for (x=0; x<IAX_MAX_CALLS; x++) {
09012       /* Look for an *exact match* call.  Once a call is negotiated, it can only
09013          look up entries for a single context */
09014       if (!ast_mutex_trylock(&iaxsl[x])) {
09015          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
09016             return x;
09017          ast_mutex_unlock(&iaxsl[x]);
09018       }
09019    }
09020 
09021    /* No match found, we need to create a new one */
09022 
09023    memset(&cai, 0, sizeof(cai));
09024    memset(&ied, 0, sizeof(ied));
09025    memset(&pds, 0, sizeof(pds));
09026 
09027    tmpstr = ast_strdupa(data);
09028    parse_dial_string(tmpstr, &pds);
09029 
09030    /* Populate our address from the given */
09031    if (create_addr(pds.peer, &sin, &cai))
09032       return -1;
09033 
09034    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09035       pds.peer, pds.username, pds.password, pds.context);
09036 
09037    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
09038    if (callno < 1) {
09039       ast_log(LOG_WARNING, "Unable to create call\n");
09040       return -1;
09041    }
09042 
09043    ast_mutex_lock(&iaxsl[callno]);
09044    ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot));
09045    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09046 
09047    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09048    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09049    /* the string format is slightly different from a standard dial string,
09050       because the context appears in the 'exten' position
09051    */
09052    if (pds.exten)
09053       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09054    if (pds.username)
09055       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09056    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09057    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09058    /* Keep password handy */
09059    if (pds.password)
09060       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
09061    if (pds.key)
09062       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
09063    /* Start the call going */
09064    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09065 
09066    return callno;
09067 }

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

Definition at line 3678 of file chan_iax2.c.

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

03679 {
03680    /* Returns where in "receive time" we are.  That is, how many ms
03681       since we received (or would have received) the frame with timestamp 0 */
03682    int ms;
03683 #ifdef IAXTESTS
03684    int jit;
03685 #endif /* IAXTESTS */
03686    /* Setup rxcore if necessary */
03687    if (ast_tvzero(p->rxcore)) {
03688       p->rxcore = ast_tvnow();
03689       if (option_debug && iaxdebug)
03690          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03691                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03692       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03693 #if 1
03694       if (option_debug && iaxdebug)
03695          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03696                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03697 #endif
03698    }
03699 
03700    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03701 #ifdef IAXTESTS
03702    if (test_jit) {
03703       if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) {
03704          jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0));
03705          if ((int)(2.0 * rand() / (RAND_MAX + 1.0)))
03706             jit = -jit;
03707          ms += jit;
03708       }
03709    }
03710    if (test_late) {
03711       ms += test_late;
03712       test_late = 0;
03713    }
03714 #endif /* IAXTESTS */
03715    return ms;
03716 }

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

Definition at line 3534 of file chan_iax2.c.

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

Referenced by iax2_send(), and socket_read().

03535 {
03536    int ms;
03537    int voice = 0;
03538    int genuine = 0;
03539    int adjust;
03540    struct timeval *delivery = NULL;
03541 
03542 
03543    /* What sort of frame do we have?: voice is self-explanatory
03544       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03545       non-genuine frames are CONTROL frames [ringing etc], DTMF
03546       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03547       the others need a timestamp slaved to the voice frames so that they go in sequence
03548    */
03549    if (f) {
03550       if (f->frametype == AST_FRAME_VOICE) {
03551          voice = 1;
03552          delivery = &f->delivery;
03553       } else if (f->frametype == AST_FRAME_IAX) {
03554          genuine = 1;
03555       } else if (f->frametype == AST_FRAME_CNG) {
03556          p->notsilenttx = 0;  
03557       }
03558    }
03559    if (ast_tvzero(p->offset)) {
03560       gettimeofday(&p->offset, NULL);
03561       /* Round to nearest 20ms for nice looking traces */
03562       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03563    }
03564    /* If the timestamp is specified, just send it as is */
03565    if (ts)
03566       return ts;
03567    /* If we have a time that the frame arrived, always use it to make our timestamp */
03568    if (delivery && !ast_tvzero(*delivery)) {
03569       ms = ast_tvdiff_ms(*delivery, p->offset);
03570       if (option_debug > 2 && iaxdebug)
03571          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03572    } else {
03573       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03574       if (ms < 0)
03575          ms = 0;
03576       if (voice) {
03577          /* On a voice frame, use predicted values if appropriate */
03578          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03579             /* Adjust our txcore, keeping voice and non-voice synchronized */
03580             /* AN EXPLANATION:
03581                When we send voice, we usually send "calculated" timestamps worked out
03582                on the basis of the number of samples sent. When we send other frames,
03583                we usually send timestamps worked out from the real clock.
03584                The problem is that they can tend to drift out of step because the 
03585                   source channel's clock and our clock may not be exactly at the same rate.
03586                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03587                for this call.  Moving it adjusts timestamps for non-voice frames.
03588                We make the adjustment in the style of a moving average.  Each time we
03589                adjust p->offset by 10% of the difference between our clock-derived
03590                timestamp and the predicted timestamp.  That's why you see "10000"
03591                below even though IAX2 timestamps are in milliseconds.
03592                The use of a moving average avoids offset moving too radically.
03593                Generally, "adjust" roams back and forth around 0, with offset hardly
03594                changing at all.  But if a consistent different starts to develop it
03595                will be eliminated over the course of 10 frames (200-300msecs) 
03596             */
03597             adjust = (ms - p->nextpred);
03598             if (adjust < 0)
03599                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03600             else if (adjust > 0)
03601                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03602 
03603             if (!p->nextpred) {
03604                p->nextpred = ms; /*f->samples / 8;*/
03605                if (p->nextpred <= p->lastsent)
03606                   p->nextpred = p->lastsent + 3;
03607             }
03608             ms = p->nextpred;
03609          } else {
03610                 /* in this case, just use the actual
03611             * time, since we're either way off
03612             * (shouldn't happen), or we're  ending a
03613             * silent period -- and seed the next
03614             * predicted time.  Also, round ms to the
03615             * next multiple of frame size (so our
03616             * silent periods are multiples of
03617             * frame size too) */
03618 
03619             if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03620                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03621                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03622 
03623             if (f->samples >= 8) /* check to make sure we dont core dump */
03624             {
03625                int diff = ms % (f->samples / 8);
03626                if (diff)
03627                    ms += f->samples/8 - diff;
03628             }
03629 
03630             p->nextpred = ms;
03631             p->notsilenttx = 1;
03632          }
03633       } else {
03634          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03635             it's a genuine frame */
03636          if (genuine) {
03637             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03638             if (ms <= p->lastsent)
03639                ms = p->lastsent + 3;
03640          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03641             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03642             ms = p->lastsent + 3;
03643          }
03644       }
03645    }
03646    p->lastsent = ms;
03647    if (voice)
03648       p->nextpred = p->nextpred + f->samples / 8;
03649    return ms;
03650 }

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

Definition at line 3490 of file chan_iax2.c.

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

Referenced by send_trunk().

03491 {
03492    unsigned long int mssincetx; /* unsigned to handle overflows */
03493    long int ms, pred;
03494 
03495    tpeer->trunkact = *tv;
03496    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03497    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03498       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03499       tpeer->txtrunktime = *tv;
03500       tpeer->lastsent = 999999;
03501    }
03502    /* Update last transmit time now */
03503    tpeer->lasttxtime = *tv;
03504    
03505    /* Calculate ms offset */
03506    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03507    /* Predict from last value */
03508    pred = tpeer->lastsent + sampms;
03509    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03510       ms = pred;
03511    
03512    /* We never send the same timestamp twice, so fudge a little if we must */
03513    if (ms == tpeer->lastsent)
03514       ms = tpeer->lastsent + 1;
03515    tpeer->lastsent = ms;
03516    return ms;
03517 }

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

Definition at line 4744 of file chan_iax2.c.

References accountcode, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_variable_new(), cid_name, cid_num, context, destroy_user(), exten, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, ies, key(), language, ast_user_list::lock, LOG_WARNING, ast_variable::name, ast_variable::next, prefs, realtime_user(), secret, user, userl, username, ast_user_list::users, and ast_variable::value.

Referenced by socket_read().

04745 {
04746    /* Start pessimistic */
04747    int res = -1;
04748    int version = 2;
04749    struct iax2_user *user, *best = NULL;
04750    int bestscore = 0;
04751    int gotcapability = 0;
04752    char iabuf[INET_ADDRSTRLEN];
04753    struct ast_variable *v = NULL, *tmpvar = NULL;
04754 
04755    if (!iaxs[callno])
04756       return res;
04757    if (ies->called_number)
04758       ast_copy_string(iaxs[callno]->exten, ies->called_number, sizeof(iaxs[callno]->exten));
04759    if (ies->calling_number) {
04760       ast_shrink_phone_number(ies->calling_number);
04761       ast_copy_string(iaxs[callno]->cid_num, ies->calling_number, sizeof(iaxs[callno]->cid_num));
04762    }
04763    if (ies->calling_name)
04764       ast_copy_string(iaxs[callno]->cid_name, ies->calling_name, sizeof(iaxs[callno]->cid_name));
04765    if (ies->calling_ani)
04766       ast_copy_string(iaxs[callno]->ani, ies->calling_ani, sizeof(iaxs[callno]->ani));
04767    if (ies->dnid)
04768       ast_copy_string(iaxs[callno]->dnid, ies->dnid, sizeof(iaxs[callno]->dnid));
04769    if (ies->called_context)
04770       ast_copy_string(iaxs[callno]->context, ies->called_context, sizeof(iaxs[callno]->context));
04771    if (ies->language)
04772       ast_copy_string(iaxs[callno]->language, ies->language, sizeof(iaxs[callno]->language));
04773    if (ies->username)
04774       ast_copy_string(iaxs[callno]->username, ies->username, sizeof(iaxs[callno]->username));
04775    if (ies->calling_ton > -1)
04776       iaxs[callno]->calling_ton = ies->calling_ton;
04777    if (ies->calling_tns > -1)
04778       iaxs[callno]->calling_tns = ies->calling_tns;
04779    if (ies->calling_pres > -1)
04780       iaxs[callno]->calling_pres = ies->calling_pres;
04781    if (ies->format)
04782       iaxs[callno]->peerformat = ies->format;
04783    if (ies->adsicpe)
04784       iaxs[callno]->peeradsicpe = ies->adsicpe;
04785    if (ies->capability) {
04786       gotcapability = 1;
04787       iaxs[callno]->peercapability = ies->capability;
04788    } 
04789    if (ies->version)
04790       version = ies->version;
04791 
04792    /* Use provided preferences until told otherwise for actual preferences */
04793    if(ies->codec_prefs) {
04794       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04795       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04796    }
04797 
04798    if (!gotcapability) 
04799       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04800    if (version > IAX_PROTO_VERSION) {
04801       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
04802          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), version);
04803       return res;
04804    }
04805    ast_mutex_lock(&userl.lock);
04806    /* Search the userlist for a compatible entry, and fill in the rest */
04807    user = userl.users;
04808    while(user) {
04809       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
04810          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
04811          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
04812          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
04813               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
04814          if (!ast_strlen_zero(iaxs[callno]->username)) {
04815             /* Exact match, stop right now. */
04816             best = user;
04817             break;
04818          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04819             /* No required authentication */
04820             if (user->ha) {
04821                /* There was host authentication and we passed, bonus! */
04822                if (bestscore < 4) {
04823                   bestscore = 4;
04824                   best = user;
04825                }
04826             } else {
04827                /* No host access, but no secret, either, not bad */
04828                if (bestscore < 3) {
04829                   bestscore = 3;
04830                   best = user;
04831                }
04832             }
04833          } else {
04834             if (user->ha) {
04835                /* Authentication, but host access too, eh, it's something.. */
04836                if (bestscore < 2) {
04837                   bestscore = 2;
04838                   best = user;
04839                }
04840             } else {
04841                /* Authentication and no host access...  This is our baseline */
04842                if (bestscore < 1) {
04843                   bestscore = 1;
04844                   best = user;
04845                }
04846             }
04847          }
04848       }
04849       user = user->next;   
04850    }
04851    ast_mutex_unlock(&userl.lock);
04852    user = best;
04853    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
04854       user = realtime_user(iaxs[callno]->username);
04855       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
04856           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
04857          destroy_user(user);
04858          user = NULL;
04859       }
04860    }
04861    if (user) {
04862       /* We found our match (use the first) */
04863       /* copy vars */
04864       for (v = user->vars ; v ; v = v->next) {
04865          if((tmpvar = ast_variable_new(v->name, v->value))) {
04866             tmpvar->next = iaxs[callno]->vars; 
04867             iaxs[callno]->vars = tmpvar;
04868          }
04869       }
04870       /* If a max AUTHREQ restriction is in place, activate it */
04871       if (user->maxauthreq > 0)
04872          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
04873       iaxs[callno]->prefs = user->prefs;
04874       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
04875       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
04876       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
04877       iaxs[callno]->encmethods = user->encmethods;
04878       /* Store the requested username if not specified */
04879       if (ast_strlen_zero(iaxs[callno]->username))
04880          ast_copy_string(iaxs[callno]->username, user->name, sizeof(iaxs[callno]->username));
04881       /* Store whether this is a trunked call, too, of course, and move if appropriate */
04882       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
04883       iaxs[callno]->capability = user->capability;
04884       /* And use the default context */
04885       if (ast_strlen_zero(iaxs[callno]->context)) {
04886          if (user->contexts)
04887             ast_copy_string(iaxs[callno]->context, user->contexts->context, sizeof(iaxs[callno]->context));
04888          else
04889             ast_copy_string(iaxs[callno]->context, context, sizeof(iaxs[callno]->context));
04890       }
04891       /* And any input keys */
04892       ast_copy_string(iaxs[callno]->inkeys, user->inkeys, sizeof(iaxs[callno]->inkeys));
04893       /* And the permitted authentication methods */
04894       iaxs[callno]->authmethods = user->authmethods;
04895       /* If they have callerid, override the given caller id.  Always store the ANI */
04896       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
04897          if (ast_test_flag(user, IAX_HASCALLERID)) {
04898             iaxs[callno]->calling_tns = 0;
04899             iaxs[callno]->calling_ton = 0;
04900             ast_copy_string(iaxs[callno]->cid_num, user->cid_num, sizeof(iaxs[callno]->cid_num));
04901             ast_copy_string(iaxs[callno]->cid_name, user->cid_name, sizeof(iaxs[callno]->cid_name));
04902             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
04903          }
04904          if (ast_strlen_zero(iaxs[callno]->ani))
04905             ast_copy_string(iaxs[callno]->ani, user->cid_num, sizeof(iaxs[callno]->ani));
04906       } else {
04907          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
04908       }
04909       if (!ast_strlen_zero(user->accountcode))
04910          ast_copy_string(iaxs[callno]->accountcode, user->accountcode, sizeof(iaxs[callno]->accountcode));
04911       if (user->amaflags)
04912          iaxs[callno]->amaflags = user->amaflags;
04913       if (!ast_strlen_zero(user->language))
04914          ast_copy_string(iaxs[callno]->language, user->language, sizeof(iaxs[callno]->language));
04915       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);  
04916       /* Keep this check last */
04917       if (!ast_strlen_zero(user->dbsecret)) {
04918          char *family, *key=NULL;
04919          family = ast_strdupa(user->dbsecret);
04920          if (family) {
04921             key = strchr(family, '/');
04922             if (key) {
04923                *key = '\0';
04924                key++;
04925             }
04926          }
04927          if (!family || !key || ast_db_get(family, key, iaxs[callno]->secret, sizeof(iaxs[callno]->secret))) {
04928             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
04929             if (ast_test_flag(user, IAX_TEMPONLY)) {
04930                destroy_user(user);
04931                user = NULL;
04932             }
04933          }
04934       } else
04935          ast_copy_string(iaxs[callno]->secret, user->secret, sizeof(iaxs[callno]->secret)); 
04936       res = 0;
04937    }
04938    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
04939    return res;
04940 }

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

Definition at line 6304 of file chan_iax2.c.

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

Referenced by socket_read().

06305 {
06306    unsigned int ourver;
06307    char rsi[80];
06308    snprintf(rsi, sizeof(rsi), "si-%s", si);
06309    if (iax_provision_version(&ourver, rsi, 1))
06310       return 0;
06311    if (option_debug)
06312       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06313    if (ourver != ver) 
06314       iax2_provision(sin, sockfd, NULL, rsi, 1);
06315    return 0;
06316 }

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

Definition at line 8142 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

Referenced by peer_set_srcaddr().

08143 {
08144    int sd;
08145    int res;
08146    
08147    sd = socket(AF_INET, SOCK_DGRAM, 0);
08148    if (sd < 0) {
08149       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08150       return -1;
08151    }
08152 
08153    res = bind(sd, sa, salen);
08154    if (res < 0) {
08155       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08156       close(sd);
08157       return 1;
08158    }
08159 
08160    close(sd);
08161    return 0;
08162 }

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

Definition at line 5404 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iaxdefaultdpcache, ies, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.

Referenced by socket_read().

05405 {
05406    char exten[256] = "";
05407    int status = CACHE_FLAG_UNKNOWN;
05408    int expiry = iaxdefaultdpcache;
05409    int x;
05410    int matchmore = 0;
05411    struct iax2_dpcache *dp, *prev;
05412    
05413    if (ies->called_number)
05414       ast_copy_string(exten, ies->called_number, sizeof(exten));
05415 
05416    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05417       status = CACHE_FLAG_EXISTS;
05418    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05419       status = CACHE_FLAG_CANEXIST;
05420    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05421       status = CACHE_FLAG_NONEXISTENT;
05422 
05423    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05424       /* Don't really do anything with this */
05425    }
05426    if (ies->refresh)
05427       expiry = ies->refresh;
05428    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05429       matchmore = CACHE_FLAG_MATCHMORE;
05430    ast_mutex_lock(&dpcache_lock);
05431    prev = NULL;
05432    dp = pvt->dpentries;
05433    while(dp) {
05434       if (!strcmp(dp->exten, exten)) {
05435          /* Let them go */
05436          if (prev)
05437             prev->peer = dp->peer;
05438          else
05439             pvt->dpentries = dp->peer;
05440          dp->peer = NULL;
05441          dp->callno = 0;
05442          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05443          if (dp->flags & CACHE_FLAG_PENDING) {
05444             dp->flags &= ~CACHE_FLAG_PENDING;
05445             dp->flags |= status;
05446             dp->flags |= matchmore;
05447          }
05448          /* Wake up waiters */
05449          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05450             if (dp->waiters[x] > -1)
05451                write(dp->waiters[x], "asdf", 4);
05452       }
05453       prev = dp;
05454       dp = dp->peer;
05455    }
05456    ast_mutex_unlock(&dpcache_lock);
05457    return 0;
05458 }

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

Definition at line 2016 of file chan_iax2.c.

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

02017 {
02018    int which = 0;
02019    struct iax2_peer *p;
02020    char *res = NULL;
02021 
02022    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02023    if(pos == 3) {
02024       ast_mutex_lock(&peerl.lock);
02025       for(p = peerl.peers ; p ; p = p->next) {
02026          if(!strncasecmp(p->name, word, strlen(word))) {
02027             if(++which > state) {
02028                res = strdup(p->name);
02029                break;
02030             }
02031          }
02032       }
02033       ast_mutex_unlock(&peerl.lock);
02034    }
02035 
02036    return res;
02037 }

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

Definition at line 5460 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, jb_frame::data, DEFAULT_RETRY_TIME, ast_iax2_queue::head, iax2_frame_free(), iaxq, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.

Referenced by socket_read().

05461 {
05462    int peercallno = 0;
05463    struct chan_iax2_pvt *pvt = iaxs[callno];
05464    struct iax_frame *cur;
05465 
05466    if (ies->callno)
05467       peercallno = ies->callno;
05468 
05469    if (peercallno < 1) {
05470       ast_log(LOG_WARNING, "Invalid transfer request\n");
05471       return -1;
05472    }
05473    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05474    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05475    /* Reset sequence numbers */
05476    pvt->oseqno = 0;
05477    pvt->rseqno = 0;
05478    pvt->iseqno = 0;
05479    pvt->aseqno = 0;
05480    pvt->peercallno = peercallno;
05481    pvt->transferring = TRANSFER_NONE;
05482    pvt->svoiceformat = -1;
05483    pvt->voiceformat = 0;
05484    pvt->svideoformat = -1;
05485    pvt->videoformat = 0;
05486    pvt->transfercallno = -1;
05487    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05488    memset(&pvt->offset, 0, sizeof(pvt->offset));
05489 #ifdef NEWJB
05490    {  /* reset jitterbuffer */
05491          jb_frame frame;
05492                while(jb_getall(pvt->jb,&frame) == JB_OK)
05493                   iax2_frame_free(frame.data);
05494 
05495       jb_reset(pvt->jb);
05496    }
05497 #else
05498    memset(&pvt->history, 0, sizeof(pvt->history));
05499    pvt->jitterbuffer = 0;
05500    pvt->jitter = 0;
05501    pvt->historicjitter = 0;
05502 #endif
05503    pvt->lag = 0;
05504    pvt->last = 0;
05505    pvt->lastsent = 0;
05506    pvt->nextpred = 0;
05507    pvt->pingtime = DEFAULT_RETRY_TIME;
05508    ast_mutex_lock(&iaxq.lock);
05509    for (cur = iaxq.head; cur ; cur = cur->next) {
05510       /* We must cancel any packets that would have been transmitted
05511          because now we're talking to someone new.  It's okay, they
05512          were transmitted to someone that didn't care anyway. */
05513       if (callno == cur->callno) 
05514          cur->retries = -1;
05515    }
05516    ast_mutex_unlock(&iaxq.lock);
05517    return 0; 
05518 }

static unsigned char compress_subclass int  subclass  )  [static]
 

Definition at line 826 of file chan_iax2.c.

References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.

Referenced by iax2_send(), and raw_hangup().

00827 {
00828    int x;
00829    int power=-1;
00830    /* If it's 128 or smaller, just return it */
00831    if (subclass < IAX_FLAG_SC_LOG)
00832       return subclass;
00833    /* Otherwise find its power */
00834    for (x = 0; x < IAX_MAX_SHIFT; x++) {
00835       if (subclass & (1 << x)) {
00836          if (power > -1) {
00837             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
00838             return 0;
00839          } else
00840             power = x;
00841       }
00842    }
00843    return power | IAX_FLAG_SC_LOG;
00844 }

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

Definition at line 6318 of file chan_iax2.c.

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

Referenced by socket_read().

06319 {
06320 #ifdef NEWJB
06321    jb_info stats;
06322    jb_getinfo(pvt->jb, &stats);
06323    
06324    memset(iep, 0, sizeof(*iep));
06325 
06326    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06327    if(stats.frames_in == 0) stats.frames_in = 1;
06328    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06329    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06330    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06331    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06332    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06333 #else
06334    memset(iep, 0, sizeof(*iep));
06335    iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter);
06336    iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received);
06337    if(!ast_test_flag(pvt, IAX_USEJITTERBUF)) 
06338       iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0);
06339    else
06340       iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min);
06341    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped);
06342    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */
06343    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */
06344 #endif
06345 }

static int create_addr const char *  peername,
struct sockaddr_in *  sin,
struct create_addr_info cai
[static]
 

Definition at line 2773 of file chan_iax2.c.

References iax2_peer::addr, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, defaultsockfd, destroy_peer(), iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, key(), iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::outkey, create_addr_info::outkey, iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.

02774 {
02775    struct ast_hostent ahp;
02776    struct hostent *hp;
02777    struct iax2_peer *peer;
02778 
02779    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02780    cai->sockfd = defaultsockfd;
02781    cai->maxtime = 0;
02782    sin->sin_family = AF_INET;
02783 
02784    if (!(peer = find_peer(peername, 1))) {
02785       cai->found = 0;
02786 
02787       hp = ast_gethostbyname(peername, &ahp);
02788       if (hp) {
02789          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02790          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02791          /* use global iax prefs for unknown peer/user */
02792          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02793          return 0;
02794       } else {
02795          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02796          return -1;
02797       }
02798    }
02799 
02800    cai->found = 1;
02801    
02802    /* if the peer has no address (current or default), return failure */
02803    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
02804       if (ast_test_flag(peer, IAX_TEMPONLY))
02805          destroy_peer(peer);
02806       return -1;
02807    }
02808 
02809    /* if the peer is being monitored and is currently unreachable, return failure */
02810    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
02811       if (ast_test_flag(peer, IAX_TEMPONLY))
02812          destroy_peer(peer);
02813       return -1;
02814    }
02815 
02816    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02817    cai->maxtime = peer->maxms;
02818    cai->capability = peer->capability;
02819    cai->encmethods = peer->encmethods;
02820    cai->sockfd = peer->sockfd;
02821    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02822    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02823    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02824    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02825    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02826    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02827    if (ast_strlen_zero(peer->dbsecret)) {
02828       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02829    } else {
02830       char *family;
02831       char *key = NULL;
02832 
02833       family = ast_strdupa(peer->dbsecret);
02834       if (family) {
02835          key = strchr(family, '/');
02836          if (key)
02837             *key++ = '\0';
02838       }
02839       if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02840          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02841          if (ast_test_flag(peer, IAX_TEMPONLY))
02842             destroy_peer(peer);
02843          return -1;
02844       }
02845    }
02846 
02847    if (peer->addr.sin_addr.s_addr) {
02848       sin->sin_addr = peer->addr.sin_addr;
02849       sin->sin_port = peer->addr.sin_port;
02850    } else {
02851       sin->sin_addr = peer->defaddr.sin_addr;
02852       sin->sin_port = peer->defaddr.sin_port;
02853    }
02854 
02855    if (ast_test_flag(peer, IAX_TEMPONLY))
02856       destroy_peer(peer);
02857 
02858    return 0;
02859 }

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

Definition at line 3869 of file chan_iax2.c.

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

Referenced by decrypt_frame().

03870 {
03871    int padding;
03872    unsigned char *workspace;
03873    workspace = alloca(*datalen);
03874    if (!workspace)
03875       return -1;
03876    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03877       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03878       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03879          return -1;
03880       /* Decrypt */
03881       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03882 
03883       padding = 16 + (workspace[15] & 0xf);
03884       if (option_debug && iaxdebug)
03885          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03886       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03887          return -1;
03888 
03889       *datalen -= padding;
03890       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03891       f->frametype = fh->type;
03892       if (f->frametype == AST_FRAME_VIDEO) {
03893          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03894       } else {
03895          f->subclass = uncompress_subclass(fh->csub);
03896       }
03897    } else {
03898       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03899       if (option_debug && iaxdebug)
03900          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03901       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03902          return -1;
03903       /* Decrypt */
03904       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03905       padding = 16 + (workspace[15] & 0x0f);
03906       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03907          return -1;
03908       *datalen -= padding;
03909       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03910    }
03911    return 0;
03912 }

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

Definition at line 3955 of file chan_iax2.c.

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

Referenced by socket_read().

03956 {
03957    int res=-1;
03958    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03959       /* Search for possible keys, given secrets */
03960       struct MD5Context md5;
03961       unsigned char digest[16];
03962       char *tmppw, *stringp;
03963       
03964       tmppw = ast_strdupa(iaxs[callno]->secret);
03965       stringp = tmppw;
03966       while((tmppw = strsep(&stringp, ";"))) {
03967          MD5Init(&md5);
03968          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03969          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03970          MD5Final(digest, &md5);
03971          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03972          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03973          if (!res) {
03974             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03975             break;
03976          }
03977       }
03978    } else 
03979       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03980    return res;
03981 }

static void delete_users void   )  [static]
 

Definition at line 8573 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_set_flag, IAX_DELME, ast_user_list::lock, iax2_registry::next, registrations, regl, user, userl, and ast_user_list::users.

08574 {
08575    struct iax2_user *user;
08576    struct iax2_peer *peer;
08577    struct iax2_registry *reg, *regl;
08578 
08579    ast_mutex_lock(&userl.lock);
08580    for (user=userl.users;user;) {
08581       ast_set_flag(user, IAX_DELME);
08582       user = user->next;
08583    }
08584    ast_mutex_unlock(&userl.lock);
08585    for (reg = registrations;reg;) {
08586       regl = reg;
08587       reg = reg->next;
08588       if (regl->expire > -1) {
08589          ast_sched_del(sched, regl->expire);
08590       }
08591       if (regl->callno) {
08592          /* XXX Is this a potential lock?  I don't think so, but you never know */
08593          ast_mutex_lock(&iaxsl[regl->callno]);
08594          if (iaxs[regl->callno]) {
08595             iaxs[regl->callno]->reg = NULL;
08596             iax2_destroy_nolock(regl->callno);
08597          }
08598          ast_mutex_unlock(&iaxsl[regl->callno]);
08599       }
08600       free(regl);
08601    }
08602    registrations = NULL;
08603    ast_mutex_lock(&peerl.lock);
08604    for (peer=peerl.peers;peer;) {
08605       /* Assume all will be deleted, and we'll find out for sure later */
08606       ast_set_flag(peer, IAX_DELME);
08607       peer = peer->next;
08608    }
08609    ast_mutex_unlock(&peerl.lock);
08610 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 9759 of file chan_iax2.c.

References desc.

09760 {
09761    return (char *) desc;
09762 }

static void destroy_firmware struct iax_firmware cur  )  [static]
 

Definition at line 1158 of file chan_iax2.c.

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

Referenced by reload_firmware().

01159 {
01160    /* Close firmware */
01161    if (cur->fwh) {
01162       munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01163    }
01164    close(cur->fd);
01165    free(cur);
01166 }

static void destroy_peer struct iax2_peer peer  )  [static]
 

Definition at line 8642 of file chan_iax2.c.

References ast_free_ha(), ast_mutex_lock(), iax2_peer::ha, iax2_destroy(), IAX_MAX_CALLS, and iaxsl.

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

08643 {
08644    int x;
08645    ast_free_ha(peer->ha);
08646    for (x=0;x<IAX_MAX_CALLS;x++) {
08647       ast_mutex_lock(&iaxsl[x]);
08648       if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
08649          iax2_destroy(x);
08650       }
08651       ast_mutex_unlock(&iaxsl[x]);
08652    }
08653    /* Delete it, it needs to disappear */
08654    if (peer->expire > -1)
08655       ast_sched_del(sched, peer->expire);
08656    if (peer->pokeexpire > -1)
08657       ast_sched_del(sched, peer->pokeexpire);
08658    if (peer->callno > 0)
08659       iax2_destroy(peer->callno);
08660    register_peer_exten(peer, 0);
08661    if (peer->dnsmgr)
08662       ast_dnsmgr_release(peer->dnsmgr);
08663    free(peer);
08664 }

static void destroy_user struct iax2_user user  )  [static]
 

Definition at line 8612 of file chan_iax2.c.

References ast_free_ha(), ast_variables_destroy(), free, free_context(), and user.

Referenced by check_access(), and prune_users().

08613 {
08614    ast_free_ha(user->ha);
08615    free_context(user->contexts);
08616    if(user->vars) {
08617       ast_variables_destroy(user->vars);
08618       user->vars = NULL;
08619    }
08620    free(user);
08621 }

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

Definition at line 6161 of file chan_iax2.c.

References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxdefaultdpcache, iaxsl, and send_command().

Referenced by dp_lookup_thread(), and socket_read().

06162 {
06163    unsigned short dpstatus = 0;
06164    struct iax_ie_data ied1;
06165    int mm;
06166 
06167    memset(&ied1, 0, sizeof(ied1));
06168    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06169    /* Must be started */
06170    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06171       dpstatus = IAX_DPSTATUS_EXISTS;
06172    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06173       dpstatus = IAX_DPSTATUS_CANEXIST;
06174    } else {
06175       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06176    }
06177    if (ast_ignore_pattern(context, callednum))
06178       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06179    if (mm)
06180       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06181    if (!skiplock)
06182       ast_mutex_lock(&iaxsl[callno]);
06183    if (iaxs[callno]) {
06184       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06185       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06186       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06187       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06188    }
06189    if (!skiplock)
06190       ast_mutex_unlock(&iaxsl[callno]);
06191 }

static void* dp_lookup_thread void *  data  )  [static]
 

Definition at line 6193 of file chan_iax2.c.

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

Referenced by spawn_dp_lookup().

06194 {
06195    /* Look up for dpreq */
06196    struct dpreq_data *dpr = data;
06197    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06198    if (dpr->callerid)
06199       free(dpr->callerid);
06200    free(dpr);
06201    return NULL;
06202 }

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

Definition at line 3914 of file chan_iax2.c.

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

Referenced by iax2_send().

03915 {
03916    int padding;
03917    unsigned char *workspace;
03918    workspace = alloca(*datalen + 32);
03919    if (!workspace)
03920       return -1;
03921    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03922       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03923       if (option_debug && iaxdebug)
03924          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03925       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03926       padding = 16 + (padding & 0xf);
03927       memcpy(workspace, poo, padding);
03928       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03929       workspace[15] &= 0xf0;
03930       workspace[15] |= (padding & 0xf);
03931       if (option_debug && iaxdebug)
03932          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
03933       *datalen += padding;
03934       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03935       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03936          memcpy(poo, workspace + *datalen - 32, 32);
03937    } else {
03938       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03939       if (option_debug && iaxdebug)
03940          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03941       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03942       padding = 16 + (padding & 0xf);
03943       memcpy(workspace, poo, padding);
03944       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03945       workspace[15] &= 0xf0;
03946       workspace[15] |= (padding & 0x0f);
03947       *datalen += padding;
03948       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03949       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03950          memcpy(poo, workspace + *datalen - 32, 32);
03951    }
03952    return 0;
03953 }

static int expire_registry void *  data  )  [static]
 

Definition at line 5655 of file chan_iax2.c.

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

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

05656 {
05657    struct iax2_peer *p = data;
05658 
05659    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05660    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05661       realtime_update_peer(p->name, &p->addr, 0);
05662    /* Reset the address */
05663    memset(&p->addr, 0, sizeof(p->addr));
05664    /* Reset expire notice */
05665    p->expire = -1;
05666    /* Reset expiry value */
05667    p->expiry = min_reg_expire;
05668    if (!ast_test_flag(p, IAX_TEMPONLY))
05669       ast_db_del("IAX/Registry", p->name);
05670    register_peer_exten(p, 0);
05671    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05672    if (iax2_regfunk)
05673       iax2_regfunk(p->name, 0);
05674 
05675    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05676       ast_set_flag(p, IAX_DELME);
05677       prune_peers();
05678    }
05679 
05680    return 0;
05681 }

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

Definition at line 9069 of file chan_iax2.c.

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

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

09070 {
09071    struct iax2_dpcache *dp, *prev = NULL, *next;
09072    struct timeval tv;
09073    int x;
09074    int com[2];
09075    int timeout;
09076    int old=0;
09077    int outfd;
09078    int abort;
09079    int callno;
09080    struct ast_channel *c;
09081    struct ast_frame *f;
09082    gettimeofday(&tv, NULL);
09083    dp = dpcache;
09084    while(dp) {
09085       next = dp->next;
09086       /* Expire old caches */
09087       if (ast_tvcmp(tv, dp->expiry) > 0) {
09088             /* It's expired, let it disappear */
09089             if (prev)
09090                prev->next = dp->next;
09091             else
09092                dpcache = dp->next;
09093             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
09094                /* Free memory and go again */
09095                free(dp);
09096             } else {
09097                ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
09098             }
09099             dp = next;
09100             continue;
09101       }
09102       /* We found an entry that matches us! */
09103       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
09104          break;
09105       prev = dp;
09106       dp = next;
09107    }
09108    if (!dp) {
09109       /* No matching entry.  Create a new one. */
09110       /* First, can we make a callno? */
09111       callno = cache_get_callno_locked(data);
09112       if (callno < 0) {
09113          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
09114          return NULL;
09115       }
09116       dp = malloc(sizeof(struct iax2_dpcache));
09117       if (!dp) {
09118          ast_mutex_unlock(&iaxsl[callno]);
09119          return NULL;
09120       }
09121       memset(dp, 0, sizeof(struct iax2_dpcache));
09122       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
09123       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09124       gettimeofday(&dp->expiry, NULL);
09125       dp->orig = dp->expiry;
09126       /* Expires in 30 mins by default */
09127       dp->expiry.tv_sec += iaxdefaultdpcache;
09128       dp->next = dpcache;
09129       dp->flags = CACHE_FLAG_PENDING;
09130       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09131          dp->waiters[x] = -1;
09132       dpcache = dp;
09133       dp->peer = iaxs[callno]->dpentries;
09134       iaxs[callno]->dpentries = dp;
09135       /* Send the request if we're already up */
09136       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
09137          iax2_dprequest(dp, callno);
09138       ast_mutex_unlock(&iaxsl[callno]);
09139    }
09140    /* By here we must have a dp */
09141    if (dp->flags & CACHE_FLAG_PENDING) {
09142       /* Okay, here it starts to get nasty.  We need a pipe now to wait
09143          for a reply to come back so long as it's pending */
09144       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09145          /* Find an empty slot */
09146          if (dp->waiters[x] < 0)
09147             break;
09148       }
09149       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09150          ast_log(LOG_WARNING, "No more waiter positions available\n");
09151          return NULL;
09152       }
09153       if (pipe(com)) {
09154          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09155          return NULL;
09156       }
09157       dp->waiters[x] = com[1];
09158       /* Okay, now we wait */
09159       timeout = iaxdefaulttimeout * 1000;
09160       /* Temporarily unlock */
09161       ast_mutex_unlock(&dpcache_lock);
09162       /* Defer any dtmf */
09163       if (chan)
09164          old = ast_channel_defer_dtmf(chan);
09165       abort = 0;
09166       while(timeout) {
09167          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09168          if (outfd > -1) {
09169             break;
09170          }
09171          if (c) {
09172             f = ast_read(c);
09173             if (f)
09174                ast_frfree(f);
09175             else {
09176                /* Got hung up on, abort! */
09177                break;
09178                abort = 1;
09179             }
09180          }
09181       }
09182       if (!timeout) {
09183          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09184       }
09185       ast_mutex_lock(&dpcache_lock);
09186       dp->waiters[x] = -1;
09187       close(com[1]);
09188       close(com[0]);
09189       if (abort) {
09190          /* Don't interpret anything, just abort.  Not sure what th epoint
09191            of undeferring dtmf on a hung up channel is but hey whatever */
09192          if (!old && chan)
09193             ast_channel_undefer_dtmf(chan);
09194          return NULL;
09195       }
09196       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09197          /* Now to do non-independent analysis the results of our wait */
09198          if (dp->flags & CACHE_FLAG_PENDING) {
09199             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
09200                pending.  Don't let it take as long to timeout. */
09201             dp->flags &= ~CACHE_FLAG_PENDING;
09202             dp->flags |= CACHE_FLAG_TIMEOUT;
09203             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
09204                systems without leaving it unavailable once the server comes back online */
09205             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09206             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09207                if (dp->waiters[x] > -1)
09208                   write(dp->waiters[x], "asdf", 4);
09209          }
09210       }
09211       /* Our caller will obtain the rest */
09212       if (!old && chan)
09213          ast_channel_undefer_dtmf(chan);
09214    }
09215    return dp;  
09216 }

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

Definition at line 1056 of file chan_iax2.c.

References ast_mutex_lock(), host, iaxs, iaxsl, match(), maxnontrunkcall, and NEW_ALLOW.

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

01057 {
01058    int res = 0;
01059    int x;
01060    struct timeval now;
01061    char iabuf[INET_ADDRSTRLEN];
01062    char host[80];
01063    if (new <= NEW_ALLOW) {
01064       /* Look for an existing connection first */
01065       for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
01066          ast_mutex_lock(&iaxsl[x]);
01067          if (iaxs[x]) {
01068             /* Look for an exact match */
01069             if (match(sin, callno, dcallno, iaxs[x])) {
01070                res = x;
01071             }
01072          }
01073          ast_mutex_unlock(&iaxsl[x]);
01074       }
01075       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
01076          ast_mutex_lock(&iaxsl[x]);
01077          if (iaxs[x]) {
01078             /* Look for an exact match */
01079             if (match(sin, callno, dcallno, iaxs[x])) {
01080                res = x;
01081             }
01082          }
01083          ast_mutex_unlock(&iaxsl[x]);
01084       }
01085    }
01086    if ((res < 1) && (new >= NEW_ALLOW)) {
01087       if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer))
01088          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
01089       gettimeofday(&now, NULL);
01090       for (x=1;x<TRUNK_CALL_START;x++) {
01091          /* Find first unused call number that hasn't been used in a while */
01092          ast_mutex_lock(&iaxsl[x]);
01093          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
01094          ast_mutex_unlock(&iaxsl[x]);
01095       }
01096       /* We've still got lock held if we found a spot */
01097       if (x >= TRUNK_CALL_START) {
01098          ast_log(LOG_WARNING, "No more space\n");
01099          return 0;
01100       }
01101       iaxs[x] = new_iax(sin, lockpeer, host);
01102       update_max_nontrunk();
01103       if (iaxs[x]) {
01104          if (option_debug && iaxdebug)
01105             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01106          iaxs[x]->sockfd = sockfd;
01107          iaxs[x]->addr.sin_port = sin->sin_port;
01108          iaxs[x]->addr.sin_family = sin->sin_family;
01109          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01110          iaxs[x]->peercallno = callno;
01111          iaxs[x]->callno = x;
01112          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01113          iaxs[x]->expiry = min_reg_expire;
01114          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01115          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01116          iaxs[x]->amaflags = amaflags;
01117          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
01118          ast_copy_string(iaxs[x]->accountcode, accountcode, sizeof(iaxs[x]->accountcode));
01119       } else {
01120          ast_log(LOG_WARNING, "Out of resources\n");
01121          ast_mutex_unlock(&iaxsl[x]);
01122          return 0;
01123       }
01124       ast_mutex_unlock(&iaxsl[x]);
01125       res = x;
01126    }
01127    return res;
01128 }

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

Definition at line 860 of file chan_iax2.c.

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

00861 {
00862    struct iax2_peer *peer;
00863    ast_mutex_lock(&peerl.lock);
00864    for(peer = peerl.peers; peer; peer = peer->next) {
00865       if (!strcasecmp(peer->name, name)) {
00866          break;
00867       }
00868    }
00869    ast_mutex_unlock(&peerl.lock);
00870    if(!peer && realtime)
00871       peer = realtime_peer(name, NULL);
00872    return peer;
00873 }

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

Definition at line 3718 of file chan_iax2.c.

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

Referenced by iax2_trunk_queue(), and socket_read().

03719 {
03720    struct iax2_trunk_peer *tpeer;
03721    char iabuf[INET_ADDRSTRLEN];
03722    /* Finds and locks trunk peer */
03723    ast_mutex_lock(&tpeerlock);
03724    tpeer = tpeers;
03725    while(tpeer) {
03726       /* We don't lock here because tpeer->addr *never* changes */
03727       if (!inaddrcmp(&tpeer->addr, sin)) {
03728          ast_mutex_lock(&tpeer->lock);
03729          break;
03730       }
03731       tpeer = tpeer->next;
03732    }
03733    if (!tpeer) {
03734       tpeer = malloc(sizeof(struct iax2_trunk_peer));
03735       if (tpeer) {
03736          memset(tpeer, 0, sizeof(struct iax2_trunk_peer));
03737          ast_mutex_init(&tpeer->lock);
03738          tpeer->lastsent = 9999;
03739          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03740          tpeer->trunkact = ast_tvnow();
03741          ast_mutex_lock(&tpeer->lock);
03742          tpeer->next = tpeers;
03743          tpeer->sockfd = fd;
03744          tpeers = tpeer;
03745 #ifdef SO_NO_CHECK
03746          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03747 #endif
03748          ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03749       }
03750    }
03751    ast_mutex_unlock(&tpeerlock);
03752    return tpeer;
03753 }

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

Definition at line 3519 of file chan_iax2.c.

Referenced by socket_read().

03520 {
03521    long ms; /* NOT unsigned */
03522    if (ast_tvzero(iaxs[callno]->rxcore)) {
03523       /* Initialize rxcore time if appropriate */
03524       gettimeofday(&iaxs[callno]->rxcore, NULL);
03525       /* Round to nearest 20ms so traces look pretty */
03526       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03527    }
03528    /* Calculate difference between trunk and channel */
03529    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03530    /* Return as the sum of trunk time and the difference between trunk and real time */
03531    return ms + ts;
03532 }

static void free_context struct iax2_context con  )  [static]
 

Definition at line 7953 of file chan_iax2.c.

References free, and iax2_context::next.

Referenced by build_user(), and destroy_user().

07954 {
07955    struct iax2_context *conl;
07956    while(con) {
07957       conl = con;
07958       con = con->next;
07959       free(conl);
07960    }
07961 }

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

Definition at line 9341 of file chan_iax2.c.

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

09342 {
09343    char *ret = NULL;
09344    struct iax2_peer *peer;
09345    char *peername, *colname;
09346    char iabuf[INET_ADDRSTRLEN];
09347 
09348    buf[0] = '\0';
09349 
09350    if (chan->tech != &iax2_tech)
09351       return buf;
09352 
09353    if (!(peername = ast_strdupa(data))) {
09354       ast_log(LOG_ERROR, "Memory Error!\n");
09355       return ret;
09356    }
09357 
09358    /* if our channel, return the IP address of the endpoint of current channel */
09359    if (!strcmp(peername,"CURRENTCHANNEL")) {
09360            unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
09361       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
09362       return buf;
09363    }
09364 
09365    if ((colname = strchr(peername, ':'))) {
09366       *colname = '\0';
09367       colname++;
09368    } else {
09369       colname = "ip";
09370    }
09371    if (!(peer = find_peer(peername, 1)))
09372       return ret;
09373 
09374    if (!strcasecmp(colname, "ip")) {
09375       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09376    } else  if (!strcasecmp(colname, "status")) {
09377       peer_status(peer, buf, len); 
09378    } else  if (!strcasecmp(colname, "mailbox")) {
09379       ast_copy_string(buf, peer->mailbox, len);
09380    } else  if (!strcasecmp(colname, "context")) {
09381       ast_copy_string(buf, peer->context, len);
09382    } else  if (!strcasecmp(colname, "expire")) {
09383       snprintf(buf, len, "%d", peer->expire);
09384    } else  if (!strcasecmp(colname, "dynamic")) {
09385       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09386    } else  if (!strcasecmp(colname, "callerid_name")) {
09387       ast_copy_string(buf, peer->cid_name, len);
09388    } else  if (!strcasecmp(colname, "callerid_num")) {
09389       ast_copy_string(buf, peer->cid_num, len);
09390    } else  if (!strcasecmp(colname, "codecs")) {
09391       ast_getformatname_multiple(buf, len -1, peer->capability);
09392    } else  if (!strncasecmp(colname, "codec[", 6)) {
09393       char *codecnum, *ptr;
09394       int index = 0, codec = 0;
09395       
09396       codecnum = strchr(colname, '[');
09397       *codecnum = '\0';
09398       codecnum++;
09399       if ((ptr = strchr(codecnum, ']'))) {
09400          *ptr = '\0';
09401       }
09402       index = atoi(codecnum);
09403       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09404          ast_copy_string(buf, ast_getformatname(codec), len);
09405       }
09406    }
09407    ret = buf;
09408 
09409    return ret;
09410 }

static int get_auth_methods char *  value  )  [static]
 

Definition at line 8123 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

08124 {
08125    int methods = 0;
08126    if (strstr(value, "rsa"))
08127       methods |= IAX_AUTH_RSA;
08128    if (strstr(value, "md5"))
08129       methods |= IAX_AUTH_MD5;
08130    if (strstr(value, "plaintext"))
08131       methods |= IAX_AUTH_PLAINTEXT;
08132    return methods;
08133 }

static int get_encrypt_methods const char *  s  )  [static]
 

Definition at line 800 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

00801 {
00802    int e;
00803    if (!strcasecmp(s, "aes128"))
00804       e = IAX_ENCRYPT_AES128;
00805    else if (ast_true(s))
00806       e = IAX_ENCRYPT_AES128;
00807    else
00808       e = 0;
00809    return e;
00810 }

static int get_from_jb void *  p  )  [static]
 

Definition at line 2207 of file chan_iax2.c.

References __do_deliver(), ast_codec_interp_len(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), chan_iax2_pvt::callno, ast_frame::data, jb_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, 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, iax_frame::next, ast_frame::offset, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by update_jbsched().

02208 {
02209    /* make sure pvt is valid! */ 
02210     struct chan_iax2_pvt *pvt = p;
02211     struct iax_frame *fr;
02212     jb_frame frame;
02213     int ret;
02214     long now;
02215     long next;
02216     struct timeval tv;
02217 
02218     ast_mutex_lock(&iaxsl[pvt->callno]);
02219     pvt->jbid = -1;
02220 
02221     gettimeofday(&tv,NULL);
02222     /* round up a millisecond since ast_sched_runq does; */
02223     /* prevents us from spinning while waiting for our now */
02224     /* to catch up with runq's now */
02225     tv.tv_usec += 1000;
02226 
02227     now = ast_tvdiff_ms(tv, pvt->rxcore);
02228 
02229     if(now >= (next = jb_next(pvt->jb))) {
02230       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02231       switch(ret) {
02232       case JB_OK:
02233          fr = frame.data;
02234          __do_deliver(fr);
02235           break;
02236       case JB_INTERP:
02237           {
02238          struct ast_frame af;
02239    
02240          /* create an interpolation frame */
02241          af.frametype = AST_FRAME_VOICE;
02242          af.subclass = pvt->voiceformat;
02243          af.datalen  = 0;
02244          af.samples  = frame.ms * 8;
02245          af.mallocd  = 0;
02246          af.src  = "IAX2 JB interpolation";
02247          af.data  = NULL;
02248          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02249          af.offset=AST_FRIENDLY_OFFSET;
02250    
02251          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02252           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02253          if (iaxs[pvt->callno] && !ast_test_flag(iaxs[pvt->callno], IAX_ALREADYGONE))
02254             iax2_queue_frame(pvt->callno, &af);
02255           }
02256           break;
02257       case JB_DROP:
02258          iax2_frame_free(frame.data);
02259           break;
02260       case JB_NOFRAME:
02261       case JB_EMPTY:
02262          /* do nothing */
02263           break;
02264       default:
02265          /* shouldn't happen */
02266           break;
02267       }
02268     }
02269     update_jbsched(pvt);
02270     ast_mutex_unlock(&iaxsl[pvt->callno]);
02271     return 0;
02272 }

static int handle_error void   )  [static]
 

Definition at line 1452 of file chan_iax2.c.

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

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

01453 {
01454    /* XXX Ideally we should figure out why an error occured and then abort those
01455       rather than continuing to try.  Unfortunately, the published interface does
01456       not seem to work XXX */
01457 #if 0
01458    struct sockaddr_in *sin;
01459    int res;
01460    struct msghdr m;
01461    struct sock_extended_err e;
01462    m.msg_name = NULL;
01463    m.msg_namelen = 0;
01464    m.msg_iov = NULL;
01465    m.msg_control = &e;
01466    m.msg_controllen = sizeof(e);
01467    m.msg_flags = 0;
01468    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
01469    if (res < 0)
01470       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
01471    else {
01472       if (m.msg_controllen) {
01473          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
01474          if (sin) 
01475             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
01476          else
01477             ast_log(LOG_WARNING, "No address detected??\n");
01478       } else {
01479          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
01480       }
01481    }
01482 #endif
01483    return 0;
01484 }

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

Acknowledgment received for OUR registration.

Definition at line 5521 of file chan_iax2.c.

References iax2_registry::addr, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, and VERBOSE_PREFIX_3.

Referenced by socket_read().

05522 {
05523    struct iax2_registry *reg;
05524    /* Start pessimistic */
05525    char peer[256] = "";
05526    char msgstatus[40];
05527    int refresh = 0;
05528    char ourip[256] = "<Unspecified>";
05529    struct sockaddr_in oldus;
05530    struct sockaddr_in us;
05531    char iabuf[INET_ADDRSTRLEN];
05532    int oldmsgs;
05533 
05534    memset(&us, 0, sizeof(us));
05535    if (ies->apparent_addr)
05536       bcopy(ies->apparent_addr, &us, sizeof(us));
05537    if (ies->username)
05538       ast_copy_string(peer, ies->username, sizeof(peer));
05539    if (ies->refresh)
05540       refresh = ies->refresh;
05541    if (ies->calling_number) {
05542       /* We don't do anything with it really, but maybe we should */
05543    }
05544    reg = iaxs[callno]->reg;
05545    if (!reg) {
05546       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05547       return -1;
05548    }
05549    memcpy(&oldus, &reg->us, sizeof(oldus));
05550    oldmsgs = reg->messages;
05551    if (inaddrcmp(&reg->addr, sin)) {
05552       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05553       return -1;
05554    }
05555    memcpy(&reg->us, &us, sizeof(reg->us));
05556    reg->messages = ies->msgcount;
05557    /* always refresh the registration at the interval requested by the server
05558       we are registering to
05559    */
05560    reg->refresh = refresh;
05561    if (reg->expire > -1)
05562       ast_sched_del(sched, reg->expire);
05563    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05564    if ((inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) {
05565       if (reg->messages > 65534)
05566          snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
05567       else if (reg->messages > 1)
05568          snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
05569       else if (reg->messages > 0)
05570          snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
05571       else
05572          snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05573       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
05574       ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ourip, msgstatus);
05575       manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05576    }
05577    reg->regstate = REG_STATE_REGISTERED;
05578    return 0;
05579 }

static int iax2_answer struct ast_channel c  )  [static]
 

Definition at line 3369 of file chan_iax2.c.

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

03370 {
03371    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03372    if (option_debug)
03373       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03374    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03375 }

static enum ast_bridge_result iax2_bridge struct ast_channel c0,
struct ast_channel c1,
int  flags,
struct ast_frame **  fo,
struct ast_channel **  rc,
int  timeoutms
[static]
 

Definition at line 3203 of file chan_iax2.c.

References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), channeltype, iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech_pvt, tv, ast_channel::type, unlock_both(), and VERBOSE_PREFIX_3.

03204 {
03205    struct ast_channel *cs[3];
03206    struct ast_channel *who;
03207    int to = -1;
03208    int res = -1;
03209    int transferstarted=0;
03210    struct ast_frame *f;
03211    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03212    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03213    struct timeval waittimer = {0, 0}, tv;
03214 
03215    lock_both(callno0, callno1);
03216    /* Put them in native bridge mode */
03217    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03218       iaxs[callno0]->bridgecallno = callno1;
03219       iaxs[callno1]->bridgecallno = callno0;
03220    }
03221    unlock_both(callno0, callno1);
03222 
03223    /* If not, try to bridge until we can execute a transfer, if we can */
03224    cs[0] = c0;
03225    cs[1] = c1;
03226    for (/* ever */;;) {
03227       /* Check in case we got masqueraded into */
03228       if ((c0->type != channeltype) || (c1->type != channeltype)) {
03229          if (option_verbose > 2)
03230             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03231          /* Remove from native mode */
03232          if (c0->type == channeltype) {
03233             ast_mutex_lock(&iaxsl[callno0]);
03234             iaxs[callno0]->bridgecallno = 0;
03235             ast_mutex_unlock(&iaxsl[callno0]);
03236          }
03237          if (c1->type == channeltype) {
03238             ast_mutex_lock(&iaxsl[callno1]);
03239             iaxs[callno1]->bridgecallno = 0;
03240             ast_mutex_unlock(&iaxsl[callno1]);
03241          }
03242          return AST_BRIDGE_FAILED_NOWARN;
03243       }
03244       if (c0->nativeformats != c1->nativeformats) {
03245          if (option_verbose > 2) {
03246             char buf0[255];
03247             char buf1[255];
03248             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03249             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03250             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03251          }
03252          /* Remove from native mode */
03253          lock_both(callno0, callno1);
03254          iaxs[callno0]->bridgecallno = 0;
03255          iaxs[callno1]->bridgecallno = 0;
03256          unlock_both(callno0, callno1);
03257          return AST_BRIDGE_FAILED_NOWARN;
03258       }
03259       /* check if transfered and if we really want native bridging */
03260       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER) && 
03261       !(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
03262          /* Try the transfer */
03263          if (iax2_start_transfer(callno0, callno1))
03264             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03265          transferstarted = 1;
03266       }
03267       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03268          /* Call has been transferred.  We're no longer involved */
03269          gettimeofday(&tv, NULL);
03270          if (ast_tvzero(waittimer)) {
03271             waittimer = tv;
03272          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03273             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03274             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03275             *fo = NULL;
03276             *rc = c0;
03277             res = AST_BRIDGE_COMPLETE;
03278             break;
03279          }
03280       }
03281       to = 1000;
03282       who = ast_waitfor_n(cs, 2, &to);
03283       if (timeoutms > -1) {
03284          timeoutms -= (1000 - to);
03285          if (timeoutms < 0)
03286             timeoutms = 0;
03287       }
03288       if (!who) {
03289          if (!timeoutms) {
03290             res = AST_BRIDGE_RETRY;
03291             break;
03292          }
03293          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03294             res = AST_BRIDGE_FAILED;
03295             break;
03296          }
03297          continue;
03298       }
03299       f = ast_read(who);
03300       if (!f) {
03301          *fo = NULL;
03302          *rc = who;
03303          res = AST_BRIDGE_COMPLETE;
03304          break;
03305       }
03306       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03307          *fo = f;
03308          *rc = who;
03309          res =  AST_BRIDGE_COMPLETE;
03310          break;
03311       }
03312       if ((f->frametype == AST_FRAME_VOICE) ||
03313           (f->frametype == AST_FRAME_TEXT) ||
03314           (f->frametype == AST_FRAME_VIDEO) || 
03315           (f->frametype == AST_FRAME_IMAGE) ||
03316           (f->frametype == AST_FRAME_DTMF)) {
03317          if ((f->frametype == AST_FRAME_DTMF) && 
03318              (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
03319             if ((who == c0)) {
03320                if  ((flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
03321                   *rc = c0;
03322                   *fo = f;
03323                   res = AST_BRIDGE_COMPLETE;
03324                   /* Remove from native mode */
03325                   break;
03326                } else 
03327                   goto tackygoto;
03328             } else
03329             if ((who == c1)) {
03330                if (flags & AST_BRIDGE_DTMF_CHANNEL_1) {
03331                   *rc = c1;
03332                   *fo = f;
03333                   res =  AST_BRIDGE_COMPLETE;
03334                   break;
03335                } else
03336                   goto tackygoto;
03337             }
03338          } else {
03339 #if 0
03340             if (iaxdebug && option_debug)
03341                ast_log(LOG_DEBUG, "Read from %s\n", who->name);
03342             if (who == last) 
03343                ast_log(LOG_DEBUG, "Servicing channel %s twice in a row?\n", last->name);
03344             last = who;
03345 #endif
03346 tackygoto:
03347             if (who == c0) 
03348                ast_write(c1, f);
03349             else 
03350                ast_write(c0, f);
03351          }
03352          ast_frfree(f);
03353       } else
03354          ast_frfree(f);
03355       /* Swap who gets priority */
03356       cs[2] = cs[0];
03357       cs[0] = cs[1];
03358       cs[1] = cs[2];
03359    }
03360    lock_both(callno0, callno1);
03361    if(iaxs[callno0])
03362       iaxs[callno0]->bridgecallno = 0;
03363    if(iaxs[callno1])
03364       iaxs[callno1]->bridgecallno = 0;
03365    unlock_both(callno0, callno1);
03366    return res;
03367 }

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

Definition at line 2962 of file chan_iax2.c.

References ast_channel::_state, ast_channel::adsicpe, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_sched_add(), ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_strlen_zero(), ast_test_flag, auto_congest(), autokill, CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, context, ast_channel::context, create_addr(), iax2_datetime(), iax2_encryption, IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxsl, ast_channel::language, LOG_WARNING, create_addr_info::maxtime, n, ast_channel::name, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), PTR_TO_CALLNO, secret, send_command(), ast_channel::tech_pvt, and username.

02963 {
02964    struct sockaddr_in sin;
02965    char *l=NULL, *n=NULL, *tmpstr;
02966    struct iax_ie_data ied;
02967    char *defaultrdest = "s";
02968    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02969    struct parsed_dial_string pds;
02970    struct create_addr_info cai;
02971 
02972    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
02973       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
02974       return -1;
02975    }
02976 
02977    memset(&cai, 0, sizeof(cai));
02978    cai.encmethods = iax2_encryption;
02979 
02980    memset(&pds, 0, sizeof(pds));
02981    tmpstr = ast_strdupa(dest);
02982    parse_dial_string(tmpstr, &pds);
02983 
02984    if (!pds.exten)
02985       pds.exten = defaultrdest;
02986 
02987    if (create_addr(pds.peer, &sin, &cai)) {
02988       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
02989       return -1;
02990    }
02991 
02992    if (!pds.username && !ast_strlen_zero(cai.username))
02993       pds.username = cai.username;
02994    if (!pds.password && !ast_strlen_zero(cai.secret))
02995       pds.password = cai.secret;
02996    if (!pds.key && !ast_strlen_zero(cai.outkey))
02997       pds.key = cai.outkey;
02998    if (!pds.context && !ast_strlen_zero(cai.peercontext))
02999       pds.context = cai.peercontext;
03000 
03001    /* Keep track of the context for outgoing calls too */
03002    ast_copy_string(c->context, cai.context, sizeof(c->context));
03003 
03004    if (pds.port)
03005       sin.sin_port = htons(atoi(pds.port));
03006 
03007    l = c->cid.cid_num;
03008    n = c->cid.cid_name;
03009 
03010    /* Now build request */ 
03011    memset(&ied, 0, sizeof(ied));
03012 
03013    /* On new call, first IE MUST be IAX version of caller */
03014    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03015    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03016    if (pds.options && strchr(pds.options, 'a')) {
03017       /* Request auto answer */
03018       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03019    }
03020 
03021    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03022 
03023    if (l) {
03024       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03025       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03026    } else {
03027       if (n)
03028          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03029       else
03030          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03031    }
03032 
03033    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03034    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03035 
03036    if (n)
03037       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03038    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03039       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03040 
03041    if (!ast_strlen_zero(c->language))
03042       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03043    if (!ast_strlen_zero(c->cid.cid_dnid))
03044       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03045 
03046    if (pds.context)
03047       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03048 
03049    if (pds.username)
03050       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03051 
03052    if (cai.encmethods)
03053       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03054 
03055    ast_mutex_lock(&iaxsl[callno]);
03056 
03057    if (!ast_strlen_zero(c->context))
03058       ast_copy_string(iaxs[callno]->context, c->context, sizeof(iaxs[callno]->context));
03059 
03060    if (pds.username)
03061       ast_copy_string(iaxs[callno]->username, pds.username, sizeof(iaxs[callno]->username));
03062 
03063    iaxs[callno]->encmethods = cai.encmethods;
03064 
03065    if (pds.key)
03066       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
03067    if (pds.password)
03068       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
03069 
03070    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03071    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03072    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03073    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03074 
03075    if (iaxs[callno]->maxtime) {
03076       /* Initialize pingtime and auto-congest time */
03077       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03078       iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03079    } else if (autokill) {
03080       iaxs[callno]->pingtime = autokill / 2;
03081       iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03082    }
03083 
03084    /* send the command using the appropriate socket for this peer */
03085    iaxs[callno]->sockfd = cai.sockfd;
03086 
03087    /* Transmit the string in a "NEW" request */
03088    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03089 
03090    ast_mutex_unlock(&iaxsl[callno]);
03091    ast_setstate(c, AST_STATE_RINGING);
03092    
03093    return 0;
03094 }

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

Definition at line 9242 of file chan_iax2.c.

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

09243 {
09244    int res = 0;
09245    struct iax2_dpcache *dp;
09246 #if 0
09247    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09248 #endif
09249    if ((priority != 1) && (priority != 2))
09250       return 0;
09251    ast_mutex_lock(&dpcache_lock);
09252    dp = find_cache(chan, data, context, exten, priority);
09253    if (dp) {
09254       if (dp->flags & CACHE_FLAG_CANEXIST)
09255          res= 1;
09256    }
09257    ast_mutex_unlock(&dpcache_lock);
09258    if (!dp) {
09259       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09260    }
09261    return res;
09262 }

static unsigned int iax2_datetime char *  tz  )  [static]
 

Definition at line 2875 of file chan_iax2.c.

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

Referenced by iax2_call(), and update_registry().

02876 {
02877    time_t t;
02878    struct tm tm;
02879    unsigned int tmp;
02880    time(&t);
02881    localtime_r(&t, &tm);
02882    if (!ast_strlen_zero(tz))
02883       ast_localtime(&t, &tm, tz);
02884    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02885    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02886    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02887    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02888    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02889    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02890    return tmp;
02891 }

static void iax2_destroy int  callno  )  [static]
 

Definition at line 1610 of file chan_iax2.c.

References ast_channel::_softhangup, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_translator_free_path(), ast_variables_destroy(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgetrans, iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, free, ast_iax2_queue::head, iax2_frame_free(), IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxq, iaxs, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, lastused, ast_user_list::lock, ast_channel::lock, LOG_NOTICE, iax_frame::next, chan_iax2_pvt::owner, chan_iax2_pvt::pingid, chan_iax2_pvt::reg, iax_frame::retries, update_max_trunk(), user, userl, chan_iax2_pvt::username, ast_user_list::users, and chan_iax2_pvt::vars.

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

01611 {
01612    struct chan_iax2_pvt *pvt;
01613    struct iax_frame *cur;
01614    struct ast_channel *owner;
01615    struct iax2_user *user;
01616 
01617 retry:
01618    ast_mutex_lock(&iaxsl[callno]);
01619    pvt = iaxs[callno];
01620    gettimeofday(&lastused[callno], NULL);
01621 
01622    if (pvt)
01623       owner = pvt->owner;
01624    else
01625       owner = NULL;
01626    if (owner) {
01627       if (ast_mutex_trylock(&owner->lock)) {
01628          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01629          ast_mutex_unlock(&iaxsl[callno]);
01630          usleep(1);
01631          goto retry;
01632       }
01633    }
01634    if (!owner)
01635       iaxs[callno] = NULL;
01636    if (pvt) {
01637       if (!owner)
01638          pvt->owner = NULL;
01639       if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01640          ast_mutex_lock(&userl.lock);
01641          user = userl.users;
01642          while (user) {
01643             if (!strcmp(user->name, pvt->username)) {
01644                user->curauthreq--;
01645                break;
01646             }
01647             user = user->next;
01648          }
01649          ast_mutex_unlock(&userl.lock);
01650       }
01651       /* No more pings or lagrq's */
01652       if (pvt->pingid > -1)
01653          ast_sched_del(sched, pvt->pingid);
01654       if (pvt->lagid > -1)
01655          ast_sched_del(sched, pvt->lagid);
01656       if (pvt->autoid > -1)
01657          ast_sched_del(sched, pvt->autoid);
01658       if (pvt->authid > -1)
01659          ast_sched_del(sched, pvt->authid);
01660       if (pvt->initid > -1)
01661          ast_sched_del(sched, pvt->initid);
01662 #ifdef NEWJB
01663       if (pvt->jbid > -1)
01664          ast_sched_del(sched, pvt->jbid);
01665       pvt->jbid = -1;
01666 #endif
01667       pvt->pingid = -1;
01668       pvt->lagid = -1;
01669       pvt->autoid = -1;
01670       pvt->authid = -1;
01671       pvt->initid = -1;
01672       if (pvt->bridgetrans)
01673          ast_translator_free_path(pvt->bridgetrans);
01674       pvt->bridgetrans = NULL;
01675 
01676       /* Already gone */
01677       ast_set_flag(pvt, IAX_ALREADYGONE); 
01678 
01679       if (owner) {
01680          /* If there's an owner, prod it to give up */
01681          owner->_softhangup |= AST_SOFTHANGUP_DEV;
01682          ast_queue_hangup(owner);
01683       }
01684 
01685       for (cur = iaxq.head; cur ; cur = cur->next) {
01686          /* Cancel any pending transmissions */
01687          if (cur->callno == pvt->callno) 
01688             cur->retries = -1;
01689       }
01690       if (pvt->reg) {
01691          pvt->reg->callno = 0;
01692       }
01693       if (!owner) {
01694          if (pvt->vars) {
01695             ast_variables_destroy(pvt->vars);
01696             pvt->vars = NULL;
01697          }
01698 #ifdef NEWJB
01699          {
01700                             jb_frame frame;
01701                             while(jb_getall(pvt->jb,&frame) == JB_OK)
01702             iax2_frame_free(frame.data);
01703                             jb_destroy(pvt->jb);
01704                         }
01705 #endif
01706          free(pvt);
01707       }
01708    }
01709    if (owner) {
01710       ast_mutex_unlock(&owner->lock);
01711    }
01712    ast_mutex_unlock(&iaxsl[callno]);
01713    if (callno & 0x4000)
01714       update_max_trunk();
01715 }

static void iax2_destroy_nolock int  callno  )  [static]
 

Definition at line 1716 of file chan_iax2.c.

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

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

01717 {  
01718    /* Actually it's easier to unlock, kill it, and relock */
01719    ast_mutex_unlock(&iaxsl[callno]);
01720    iax2_destroy(callno);
01721    ast_mutex_lock(&iaxsl[callno]);
01722 }

static int iax2_devicestate void *  data  )  [static]
 

Definition at line 9435 of file chan_iax2.c.

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

09436 {
09437    struct parsed_dial_string pds;
09438    char *tmp = ast_strdupa(data);
09439    struct iax2_peer *p;
09440    int res = AST_DEVICE_INVALID;
09441 
09442    memset(&pds, 0, sizeof(pds));
09443    parse_dial_string(tmp, &pds);
09444    if (!pds.peer || ast_strlen_zero(pds.peer))
09445       return res;
09446    
09447    if (option_debug > 2)
09448       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
09449 
09450    /* SLD: FIXME: second call to find_peer during registration */
09451    if (!(p = find_peer(pds.peer, 1)))
09452       return res;
09453 
09454    res = AST_DEVICE_UNAVAILABLE;
09455    if (option_debug > 2) 
09456       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09457          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09458    
09459    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09460        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09461       /* Peer is registered, or have default IP address
09462          and a valid registration */
09463       if (p->historicms == 0 || p->historicms <= p->maxms)
09464          /* let the core figure out whether it is in use or not */
09465          res = AST_DEVICE_UNKNOWN;  
09466    }
09467 
09468    if (ast_test_flag(p, IAX_TEMPONLY))
09469       destroy_peer(p);
09470 
09471    return res;
09472 }

static int iax2_digit struct ast_channel c,
char  digit
[static]
 

Definition at line 2564 of file chan_iax2.c.

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

02565 {
02566    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
02567 }

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

Definition at line 4592 of file chan_iax2.c.

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

04593 {
04594    if (argc != 2)
04595       return RESULT_SHOWUSAGE;
04596    iaxdebug = 1;
04597    ast_cli(fd, "IAX2 Debugging Enabled\n");
04598    return RESULT_SUCCESS;
04599 }

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

Definition at line 4610 of file chan_iax2.c.

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

04611 {
04612    if (argc != 3)
04613       return RESULT_SHOWUSAGE;
04614 #ifdef NEWJB
04615    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04616 #endif
04617    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04618    return RESULT_SUCCESS;
04619 }

static int iax2_do_register struct iax2_registry reg  )  [static]
 

Definition at line 7744 of file chan_iax2.c.

References iax2_registry::addr, AST_FRAME_IAX, ast_log(), ast_sched_add(), ast_sched_del(), iax2_registry::callno, defaultsockfd, iax2_registry::expire, find_callno(), iax2_do_register_s(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxdebug, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, REG_STATE_REGSENT, iax2_registry::regstate, send_command(), and iax2_registry::username.

Referenced by iax2_do_register_s(), and load_module().

07745 {
07746    struct iax_ie_data ied;
07747    if (option_debug && iaxdebug)
07748       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07749    if (!reg->callno) {
07750       if (option_debug)
07751          ast_log(LOG_DEBUG, "Allocate call number\n");
07752       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
07753       if (reg->callno < 1) {
07754          ast_log(LOG_WARNING, "Unable to create call for registration\n");
07755          return -1;
07756       } else if (option_debug)
07757          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07758       iaxs[reg->callno]->reg = reg;
07759    }
07760    /* Schedule the next registration attempt */
07761    if (reg->expire > -1)
07762       ast_sched_del(sched, reg->expire);
07763    /* Setup the next registration a little early */
07764    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07765    /* Send the request */
07766    memset(&ied, 0, sizeof(ied));
07767    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07768    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07769    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07770    reg->regstate = REG_STATE_REGSENT;
07771    return 0;
07772 }

static int iax2_do_register_s void *  data  )  [static]
 

Definition at line 5367 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_ack_registry(), and iax2_do_register().

05368 {
05369    struct iax2_registry *reg = data;
05370    reg->expire = -1;
05371    iax2_do_register(reg);
05372    return 0;
05373 }

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

Definition at line 4601 of file chan_iax2.c.

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

04602 {
04603    if (argc != 3)
04604       return RESULT_SHOWUSAGE;
04605    iaxtrunkdebug = 1;
04606    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04607    return RESULT_SUCCESS;
04608 }

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

Definition at line 5984 of file chan_iax2.c.

References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, and send_command().

Referenced by find_cache(), and socket_read().

05985 {
05986    struct iax_ie_data ied;
05987    /* Auto-hangup with 30 seconds of inactivity */
05988    if (iaxs[callno]->autoid > -1)
05989       ast_sched_del(sched, iaxs[callno]->autoid);
05990    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05991    memset(&ied, 0, sizeof(ied));
05992    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05993    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05994    dp->flags |= CACHE_FLAG_TRANSMITTED;
05995 }

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

Definition at line 9288 of file chan_iax2.c.

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

09289 {
09290    char odata[256];
09291    char req[256];
09292    char *ncontext;
09293    char *dialstatus;
09294    struct iax2_dpcache *dp;
09295    struct ast_app *dial;
09296 #if 0
09297    ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack);
09298 #endif
09299    if (priority == 2) {
09300       /* Indicate status, can be overridden in dialplan */
09301       dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09302       if (dialstatus) {
09303          dial = pbx_findapp(dialstatus);
09304          if (dial) 
09305             pbx_exec(chan, dial, "", newstack);
09306       }
09307       return -1;
09308    } else if (priority != 1)
09309       return -1;
09310    ast_mutex_lock(&dpcache_lock);
09311    dp = find_cache(chan, data, context, exten, priority);
09312    if (dp) {
09313       if (dp->flags & CACHE_FLAG_EXISTS) {
09314          ast_copy_string(odata, data, sizeof(odata));
09315          ncontext = strchr(odata, '/');
09316          if (ncontext) {
09317             *ncontext = '\0';
09318             ncontext++;
09319             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09320          } else {
09321             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09322          }
09323          if (option_verbose > 2)
09324             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09325       } else {
09326          ast_mutex_unlock(&dpcache_lock);
09327          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09328          return -1;
09329       }
09330    }
09331    ast_mutex_unlock(&dpcache_lock);
09332    dial = pbx_findapp("Dial");
09333    if (dial) {
09334       return pbx_exec(chan, dial, req, newstack);
09335    } else {
09336       ast_log(LOG_WARNING, "No dial application registered\n");
09337    }
09338    return -1;
09339 }

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

Definition at line 9219 of file chan_iax2.c.

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

09220 {
09221    struct iax2_dpcache *dp;
09222    int res = 0;
09223 #if 0
09224    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09225 #endif
09226    if ((priority != 1) && (priority != 2))
09227       return 0;
09228    ast_mutex_lock(&dpcache_lock);
09229    dp = find_cache(chan, data, context, exten, priority);
09230    if (dp) {
09231       if (dp->flags & CACHE_FLAG_EXISTS)
09232          res= 1;
09233    }
09234    ast_mutex_unlock(&dpcache_lock);
09235    if (!dp) {
09236       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09237    }
09238    return res;
09239 }

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

Definition at line 2586 of file chan_iax2.c.

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

02587 {
02588    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02589    ast_mutex_lock(&iaxsl[callno]);
02590    if (iaxs[callno])
02591       iaxs[callno]->owner = newchan;
02592    else
02593       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02594    ast_mutex_unlock(&iaxsl[callno]);
02595    return 0;
02596 }

static void iax2_frame_free struct iax_frame fr  )  [static]
 

Definition at line 1130 of file chan_iax2.c.

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

Referenced by __do_deliver(), attempt_transmit(), complete_transfer(), get_from_jb(), and iax2_destroy().

01131 {
01132    if (fr->retrans > -1)
01133       ast_sched_del(sched, fr->retrans);
01134    iax_frame_free(fr);
01135 }

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

Definition at line 875 of file chan_iax2.c.

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

00876 {
00877    struct iax2_peer *peer;
00878    int res = 0;
00879 
00880    if (lockpeer)
00881       ast_mutex_lock(&peerl.lock);
00882    peer = peerl.peers;
00883    while (peer) {
00884       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
00885             (peer->addr.sin_port == sin.sin_port)) {
00886                ast_copy_string(host, peer->name, len);
00887                res = 1;
00888                break;
00889       }
00890       peer = peer->next;
00891    }
00892    if (lockpeer)
00893       ast_mutex_unlock(&peerl.lock);
00894    if (!peer) {
00895       peer = realtime_peer(NULL, &sin);
00896       if (peer) {
00897          ast_copy_string(host, peer->name, len);
00898          if (ast_test_flag(peer, IAX_TEMPONLY))
00899             destroy_peer(peer);
00900          res = 1;
00901       }
00902    }
00903 
00904    return res;
00905 }

static int iax2_getpeertrunk struct sockaddr_in  sin  )  [static]
 

Definition at line 3408 of file chan_iax2.c.

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

Referenced by check_access().

03409 {
03410    struct iax2_peer *peer;
03411    int res = 0;
03412    ast_mutex_lock(&peerl.lock);
03413    peer = peerl.peers;
03414    while(peer) {
03415       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03416             (peer->addr.sin_port == sin.sin_port)) {
03417                res = ast_test_flag(peer, IAX_TRUNK);
03418                break;
03419       }
03420       peer = peer->next;
03421    }
03422    ast_mutex_unlock(&peerl.lock);
03423    return res;
03424 }

static int iax2_hangup struct ast_channel c  )  [static]
 

Definition at line 3096 of file chan_iax2.c.

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

03097 {
03098    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03099    int alreadygone;
03100    struct iax_ie_data ied;
03101    memset(&ied, 0, sizeof(ied));
03102    ast_mutex_lock(&iaxsl[callno]);
03103    if (callno && iaxs[callno]) {
03104       ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03105       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03106       /* Send the hangup unless we have had a transmission error or are already gone */
03107       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03108       if (!iaxs[callno]->error && !alreadygone) 
03109          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03110       /* Explicitly predestroy it */
03111       iax2_predestroy_nolock(callno);
03112       /* If we were already gone to begin with, destroy us now */
03113       if (alreadygone) {
03114          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03115          iax2_destroy_nolock(callno);
03116       }
03117    }
03118    ast_mutex_unlock(&iaxsl[callno]);
03119    if (option_verbose > 2) 
03120       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03121    return 0;
03122 }

static int iax2_indicate struct ast_channel c,
int  condition
[static]
 

Definition at line 3377 of file chan_iax2.c.

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

03378 {
03379    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03380    if (option_debug && iaxdebug)
03381       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03382    return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
03383 }

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

Definition at line 9265 of file chan_iax2.c.

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

09266 {
09267    int res = 0;
09268    struct iax2_dpcache *dp;
09269 #if 0
09270    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09271 #endif
09272    if ((priority != 1) && (priority != 2))
09273       return 0;
09274    ast_mutex_lock(&dpcache_lock);
09275    dp = find_cache(chan, data, context, exten, priority);
09276    if (dp) {
09277       if (dp->flags & CACHE_FLAG_MATCHMORE)
09278          res= 1;
09279    }
09280    ast_mutex_unlock(&dpcache_lock);
09281    if (!dp) {
09282       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09283    }
09284    return res;
09285 }

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

Definition at line 4621 of file chan_iax2.c.

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

04622 {
04623    if (argc != 3)
04624       return RESULT_SHOWUSAGE;
04625    iaxdebug = 0;
04626    ast_cli(fd, "IAX2 Debugging Disabled\n");
04627    return RESULT_SUCCESS;
04628 }

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

Definition at line 4639 of file chan_iax2.c.

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

04640 {
04641    if (argc != 4)
04642       return RESULT_SHOWUSAGE;
04643 #ifdef NEWJB
04644    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04645    jb_debug_output("\n");
04646 #endif
04647    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04648    return RESULT_SUCCESS;
04649 }

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

Definition at line 4630 of file chan_iax2.c.

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

04631 {
04632    if (argc != 4)
04633       return RESULT_SHOWUSAGE;
04634    iaxtrunkdebug = 0;
04635    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04636    return RESULT_SUCCESS;
04637 }

static int iax2_poke_noanswer void *  data  )  [static]
 

Definition at line 7895 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

07896 {
07897    struct iax2_peer *peer = data;
07898    peer->pokeexpire = -1;
07899    if (peer->lastms > -1) {
07900       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07901       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07902       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07903    }
07904    if (peer->callno > 0)
07905       iax2_destroy(peer->callno);
07906    peer->callno = 0;
07907    peer->lastms = -1;
07908    /* Try again quickly */
07909    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07910    return 0;
07911 }

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

Definition at line 7913 of file chan_iax2.c.

References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), IAX_COMMAND_POKE, iaxsl, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, send_command(), and iax2_peer::sockfd.

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

07914 {
07915    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07916       /* IF we have no IP, or this isn't to be monitored, return
07917         imeediately after clearing things out */
07918       peer->lastms = 0;
07919       peer->historicms = 0;
07920       peer->pokeexpire = -1;
07921       peer->callno = 0;
07922       return 0;
07923    }
07924    if (peer->callno > 0) {
07925       ast_log(LOG_NOTICE, "Still have a callno...\n");
07926       iax2_destroy(peer->callno);
07927    }
07928    if (heldcall)
07929       ast_mutex_unlock(&iaxsl[heldcall]);
07930    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
07931    if (heldcall)
07932       ast_mutex_lock(&iaxsl[heldcall]);
07933    if (peer->callno < 1) {
07934       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
07935       return -1;
07936    }
07937    if (peer->pokeexpire > -1)
07938       ast_sched_del(sched, peer->pokeexpire);
07939    /* Speed up retransmission times */
07940    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
07941    iaxs[peer->callno]->peerpoke = peer;
07942    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
07943    
07944    /* If the host is already unreachable then use the unreachable interval instead */
07945    if (peer->lastms < 0) {
07946       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
07947    } else
07948       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
07949 
07950    return 0;
07951 }

static int iax2_poke_peer_s void *  data  )  [static]
 

Definition at line 6018 of file chan_iax2.c.

References iax2_poke_peer(), and iax2_peer::pokeexpire.

Referenced by iax2_poke_noanswer(), and socket_read().

06019 {
06020    struct iax2_peer *peer = data;
06021    peer->pokeexpire = -1;
06022    iax2_poke_peer(peer, 0);
06023    return 0;
06024 }

static int iax2_predestroy int  callno  )  [static]
 

Definition at line 1537 of file chan_iax2.c.

References ast_channel::_softhangup, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_queue_hangup(), ast_sched_del(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_test_flag, ast_update_use_count(), IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxs, iaxsl, ast_user_list::lock, LOG_WARNING, chan_iax2_pvt::owner, ast_channel::tech_pvt, usecnt, usecnt_lock, user, userl, and ast_user_list::users.

Referenced by iax2_predestroy_nolock().

01538 {
01539    struct ast_channel *c;
01540    struct chan_iax2_pvt *pvt;
01541    struct iax2_user *user;
01542    ast_mutex_lock(&iaxsl[callno]);
01543    pvt = iaxs[callno];
01544    if (!pvt) {
01545       ast_mutex_unlock(&iaxsl[callno]);
01546       return -1;
01547    }
01548    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01549       if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01550          ast_mutex_lock(&userl.lock);
01551          user = userl.users;
01552          while (user) {
01553             if (!strcmp(user->name, pvt->username)) {
01554                user->curauthreq--;
01555                break;
01556             }
01557             user = user->next;
01558          }
01559          ast_mutex_unlock(&userl.lock);
01560       }
01561       /* No more pings or lagrq's */
01562       if (pvt->pingid > -1)
01563          ast_sched_del(sched, pvt->pingid);
01564       if (pvt->lagid > -1)
01565          ast_sched_del(sched, pvt->lagid);
01566       if (pvt->autoid > -1)
01567          ast_sched_del(sched, pvt->autoid);
01568       if (pvt->authid > -1)
01569          ast_sched_del(sched, pvt->authid);
01570       if (pvt->initid > -1)
01571          ast_sched_del(sched, pvt->initid);
01572 #ifdef NEWJB
01573       if (pvt->jbid > -1)
01574          ast_sched_del(sched, pvt->jbid);
01575       pvt->jbid = -1;
01576 #endif
01577       pvt->pingid = -1;
01578       pvt->lagid = -1;
01579       pvt->autoid = -1;
01580       pvt->initid = -1;
01581       pvt->authid = -1;
01582       ast_set_flag(pvt, IAX_ALREADYGONE); 
01583    }
01584    c = pvt->owner;
01585    if (c) {
01586       c->_softhangup |= AST_SOFTHANGUP_DEV;
01587       c->tech_pvt = NULL;
01588       ast_queue_hangup(c);
01589       pvt->owner = NULL;
01590       ast_mutex_lock(&usecnt_lock);
01591       usecnt--;
01592       if (usecnt < 0) 
01593          ast_log(LOG_WARNING, "Usecnt < 0???\n");
01594       ast_mutex_unlock(&usecnt_lock);
01595    }
01596    ast_mutex_unlock(&iaxsl[callno]);
01597    ast_update_use_count();
01598    return 0;
01599 }

static int iax2_predestroy_nolock int  callno  )  [static]
 

Definition at line 1601 of file chan_iax2.c.

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

Referenced by iax2_hangup(), and send_command_final().

01602 {
01603    int res;
01604    ast_mutex_unlock(&iaxsl[callno]);
01605    res = iax2_predestroy(callno);
01606    ast_mutex_lock(&iaxsl[callno]);
01607    return res;
01608 }

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

Definition at line 7873 of file chan_iax2.c.

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

07874 {
07875    int force = 0;
07876    int res;
07877    if (argc < 4)
07878       return RESULT_SHOWUSAGE;
07879    if ((argc > 4)) {
07880       if (!strcasecmp(argv[4], "forced"))
07881          force = 1;
07882       else
07883          return RESULT_SHOWUSAGE;
07884    }
07885    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07886    if (res < 0)
07887       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07888    else if (res < 1)
07889       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07890    else
07891       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07892    return RESULT_SUCCESS;
07893 }

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

Definition at line 7774 of file chan_iax2.c.

References iax_prov_complete_template().

07775 {
07776    if (pos != 3)
07777       return NULL;
07778    return iax_prov_complete_template(line, word, pos, state);
07779 }

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

Definition at line 7781 of file chan_iax2.c.

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

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

07782 {
07783    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
07784       is found for template */
07785    struct iax_ie_data provdata;
07786    struct iax_ie_data ied;
07787    unsigned int sig;
07788    struct sockaddr_in sin;
07789    int callno;
07790    struct create_addr_info cai;
07791 
07792    memset(&cai, 0, sizeof(cai));
07793 
07794    if (option_debug)
07795       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07796 
07797    if (iax_provision_build(&provdata, &sig, template, force)) {
07798       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07799       return 0;
07800    }
07801 
07802    if (end) {
07803       memcpy(&sin, end, sizeof(sin));
07804       cai.sockfd = sockfd;
07805    } else if (create_addr(dest, &sin, &cai))
07806       return -1;
07807 
07808    /* Build the rest of the message */
07809    memset(&ied, 0, sizeof(ied));
07810    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07811 
07812    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07813    if (!callno)
07814       return -1;
07815 
07816    ast_mutex_lock(&iaxsl[callno]);
07817    if (iaxs[callno]) {
07818       /* Schedule autodestruct in case they don't ever give us anything back */
07819       if (iaxs[callno]->autoid > -1)
07820          ast_sched_del(sched, iaxs[callno]->autoid);
07821       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07822       ast_set_flag(iaxs[callno], IAX_PROVISION);
07823       /* Got a call number now, so go ahead and send the provisioning information */
07824       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07825    }
07826    ast_mutex_unlock(&iaxsl[callno]);
07827 
07828    return 1;
07829 }

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

Definition at line 1862 of file chan_iax2.c.

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

01863 {
01864    struct iax2_peer *peer;
01865 
01866    if (argc != 4)
01867         return RESULT_SHOWUSAGE;
01868    if (!strcmp(argv[3],"all")) {
01869       reload_config();
01870       ast_cli(fd, "OK cache is flushed.\n");
01871    } else if ((peer = find_peer(argv[3], 0))) {
01872       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
01873          ast_set_flag(peer, IAX_RTAUTOCLEAR);
01874          expire_registry(peer);
01875          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
01876       } else {
01877          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
01878       }
01879    } else {
01880       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
01881    }
01882    
01883    return RESULT_SUCCESS;
01884 }

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

Definition at line 1137 of file chan_iax2.c.

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

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

01138 {
01139    /* Assumes lock for callno is already held... */
01140    for (;;) {
01141       if (iaxs[callno] && iaxs[callno]->owner) {
01142          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01143             /* Avoid deadlock by pausing and trying again */
01144             ast_mutex_unlock(&iaxsl[callno]);
01145             usleep(1);
01146             ast_mutex_lock(&iaxsl[callno]);
01147          } else {
01148             ast_queue_frame(iaxs[callno]->owner, f);
01149             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01150             break;
01151          }
01152       } else
01153          break;
01154    }
01155    return 0;
01156 }

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

Definition at line 3153 of file chan_iax2.c.

References AST_FRAME_NULL, ast_log(), and LOG_NOTICE.

03154 {
03155    static struct ast_frame f = { AST_FRAME_NULL, };
03156    ast_log(LOG_NOTICE, "I should never be called!\n");
03157    return &f;
03158 }

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

Definition at line 5581 of file chan_iax2.c.

References ahp, ast_gethostbyname(), ast_log(), iax2_registry::callno, copy(), hostname, hp, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_ERROR, LOG_WARNING, malloc, registrations, secret, strsep(), and username.

Referenced by set_config().

05582 {
05583    struct iax2_registry *reg;
05584    char copy[256];
05585    char *username, *hostname, *secret;
05586    char *porta;
05587    char *stringp=NULL;
05588    
05589    struct ast_hostent ahp; struct hostent *hp;
05590    if (!value)
05591       return -1;
05592    ast_copy_string(copy, value, sizeof(copy));
05593    stringp=copy;
05594    username = strsep(&stringp, "@");
05595    hostname = strsep(&stringp, "@");
05596    if (!hostname) {
05597       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
05598       return -1;
05599    }
05600    stringp=username;
05601    username = strsep(&stringp, ":");
05602    secret = strsep(&stringp, ":");
05603    stringp=hostname;
05604    hostname = strsep(&stringp, ":");
05605    porta = strsep(&stringp, ":");
05606    
05607    if (porta && !atoi(porta)) {
05608       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05609       return -1;
05610    }
05611    hp = ast_gethostbyname(hostname, &ahp);
05612    if (!hp) {
05613       ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
05614       return -1;
05615    }
05616    reg = malloc(sizeof(struct iax2_registry));
05617    if (reg) {
05618       memset(reg, 0, sizeof(struct iax2_registry));
05619       ast_copy_string(reg->username, username, sizeof(reg->username));
05620       if (secret)
05621          ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05622       reg->expire = -1;
05623       reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05624       reg->addr.sin_family = AF_INET;
05625       memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
05626       reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05627       reg->next = registrations;
05628       reg->callno = 0;
05629       registrations = reg;
05630    } else {
05631       ast_log(LOG_ERROR, "Out of memory\n");
05632       return -1;
05633    }
05634    return 0;
05635 }

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

Definition at line 8991 of file chan_iax2.c.

References reload_config().

08992 {
08993    return reload_config();
08994 }

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

Definition at line 7963 of file chan_iax2.c.

References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno(), globalflags, iax2_capability, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iaxsl, LOG_WARNING, make_trunk(), ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.

07964 {
07965    int callno;
07966    int res;
07967    int fmt, native;
07968    struct sockaddr_in sin;
07969    struct ast_channel *c;
07970    struct parsed_dial_string pds;
07971    struct create_addr_info cai;
07972    char *tmpstr;
07973 
07974    memset(&pds, 0, sizeof(pds));
07975    tmpstr = ast_strdupa(data);
07976    parse_dial_string(tmpstr, &pds);
07977 
07978    memset(&cai, 0, sizeof(cai));
07979    cai.capability = iax2_capability;
07980 
07981    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07982 
07983    if (!pds.peer) {
07984       ast_log(LOG_WARNING, "No peer given\n");
07985       return NULL;
07986    }
07987           
07988    
07989    /* Populate our address from the given */
07990    if (create_addr(pds.peer, &sin, &cai)) {
07991       *cause = AST_CAUSE_UNREGISTERED;
07992       return NULL;
07993    }
07994 
07995    if (pds.port)
07996       sin.sin_port = htons(atoi(pds.port));
07997 
07998    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07999    if (callno < 1) {
08000       ast_log(LOG_WARNING, "Unable to create call\n");
08001       *cause = AST_CAUSE_CONGESTION;
08002       return NULL;
08003    }
08004 
08005    ast_mutex_lock(&iaxsl[callno]);
08006 
08007    /* If this is a trunk, update it now */
08008    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
08009    if (ast_test_flag(&cai, IAX_TRUNK))
08010       callno = make_trunk(callno, 1);
08011    iaxs[callno]->maxtime = cai.maxtime;
08012    if (cai.found)
08013       ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host));
08014 
08015    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08016 
08017    ast_mutex_unlock(&iaxsl[callno]);
08018 
08019    if (c) {
08020       /* Choose a format we can live with */
08021       if (c->nativeformats & format) 
08022          c->nativeformats &= format;
08023       else {
08024          native = c->nativeformats;
08025          fmt = format;
08026          res = ast_translator_best_choice(&fmt, &native);
08027          if (res < 0) {
08028             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08029                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08030             ast_hangup(c);
08031             return NULL;
08032          }
08033          c->nativeformats = native;
08034       }
08035       c->readformat = ast_best_codec(c->nativeformats);
08036       c->writeformat = c->readformat;
08037    }
08038 
08039    return c;
08040 }

static int iax2_send struct chan_iax2_pvt pvt,
struct ast_frame f,
unsigned int  ts,
int  seqno,
int  now,
int  transfer,
int  final
[static]
 

Definition at line 3983 of file chan_iax2.c.

References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, iaxdebug, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, MAX_RETRY_TIME, MIN_RETRY_TIME, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.

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

03984 {
03985    /* Queue a packet for delivery on a given private structure.  Use "ts" for
03986       timestamp, or calculate if ts is 0.  Send immediately without retransmission
03987       or delayed, with retransmission */
03988    struct ast_iax2_full_hdr *fh;
03989    struct ast_iax2_mini_hdr *mh;
03990    struct ast_iax2_video_hdr *vh;
03991    struct {
03992       struct iax_frame fr2;
03993       unsigned char buffer[4096];
03994    } frb;
03995    struct iax_frame *fr;
03996    int res;
03997    int sendmini=0;
03998    unsigned int lastsent;
03999    unsigned int fts;
04000       
04001    if (!pvt) {
04002       ast_log(LOG_WARNING, "No private structure for packet?\n");
04003       return -1;
04004    }
04005    
04006    lastsent = pvt->lastsent;
04007 
04008    /* Calculate actual timestamp */
04009    fts = calc_timestamp(pvt, ts, f);
04010 
04011    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04012     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04013     * increment the "predicted timestamps" for voice, if we're predecting */
04014    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04015        return 0;
04016 
04017 
04018    if ((ast_test_flag(pvt, IAX_TRUNK) || ((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)))
04019       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04020        (f->frametype == AST_FRAME_VOICE) 
04021       /* is a voice frame */ &&
04022       (f->subclass == pvt->svoiceformat) 
04023       /* is the same type */ ) {
04024          /* Force immediate rather than delayed transmission */
04025          now = 1;
04026          /* Mark that mini-style frame is appropriate */
04027          sendmini = 1;
04028    }
04029    if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) && 
04030       (f->frametype == AST_FRAME_VIDEO) &&
04031       ((f->subclass & ~0x1) == pvt->svideoformat)) {
04032          now = 1;
04033          sendmini = 1;
04034    }
04035    /* Allocate an iax_frame */
04036    if (now) {
04037       fr = &frb.fr2;
04038    } else
04039       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen);
04040    if (!fr) {
04041       ast_log(LOG_WARNING, "Out of memory\n");
04042       return -1;
04043    }
04044    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04045    iax_frame_wrap(fr, f);
04046 
04047    fr->ts = fts;
04048    fr->callno = pvt->callno;
04049    fr->transfer = transfer;
04050    fr->final = final;
04051    if (!sendmini) {
04052       /* We need a full frame */
04053       if (seqno > -1)
04054          fr->oseqno = seqno;
04055       else
04056          fr->oseqno = pvt->oseqno++;
04057       fr->iseqno = pvt->iseqno;
04058       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04059       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04060       fh->ts = htonl(fr->ts);
04061       fh->oseqno = fr->oseqno;
04062       if (transfer) {
04063          fh->iseqno = 0;
04064       } else
04065          fh->iseqno = fr->iseqno;
04066       /* Keep track of the last thing we've acknowledged */
04067       if (!transfer)
04068          pvt->aseqno = fr->iseqno;
04069       fh->type = fr->af.frametype & 0xFF;
04070       if (fr->af.frametype == AST_FRAME_VIDEO)
04071          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04072       else
04073          fh->csub = compress_subclass(fr->af.subclass);
04074       if (transfer) {
04075          fr->dcallno = pvt->transfercallno;
04076       } else
04077          fr->dcallno = pvt->peercallno;
04078       fh->dcallno = htons(fr->dcallno);
04079       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04080       fr->data = fh;
04081       fr->retries = 0;
04082       /* Retry after 2x the ping time has passed */
04083       fr->retrytime = pvt->pingtime * 2;
04084       if (fr->retrytime < MIN_RETRY_TIME)
04085          fr->retrytime = MIN_RETRY_TIME;
04086       if (fr->retrytime > MAX_RETRY_TIME)
04087          fr->retrytime = MAX_RETRY_TIME;
04088       /* Acks' don't get retried */
04089       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04090          fr->retries = -1;
04091       else if (f->frametype == AST_FRAME_VOICE)
04092          pvt->svoiceformat = f->subclass;
04093       else if (f->frametype == AST_FRAME_VIDEO)
04094          pvt->svideoformat = f->subclass & ~0x1;
04095       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04096          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04097             if (iaxdebug) {
04098                if (fr->transfer)
04099                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04100                else
04101                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04102             }
04103             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04104          } else
04105             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04106       }
04107    
04108       if (now) {
04109          res = send_packet(fr);
04110       } else
04111          res = iax2_transmit(fr);
04112    } else {
04113       if (ast_test_flag(pvt, IAX_TRUNK)) {
04114          iax2_trunk_queue(pvt, fr);
04115          res = 0;
04116       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04117          /* Video frame have no sequence number */
04118          fr->oseqno = -1;
04119          fr->iseqno = -1;
04120          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04121          vh->zeros = 0;
04122          vh->callno = htons(0x8000 | fr->callno);
04123          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04124          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04125          fr->data = vh;
04126          fr->retries = -1;
04127          res = send_packet(fr);        
04128       } else {
04129          /* Mini-frames have no sequence number */
04130          fr->oseqno = -1;
04131          fr->iseqno = -1;
04132          /* Mini frame will do */
04133          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04134          mh->callno = htons(fr->callno);
04135          mh->ts = htons(fr->ts & 0xFFFF);
04136          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04137          fr->data = mh;
04138          fr->retries = -1;
04139          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04140             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04141                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04142             } else
04143                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04144          }
04145          res = send_packet(fr);
04146       }
04147    }
04148    return res;
04149 }

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

Definition at line 2581 of file chan_iax2.c.

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

02582 {
02583    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02584 }

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

Definition at line 2576 of file chan_iax2.c.

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

02577 {
02578    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02579 }

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

Definition at line 2569 of file chan_iax2.c.

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

02570 {
02571    
02572    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02573       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02574 }

static int iax2_set_jitter int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1826 of file chan_iax2.c.

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

01827 {
01828 #ifdef NEWJB
01829    ast_cli(fd, "sorry, this command is deprecated\n");
01830    return RESULT_SUCCESS;
01831 #else
01832    if ((argc != 4) && (argc != 5))
01833       return RESULT_SHOWUSAGE;
01834    if (argc == 4) {
01835       max_jitter_buffer = atoi(argv[3]);
01836       if (max_jitter_buffer < 0)
01837          max_jitter_buffer = 0;
01838    } else {
01839       if (argc == 5) {
01840          if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < IAX_MAX_CALLS)) {
01841             if (iaxs[atoi(argv[3])]) {
01842                iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]);
01843                if (iaxs[atoi(argv[3])]->jitterbuffer < 0)
01844                   iaxs[atoi(argv[3])]->jitterbuffer = 0;
01845             } else
01846                ast_cli(fd, "No such call '%d'\n", atoi(argv[3]));
01847          } else
01848             ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3]));
01849       }
01850    }
01851    return RESULT_SUCCESS;
01852 #endif
01853 }

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

Definition at line 3124 of file chan_iax2.c.

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

03125 {
03126    struct ast_option_header *h;
03127    int res;
03128 
03129    switch (option) {
03130    case AST_OPTION_TXGAIN:
03131    case AST_OPTION_RXGAIN:
03132       /* these two cannot be sent, because they require a result */
03133       errno = ENOSYS;
03134       return -1;
03135    default:
03136       h = malloc(datalen + sizeof(*h));
03137       if (h) {
03138          h->flag = AST_OPTION_FLAG_REQUEST;
03139          h->option = htons(option);
03140          memcpy(h->data, data, datalen);
03141          res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03142                     AST_CONTROL_OPTION, 0, (unsigned char *) h,
03143                     datalen + sizeof(*h), -1);
03144          free(h);
03145          return res;
03146       } else {
03147          ast_log(LOG_WARNING, "Out of memory\n");
03148          return -1;
03149       }
03150    }
03151 }

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

Definition at line 2059 of file chan_iax2.c.

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

02060 {
02061    struct iax2_dpcache *dp;
02062    char tmp[1024], *pc;
02063    int s;
02064    int x,y;
02065    struct timeval tv;
02066    gettimeofday(&tv, NULL);
02067    ast_mutex_lock(&dpcache_lock);
02068    dp = dpcache;
02069    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02070    while(dp) {
02071       s = dp->expiry.tv_sec - tv.tv_sec;
02072       tmp[0] = '\0';
02073       if (dp->flags & CACHE_FLAG_EXISTS)
02074          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02075       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02076          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02077       if (dp->flags & CACHE_FLAG_CANEXIST)
02078          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02079       if (dp->flags & CACHE_FLAG_PENDING)
02080          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02081       if (dp->flags & CACHE_FLAG_TIMEOUT)
02082          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02083       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02084          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02085       if (dp->flags & CACHE_FLAG_MATCHMORE)
02086          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02087       if (dp->flags & CACHE_FLAG_UNKNOWN)
02088          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02089       /* Trim trailing pipe */
02090       if (!ast_strlen_zero(tmp))
02091          tmp[strlen(tmp) - 1] = '\0';
02092       else
02093          ast_copy_string(tmp, "(none)", sizeof(tmp));
02094       y=0;
02095       pc = strchr(dp->peercontext, '@');
02096       if (!pc)
02097          pc = dp->peercontext;
02098       else
02099          pc++;
02100       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02101          if (dp->waiters[x] > -1)
02102             y++;
02103       if (s > 0)
02104          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02105       else
02106          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02107       dp = dp->next;
02108    }
02109    ast_mutex_unlock(&dpcache_lock);
02110    return RESULT_SUCCESS;
02111 }

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

Definition at line 4434 of file chan_iax2.c.

References iax2_registry::addr, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_strlen_zero(), ast_test_flag, iax2_registry::callno, jb_info::current, FORMAT, FORMAT2, FORMATB, IAX_MAX_CALLS, IAX_USEJITTERBUF, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, RESULT_SHOWUSAGE, and username.

04435 {
04436 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04437 #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"
04438 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04439    int x;
04440    int numchans = 0;
04441    char iabuf[INET_ADDRSTRLEN];
04442 
04443    if (argc != 3)
04444       return RESULT_SHOWUSAGE;
04445    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04446    for (x=0;x<IAX_MAX_CALLS;x++) {
04447       ast_mutex_lock(&iaxsl[x]);
04448       if (iaxs[x]) {
04449 #ifdef BRIDGE_OPTIMIZATION
04450          if (iaxs[x]->bridgecallno)
04451             ast_cli(fd, FORMATB,
04452                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04453                   ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 
04454                   !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 
04455                   iaxs[x]->callno, iaxs[x]->peercallno, 
04456                   iaxs[x]->oseqno, iaxs[x]->iseqno, 
04457                   iaxs[x]->bridgecallno );
04458          else
04459 #endif
04460          {
04461             int lag, jitter, localdelay;
04462 #ifdef NEWJB
04463             jb_info jbinfo;
04464 
04465             if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04466                jb_getinfo(iaxs[x]->jb, &jbinfo);
04467                jitter = jbinfo.jitter;
04468                localdelay = jbinfo.current - jbinfo.min;
04469             } else {
04470                jitter = -1;
04471                localdelay = 0;
04472             }
04473 #else
04474             jitter = iaxs[x]->jitter;
04475             localdelay = ast_test_flag(iaxs[x], IAX_USEJITTERBUF) ? jitterbufsize(iaxs[x]) : 0;
04476 #endif
04477             lag = iaxs[x]->remote_rr.delay;
04478             ast_cli(fd, FORMAT,
04479                   iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04480                   ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[x]->addr.sin_addr), 
04481                   !ast_strlen_zero(iaxs[x]->username) ? iaxs[x]->username : "(None)", 
04482                   iaxs[x]->callno, iaxs[x]->peercallno, 
04483                   iaxs[x]->oseqno, iaxs[x]->iseqno, 
04484                   lag,
04485                   jitter,
04486                   localdelay,
04487                   ast_getformatname(iaxs[x]->voiceformat) );
04488          }
04489          numchans++;
04490       }
04491       ast_mutex_unlock(&iaxsl[x]);
04492    }
04493    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04494    return RESULT_SUCCESS;
04495 #undef FORMAT
04496 #undef FORMAT2
04497 #undef FORMATB
04498 }

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

Definition at line 4331 of file chan_iax2.c.

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

04332 {
04333 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04334 #if !defined(__FreeBSD__)
04335 #define FORMAT "%-15.15s  %-15d %-15d\n"
04336 #else /* __FreeBSD__ */
04337 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04338 #endif /* __FreeBSD__ */
04339    struct iax_firmware *cur;
04340    if ((argc != 3) && (argc != 4))
04341       return RESULT_SHOWUSAGE;
04342    ast_mutex_lock(&waresl.lock);
04343    
04344    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04345    for (cur = waresl.wares;cur;cur = cur->next) {
04346       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04347          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04348             (int)ntohl(cur->fwh->datalen));
04349    }
04350    ast_mutex_unlock(&waresl.lock);
04351    return RESULT_SUCCESS;
04352 #undef FORMAT
04353 #undef FORMAT2
04354 }

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

Definition at line 4580 of file chan_iax2.c.

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

04581 {
04582    int numchans = 0;
04583    if (argc != 3)
04584       return RESULT_SHOWUSAGE;
04585    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04586    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04587    numchans = ast_cli_netstats(fd, 1);
04588    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04589    return RESULT_SUCCESS;
04590 }

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

Definition at line 1955 of file chan_iax2.c.

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

01956 {
01957    char status[30];
01958    char cbuf[256];
01959    char iabuf[INET_ADDRSTRLEN];
01960    struct iax2_peer *peer;
01961    char codec_buf[512];
01962    int x = 0, codec = 0, load_realtime = 0;
01963 
01964    if (argc < 4)
01965       return RESULT_SHOWUSAGE;
01966 
01967    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
01968 
01969    peer = find_peer(argv[3], load_realtime);
01970    if (peer) {
01971       ast_cli(fd,"\n\n");
01972       ast_cli(fd, "  * Name       : %s\n", peer->name);
01973       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
01974       ast_cli(fd, "  Context      : %s\n", peer->context);
01975       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
01976       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
01977       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
01978       ast_cli(fd, "  Expire       : %d\n", peer->expire);
01979       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
01980       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
01981       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
01982       ast_cli(fd, "  Username     : %s\n", peer->username);
01983       ast_cli(fd, "  Codecs       : ");
01984       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
01985       ast_cli(fd, "%s\n", codec_buf);
01986 
01987       ast_cli(fd, "  Codec Order  : (");
01988       for(x = 0; x < 32 ; x++) {
01989          codec = ast_codec_pref_index(&peer->prefs,x);
01990          if(!codec)
01991             break;
01992          ast_cli(fd, "%s", ast_getformatname(codec));
01993          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
01994             ast_cli(fd, "|");
01995       }
01996 
01997       if (!x)
01998          ast_cli(fd, "none");
01999       ast_cli(fd, ")\n");
02000 
02001       ast_cli(fd, "  Status       : ");
02002       peer_status(peer, status, sizeof(status));   
02003       ast_cli(fd, "%s\n",status);
02004       ast_cli(fd, " Qualify        : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02005       ast_cli(fd,"\n");
02006       if (ast_test_flag(peer, IAX_TEMPONLY))
02007          destroy_peer(peer);
02008    } else {
02009       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02010       ast_cli(fd,"\n");
02011    }
02012 
02013    return RESULT_SUCCESS;
02014 }

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

Definition at line 4320 of file chan_iax2.c.

References __iax2_show_peers().

04321 {
04322    return __iax2_show_peers(0, fd, argc, argv);
04323 }

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

Definition at line 4392 of file chan_iax2.c.

References iax2_registry::addr, ast_cli(), ast_inet_ntoa(), ast_mutex_lock(), FORMAT, FORMAT2, ast_peer_list::lock, iax2_registry::next, peerl, iax2_registry::refresh, registrations, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, iax2_registry::us, and iax2_registry::username.

04393 {
04394 #define FORMAT2 "%-20.20s  %-10.10s  %-20.20s %8.8s  %s\n"
04395 #define FORMAT "%-20.20s  %-10.10s  %-20.20s %8d  %s\n"
04396    struct iax2_registry *reg;
04397    char host[80];
04398    char perceived[80];
04399    char iabuf[INET_ADDRSTRLEN];
04400    if (argc != 3)
04401       return RESULT_SHOWUSAGE;
04402    ast_mutex_lock(&peerl.lock);
04403    ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
04404    for (reg = registrations;reg;reg = reg->next) {
04405       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04406       if (reg->us.sin_addr.s_addr) 
04407          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
04408       else
04409          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04410       ast_cli(fd, FORMAT, host, 
04411                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04412    }
04413    ast_mutex_unlock(&peerl.lock);
04414    return RESULT_SUCCESS;
04415 #undef FORMAT
04416 #undef FORMAT2
04417 }

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

Definition at line 2039 of file chan_iax2.c.

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

02040 {
02041    struct iax_frame *cur;
02042    int cnt = 0, dead=0, final=0;
02043    if (argc != 3)
02044       return RESULT_SHOWUSAGE;
02045    for (cur = iaxq.head; cur ; cur = cur->next) {
02046       if (cur->retries < 0)
02047          dead++;
02048       if (cur->final)
02049          final++;
02050       cnt++;
02051    }
02052    ast_cli(fd, "    IAX Statistics\n");
02053    ast_cli(fd, "---------------------\n");
02054    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02055    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
02056    return RESULT_SUCCESS;
02057 }

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

Definition at line 4153 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_test_flag, context, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_user_list::lock, RESULT_SHOWUSAGE, RESULT_SUCCESS, user, userl, and ast_user_list::users.

04154 {
04155    regex_t regexbuf;
04156    int havepattern = 0;
04157 
04158 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04159 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04160 
04161    struct iax2_user *user;
04162    char auth[90];
04163    char *pstr = "";
04164 
04165    switch (argc) {
04166    case 5:
04167       if (!strcasecmp(argv[3], "like")) {
04168          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04169             return RESULT_SHOWUSAGE;
04170          havepattern = 1;
04171       } else
04172          return RESULT_SHOWUSAGE;
04173    case 3:
04174       break;
04175    default:
04176       return RESULT_SHOWUSAGE;
04177    }
04178 
04179    ast_mutex_lock(&userl.lock);
04180    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04181    for(user=userl.users;user;user=user->next) {
04182       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04183          continue;
04184 
04185       if (!ast_strlen_zero(user->secret)) {
04186          ast_copy_string(auth,user->secret,sizeof(auth));
04187       } else if (!ast_strlen_zero(user->inkeys)) {
04188          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04189       } else
04190          ast_copy_string(auth, "-no secret-", sizeof(auth));
04191 
04192       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04193          pstr = "REQ Only";
04194       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04195          pstr = "Disabled";
04196       else
04197          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04198 
04199       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04200             user->contexts ? user->contexts->context : context,
04201             user->ha ? "Yes" : "No", pstr);
04202 
04203    }
04204    ast_mutex_unlock(&userl.lock);
04205 
04206    if (havepattern)
04207       regfree(&regexbuf);
04208 
04209    return RESULT_SUCCESS;
04210 #undef FORMAT
04211 #undef FORMAT2
04212 }

static int iax2_start_transfer unsigned short  callno0,
unsigned short  callno1
[static]
 

Definition at line 3160 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, send_command(), and TRANSFER_BEGIN.

03161 {
03162    int res;
03163    struct iax_ie_data ied0;
03164    struct iax_ie_data ied1;
03165    unsigned int transferid = rand();
03166    memset(&ied0, 0, sizeof(ied0));
03167    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03168    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03169    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03170 
03171    memset(&ied1, 0, sizeof(ied1));
03172    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03173    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03174    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03175    
03176    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03177    if (res)
03178       return -1;
03179    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03180    if (res)
03181       return -1;
03182    iaxs[callno0]->transferring = TRANSFER_BEGIN;
03183    iaxs[callno1]->transferring = TRANSFER_BEGIN;
03184    return 0;
03185 }

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

Definition at line 1886 of file chan_iax2.c.

References RESULT_SHOWUSAGE, RESULT_SUCCESS, and test_losspct.

01887 {
01888        if (argc != 4)
01889                return RESULT_SHOWUSAGE;
01890 
01891        test_losspct = atoi(argv[3]);
01892 
01893        return RESULT_SUCCESS;
01894 }

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

Definition at line 3385 of file chan_iax2.c.

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

03386 {
03387    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03388    struct iax_ie_data ied;
03389    char tmp[256], *context;
03390    ast_copy_string(tmp, dest, sizeof(tmp));
03391    context = strchr(tmp, '@');
03392    if (context) {
03393       *context = '\0';
03394       context++;
03395    }
03396    memset(&ied, 0, sizeof(ied));
03397    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03398    if (context)
03399       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03400    if (option_debug)
03401       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03402    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03403 }

static int iax2_transmit struct iax_frame fr  )  [static]
 

Definition at line 2536 of file chan_iax2.c.

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

Referenced by iax2_send().

02537 {
02538    /* Lock the queue and place this packet at the end */
02539    fr->next = NULL;
02540    fr->prev = NULL;
02541    /* By setting this to 0, the network thread will send it for us, and
02542       queue retransmission if necessary */
02543    fr->sentyet = 0;
02544    ast_mutex_lock(&iaxq.lock);
02545    if (!iaxq.head) {
02546       /* Empty queue */
02547       iaxq.head = fr;
02548       iaxq.tail = fr;
02549    } else {
02550       /* Double link */
02551       iaxq.tail->next = fr;
02552       fr->prev = iaxq.tail;
02553       iaxq.tail = fr;
02554    }
02555    iaxq.count++;
02556    ast_mutex_unlock(&iaxq.lock);
02557    /* Wake up the network thread */
02558    pthread_kill(netthreadid, SIGURG);
02559    return 0;
02560 }

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

Definition at line 6069 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

06070 {
06071    /* Drop when trunk is about 5 seconds idle */
06072    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06073       return 1;
06074    return 0;
06075 }

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

Definition at line 3755 of file chan_iax2.c.

References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, realloc, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.

Referenced by iax2_send().

03756 {
03757    struct ast_frame *f;
03758    struct iax2_trunk_peer *tpeer;
03759    void *tmp, *ptr;
03760    struct ast_iax2_meta_trunk_entry *met;
03761    struct ast_iax2_meta_trunk_mini *mtm;
03762    char iabuf[INET_ADDRSTRLEN];
03763 
03764    f = &fr->af;
03765    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03766    if (tpeer) {
03767       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03768          /* Need to reallocate space */
03769          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03770             tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE);
03771             if (tmp) {
03772                tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03773                tpeer->trunkdata = tmp;
03774                ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
03775             } else {
03776                ast_log(LOG_WARNING, "Insufficient memory to expand trunk data to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03777                ast_mutex_unlock(&tpeer->lock);
03778                return -1;
03779             }
03780          } else {
03781             ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03782             ast_mutex_unlock(&tpeer->lock);
03783             return -1;
03784          }
03785       }
03786 
03787       /* Append to meta frame */
03788       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03789       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03790          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03791          mtm->len = htons(f->datalen);
03792          mtm->mini.callno = htons(pvt->callno);
03793          mtm->mini.ts = htons(0xffff & fr->ts);
03794          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03795          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03796       } else {
03797          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03798          /* Store call number and length in meta header */
03799          met->callno = htons(pvt->callno);
03800          met->len = htons(f->datalen);
03801          /* Advance pointers/decrease length past trunk entry header */
03802          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03803          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03804       }
03805       /* Copy actual trunk data */
03806       memcpy(ptr, f->data, f->datalen);
03807       tpeer->trunkdatalen += f->datalen;
03808 
03809       tpeer->calls++;
03810       ast_mutex_unlock(&tpeer->lock);
03811    }
03812    return 0;
03813 }

static int iax2_vnak int  callno  )  [static]
 

Definition at line 5997 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().

Referenced by socket_read().

05998 {
05999    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06000 }

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

Definition at line 4651 of file chan_iax2.c.

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

04652 {
04653    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04654    int res = -1;
04655    ast_mutex_lock(&iaxsl[callno]);
04656    if (iaxs[callno]) {
04657    /* If there's an outstanding error, return failure now */
04658       if (!iaxs[callno]->error) {
04659          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04660             res = 0;
04661             /* Don't waste bandwidth sending null frames */
04662          else if (f->frametype == AST_FRAME_NULL)
04663             res = 0;
04664          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04665             res = 0;
04666          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04667             res = 0;
04668          else
04669          /* Simple, just queue for transmission */
04670             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04671       } else {
04672          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04673       }
04674    }
04675    /* If it's already gone, just return */
04676    ast_mutex_unlock(&iaxsl[callno]);
04677    return res;
04678 }

static int iax_check_version char *  dev  )  [static]
 

Definition at line 1315 of file chan_iax2.c.

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

Referenced by update_registry().

01316 {
01317    int res = 0;
01318    struct iax_firmware *cur;
01319    if (!ast_strlen_zero(dev)) {
01320       ast_mutex_lock(&waresl.lock);
01321       cur = waresl.wares;
01322       while(cur) {
01323          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01324             res = ntohs(cur->fwh->version);
01325             break;
01326          }
01327          cur = cur->next;
01328       }
01329       ast_mutex_unlock(&waresl.lock);
01330    }
01331    return res;
01332 }

static void iax_debug_output const char *  data  )  [static]
 

Definition at line 675 of file chan_iax2.c.

References ast_verbose().

Referenced by load_module().

00676 {
00677    if (iaxdebug)
00678       ast_verbose("%s", data);
00679 }

static void iax_error_output const char *  data  )  [static]
 

Definition at line 681 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

00682 {
00683    ast_log(LOG_WARNING, "%s", data);
00684 }

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

Definition at line 1334 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, ast_firmware_list::lock, iax_firmware::next, ast_firmware_list::wares, and waresl.

Referenced by socket_read().

01335 {
01336    int res = -1;
01337    unsigned int bs = desc & 0xff;
01338    unsigned int start = (desc >> 8) & 0xffffff;
01339    unsigned int bytes;
01340    struct iax_firmware *cur;
01341    if (!ast_strlen_zero((char *)dev) && bs) {
01342       start *= bs;
01343       ast_mutex_lock(&waresl.lock);
01344       cur = waresl.wares;
01345       while(cur) {
01346          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01347             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01348             if (start < ntohl(cur->fwh->datalen)) {
01349                bytes = ntohl(cur->fwh->datalen) - start;
01350                if (bytes > bs)
01351                   bytes = bs;
01352                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01353             } else {
01354                bytes = 0;
01355                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01356             }
01357             if (bytes == bs)
01358                res = 0;
01359             else
01360                res = 1;
01361             break;
01362          }
01363          cur = cur->next;
01364       }
01365       ast_mutex_unlock(&waresl.lock);
01366    }
01367    return res;
01368 }

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

Definition at line 6248 of file chan_iax2.c.

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

Referenced by socket_read().

06249 {
06250    struct iax_dual *d;
06251    struct ast_channel *chan1m, *chan2m;
06252    pthread_t th;
06253    chan1m = ast_channel_alloc(0);
06254    chan2m = ast_channel_alloc(0);
06255    if (chan2m && chan1m) {
06256       snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
06257       /* Make formats okay */
06258       chan1m->readformat = chan1->readformat;
06259       chan1m->writeformat = chan1->writeformat;
06260       ast_channel_masquerade(chan1m, chan1);
06261       /* Setup the extensions and such */
06262       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06263       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06264       chan1m->priority = chan1->priority;
06265       
06266       /* We make a clone of the peer channel too, so we can play
06267          back the announcement */
06268       snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name);
06269       /* Make formats okay */
06270       chan2m->readformat = chan2->readformat;
06271       chan2m->writeformat = chan2->writeformat;
06272       ast_channel_masquerade(chan2m, chan2);
06273       /* Setup the extensions and such */
06274       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06275       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06276       chan2m->priority = chan2->priority;
06277       if (ast_do_masquerade(chan2m)) {
06278          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06279          ast_hangup(chan2m);
06280          return -1;
06281       }
06282    } else {
06283       if (chan1m)
06284          ast_hangup(chan1m);
06285       if (chan2m)
06286          ast_hangup(chan2m);
06287       return -1;
06288    }
06289    d = malloc(sizeof(struct iax_dual));
06290    if (d) {
06291       memset(d, 0, sizeof(*d));
06292       d->chan1 = chan1m;
06293       d->chan2 = chan2m;
06294       if (!ast_pthread_create(&th, NULL, iax_park_thread, d))
06295          return 0;
06296       free(d);
06297    }
06298    return -1;
06299 }

static void* iax_park_thread void *  stuff  )  [static]
 

Definition at line 6228 of file chan_iax2.c.

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

Referenced by iax_park().

06229 {
06230    struct ast_channel *chan1, *chan2;
06231    struct iax_dual *d;
06232    struct ast_frame *f;
06233    int ext;
06234    int res;
06235    d = stuff;
06236    chan1 = d->chan1;
06237    chan2 = d->chan2;
06238    free(d);
06239    f = ast_read(chan1);
06240    if (f)
06241       ast_frfree(f);
06242    res = ast_park_call(chan1, chan2, 0, &ext);
06243    ast_hangup(chan2);
06244    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06245    return NULL;
06246 }

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

Definition at line 942 of file chan_iax2.c.

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

Referenced by socket_read().

00943 {
00944    /* Malloc() a copy of a frame */
00945    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
00946    if (new) {
00947       memcpy(new, fr, sizeof(struct iax_frame));   
00948       iax_frame_wrap(new, &fr->af);
00949       new->data = NULL;
00950       new->datalen = 0;
00951       new->direction = DIRECTION_INGRESS;
00952       new->retrans = -1;
00953    }
00954    return new;
00955 }

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

Definition at line 711 of file chan_iax2.c.

References ast_verbose().

Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().

00712 {
00713    va_list args;
00714    char buf[1024];
00715 
00716    va_start(args, fmt);
00717    vsnprintf(buf, 1024, fmt, args);
00718    va_end(args);
00719 
00720    ast_verbose(buf);
00721 }

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

Definition at line 687 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

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

00688 {
00689    va_list args;
00690    char buf[1024];
00691 
00692    va_start(args, fmt);
00693    vsnprintf(buf, 1024, fmt, args);
00694    va_end(args);
00695 
00696    ast_log(LOG_ERROR, buf);
00697 }

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

Definition at line 699 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

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

00700 {
00701    va_list args;
00702    char buf[1024];
00703 
00704    va_start(args, fmt);
00705    vsnprintf(buf, 1024, fmt, args);
00706    va_end(args);
00707 
00708    ast_log(LOG_WARNING, buf);
00709 }

char* key void   ) 
 

Returns the ASTERISK_GPL_KEY.

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

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 9769 of file chan_iax2.c.

References ASTERISK_GPL_KEY.

09770 {
09771    return ASTERISK_GPL_KEY;
09772 }

int load_module void   ) 
 

Initialize the module.

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

Returns:
int Always 0.

Definition at line 9667 of file chan_iax2.c.

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

09668 {
09669    char *config = "iax.conf";
09670    int res = 0;
09671    int x;
09672    struct iax2_registry *reg;
09673    struct iax2_peer *peer;
09674    
09675    ast_custom_function_register(&iaxpeer_function);
09676 
09677    iax_set_output(iax_debug_output);
09678    iax_set_error(iax_error_output);
09679 #ifdef NEWJB
09680    jb_setoutput(jb_error_output, jb_warning_output, NULL);
09681 #endif
09682    
09683 #ifdef IAX_TRUNKING
09684 #ifdef ZT_TIMERACK
09685    timingfd = open("/dev/zap/timer", O_RDWR);
09686    if (timingfd < 0)
09687 #endif
09688       timingfd = open("/dev/zap/pseudo", O_RDWR);
09689    if (timingfd < 0) 
09690       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
09691 #endif      
09692 
09693    memset(iaxs, 0, sizeof(iaxs));
09694 
09695    for (x=0;x<IAX_MAX_CALLS;x++)
09696       ast_mutex_init(&iaxsl[x]);
09697    
09698    io = io_context_create();
09699    sched = sched_context_create();
09700    
09701    if (!io || !sched) {
09702       ast_log(LOG_ERROR, "Out of memory\n");
09703       return -1;
09704    }
09705 
09706    netsock = ast_netsock_list_alloc();
09707    if (!netsock) {
09708       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
09709       return -1;
09710    }
09711    ast_netsock_init(netsock);
09712 
09713    ast_mutex_init(&iaxq.lock);
09714    ast_mutex_init(&userl.lock);
09715    ast_mutex_init(&peerl.lock);
09716    ast_mutex_init(&waresl.lock);
09717    
09718    ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09719 
09720    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
09721    
09722    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
09723    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
09724 
09725    set_config(config, 0);
09726 
09727    if (ast_channel_register(&iax2_tech)) {
09728       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
09729       __unload_module();
09730       return -1;
09731    }
09732 
09733    if (ast_register_switch(&iax2_switch)) 
09734       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
09735 
09736    res = start_network_thread();
09737    if (!res) {
09738       if (option_verbose > 1) 
09739          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
09740    } else {
09741       ast_log(LOG_ERROR, "Unable to start network thread\n");
09742       ast_netsock_release(netsock);
09743    }
09744 
09745    for (reg = registrations; reg; reg = reg->next)
09746       iax2_do_register(reg);
09747    ast_mutex_lock(&peerl.lock);
09748    for (peer = peerl.peers; peer; peer = peer->next) {
09749       if (peer->sockfd < 0)
09750          peer->sockfd = defaultsockfd;
09751       iax2_poke_peer(peer, 0);
09752    }
09753    ast_mutex_unlock(&peerl.lock);
09754    reload_firmware();
09755    iax_provision_reload();
09756    return res;
09757 }

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

Definition at line 3187 of file chan_iax2.c.

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

Referenced by iax2_bridge().

03188 {
03189    ast_mutex_lock(&iaxsl[callno0]);
03190    while (ast_mutex_trylock(&iaxsl[callno1])) {
03191       ast_mutex_unlock(&iaxsl[callno0]);
03192       usleep(10);
03193       ast_mutex_lock(&iaxsl[callno0]);
03194    }
03195 }

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

Definition at line 1009 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, IAX_MAX_CALLS, iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_WARNING, MIN_REUSE_TIME, ping_time, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), and TRUNK_CALL_START.

Referenced by iax2_request(), and socket_read().

01010 {
01011    int x;
01012    int res= 0;
01013    struct timeval now;
01014    if (iaxs[callno]->oseqno) {
01015       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01016       return -1;
01017    }
01018    if (callno & TRUNK_CALL_START) {
01019       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01020       return -1;
01021    }
01022    gettimeofday(&now, NULL);
01023    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01024       ast_mutex_lock(&iaxsl[x]);
01025       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01026          iaxs[x] = iaxs[callno];
01027          iaxs[x]->callno = x;
01028          iaxs[callno] = NULL;
01029          /* Update the two timers that should have been started */
01030          if (iaxs[x]->pingid > -1)
01031             ast_sched_del(sched, iaxs[x]->pingid);
01032          if (iaxs[x]->lagid > -1)
01033             ast_sched_del(sched, iaxs[x]->lagid);
01034          iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01035          iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01036          if (locked)
01037             ast_mutex_unlock(&iaxsl[callno]);
01038          res = x;
01039          if (!locked)
01040             ast_mutex_unlock(&iaxsl[x]);
01041          break;
01042       }
01043       ast_mutex_unlock(&iaxsl[x]);
01044    }
01045    if (x >= IAX_MAX_CALLS - 1) {
01046       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01047       return -1;
01048    }
01049    ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01050    /* We move this call from a non-trunked to a trunked call */
01051    update_max_trunk();
01052    update_max_nontrunk();
01053    return res;
01054 }

static int manager_iax2_show_netstats struct mansession s,
struct message m
[static]
 

Definition at line 4324 of file chan_iax2.c.

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

Referenced by load_module().

04325 {
04326    ast_cli_netstats(s->fd, 0);
04327    ast_cli(s->fd, "\r\n");
04328    return RESULT_SUCCESS;
04329 }

static int manager_iax2_show_peers struct mansession s,
struct message m
[static]
 

Definition at line 4357 of file chan_iax2.c.

References __iax2_show_peers(), ast_cli(), ast_strlen_zero(), astman_get_header(), id, and s.

Referenced by load_module().

04358 {
04359    char *a[] = { "iax2", "show", "users" };
04360    int ret;
04361    char *id;
04362    id = astman_get_header(m,"ActionID");
04363    if (!ast_strlen_zero(id))
04364       ast_cli(s->fd, "ActionID: %s\r\n",id);
04365    ret = __iax2_show_peers(1, s->fd, 3, a );
04366    ast_cli(s->fd, "\r\n\r\n" );
04367    return ret;
04368 } /* /JDG */

static int match struct sockaddr_in *  sin,
unsigned short  callno,
unsigned short  dcallno,
struct chan_iax2_pvt cur
[static]
 

Definition at line 961 of file chan_iax2.c.

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

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

00962 {
00963    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
00964       (cur->addr.sin_port == sin->sin_port)) {
00965       /* This is the main host */
00966       if ((cur->peercallno == callno) ||
00967          ((dcallno == cur->callno) && !cur->peercallno)) {
00968          /* That's us.  Be sure we keep track of the peer call number */
00969          return 1;
00970       }
00971    }
00972    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
00973        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
00974       /* We're transferring */
00975       if (dcallno == cur->callno)
00976          return 1;
00977    }
00978    return 0;
00979 }

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

Definition at line 3821 of file chan_iax2.c.

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

Referenced by decode_frame().

03822 {
03823 #if 0
03824    /* Debug with "fake encryption" */
03825    int x;
03826    if (len % 16)
03827       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03828    for (x=0;x<len;x++)
03829       dst[x] = src[x] ^ 0xff;
03830 #else 
03831    unsigned char lastblock[16] = { 0 };
03832    int x;
03833    while(len > 0) {
03834       aes_decrypt(src, dst, dcx);
03835       for (x=0;x<16;x++)
03836          dst[x] ^= lastblock[x];
03837       memcpy(lastblock, src, sizeof(lastblock));
03838       dst += 16;
03839       src += 16;
03840       len -= 16;
03841    }
03842 #endif
03843 }

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

Definition at line 3845 of file chan_iax2.c.

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

Referenced by encrypt_frame().

03846 {
03847 #if 0
03848    /* Debug with "fake encryption" */
03849    int x;
03850    if (len % 16)
03851       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03852    for (x=0;x<len;x++)
03853       dst[x] = src[x] ^ 0xff;
03854 #else
03855    unsigned char curblock[16] = { 0 };
03856    int x;
03857    while(len > 0) {
03858       for (x=0;x<16;x++)
03859          curblock[x] ^= src[x];
03860       aes_encrypt(curblock, dst, ecx);
03861       memcpy(curblock, dst, sizeof(curblock)); 
03862       dst += 16;
03863       src += 16;
03864       len -= 16;
03865    }
03866 #endif
03867 }

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

Definition at line 4963 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.

Referenced by authenticate_reply(), and socket_read().

04964 {
04965    /* Select exactly one common encryption if there are any */
04966    p->encmethods &= enc;
04967    if (p->encmethods) {
04968       if (p->encmethods & IAX_ENCRYPT_AES128)
04969          p->encmethods = IAX_ENCRYPT_AES128;
04970       else
04971          p->encmethods = 0;
04972    }
04973 }

static void* network_thread void *  ignore  )  [static]
 

Definition at line 8042 of file chan_iax2.c.

References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_mutex_lock(), ast_iax2_queue::head, iaxq, io, ast_iax2_queue::lock, send_packet(), iax_frame::sentyet, timing_read(), and timingfd.

Referenced by start_network_thread().

08043 {
08044    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08045       from the network, and queue them for delivery to the channels */
08046    int res, count;
08047    struct iax_frame *f, *freeme;
08048    if (timingfd > -1)
08049       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08050    for(;;) {
08051       /* Go through the queue, sending messages which have not yet been
08052          sent, and scheduling retransmissions if appropriate */
08053       ast_mutex_lock(&iaxq.lock);
08054       f = iaxq.head;
08055       count = 0;
08056       while(f) {
08057          freeme = NULL;
08058          if (!f->sentyet) {
08059             f->sentyet++;
08060             /* Send a copy immediately -- errors here are ok, so don't bother locking */
08061             if (iaxs[f->callno]) {
08062                send_packet(f);
08063                count++;
08064             } 
08065             if (f->retries < 0) {
08066                /* This is not supposed to be retransmitted */
08067                if (f->prev) 
08068                   f->prev->next = f->next;
08069                else
08070                   iaxq.head = f->next;
08071                if (f->next)
08072                   f->next->prev = f->prev;
08073                else
08074                   iaxq.tail = f->prev;
08075                iaxq.count--;
08076                /* Free the iax frame */
08077                freeme = f;
08078             } else {
08079                /* We need reliable delivery.  Schedule a retransmission */
08080                f->retries++;
08081                f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08082             }
08083          }
08084          f = f->next;
08085          if (freeme)
08086             iax_frame_free(freeme);
08087       }
08088       ast_mutex_unlock(&iaxq.lock);
08089       if (count >= 20)
08090          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08091 
08092       /* Now do the IO, and run scheduled tasks */
08093       res = ast_sched_wait(sched);
08094       if ((res > 1000) || (res < 0))
08095          res = 1000;
08096       res = ast_io_wait(io, res);
08097       if (res >= 0) {
08098          if (res >= 20)
08099             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08100          count = ast_sched_runq(sched);
08101          if (count >= 20)
08102             ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08103       }
08104    }
08105    return NULL;
08106 }

static struct chan_iax2_pvt* new_iax struct sockaddr_in *  sin,
int  lockpeer,
const char *  host
[static]
 

Definition at line 907 of file chan_iax2.c.

References jb_new(), jb_setconf(), malloc, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, maxjitterbuffer, maxjitterinterps, prefs, jb_conf::resync_threshold, and resyncthreshold.

00908 {
00909    struct chan_iax2_pvt *tmp;
00910    tmp = malloc(sizeof(struct chan_iax2_pvt));
00911    if (tmp) {
00912       memset(tmp, 0, sizeof(struct chan_iax2_pvt));
00913       tmp->prefs = prefs;
00914       tmp->callno = 0;
00915       tmp->peercallno = 0;
00916       tmp->transfercallno = 0;
00917       tmp->bridgecallno = 0;
00918       tmp->pingid = -1;
00919       tmp->lagid = -1;
00920       tmp->autoid = -1;
00921       tmp->authid = -1;
00922       tmp->initid = -1;
00923       /* ast_copy_string(tmp->context, context, sizeof(tmp->context)); */
00924       ast_copy_string(tmp->exten, "s", sizeof(tmp->exten));
00925       ast_copy_string(tmp->host, host, sizeof(tmp->host));
00926 #ifdef NEWJB
00927       {
00928          jb_conf jbconf;
00929 
00930          tmp->jb = jb_new();
00931          tmp->jbid = -1;
00932          jbconf.max_jitterbuf = maxjitterbuffer;
00933          jbconf.resync_threshold = resyncthreshold;
00934          jbconf.max_contig_interp = maxjitterinterps;
00935          jb_setconf(tmp->jb,&jbconf);
00936       }
00937 #endif
00938    }
00939    return tmp;
00940 }

static void parse_dial_string char *  data,
struct parsed_dial_string pds
[static]
 

Parses an IAX dial string into its component parts.

Parameters:
data the string to be parsed
pds pointer to a struct parsed_dial_string to be filled in
Returns:
nothing
This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.

Note:
This function supports both plaintext passwords and RSA key names; if the password string is formatted as '[keyname]', then the keyname will be placed into the key field, and the password field will be set to NULL.

The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]

Definition at line 2922 of file chan_iax2.c.

References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, strsep(), and parsed_dial_string::username.

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

02923 {
02924    if (ast_strlen_zero(data))
02925       return;
02926 
02927    pds->peer = strsep(&data, "/");
02928    pds->exten = strsep(&data, "/");
02929    pds->options = data;
02930 
02931    if (pds->exten) {
02932       data = pds->exten;
02933       pds->exten = strsep(&data, "@");
02934       pds->context = data;
02935    }
02936 
02937    if (strchr(pds->peer, '@')) {
02938       data = pds->peer;
02939       pds->username = strsep(&data, "@");
02940       pds->peer = data;
02941    }
02942 
02943    if (pds->username) {
02944       data = pds->username;
02945       pds->username = strsep(&data, ":");
02946       pds->password = data;
02947    }
02948 
02949    data = pds->peer;
02950    pds->peer = strsep(&data, ":");
02951    pds->port = data;
02952 
02953    /* check for a key name wrapped in [] in the secret position, if found,
02954       move it to the key field instead
02955    */
02956    if (pds->password && (pds->password[0] == '[')) {
02957       pds->key = ast_strip_quoted(pds->password, "[", "]");
02958       pds->password = NULL;
02959    }
02960 }

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

Definition at line 8167 of file chan_iax2.c.

References ast_get_ip(), ast_log(), ast_netsock_find(), ast_netsock_sockfd(), ast_strdupa, check_srcaddr(), defaultsockfd, IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, netsock, iax2_peer::sockfd, and strsep().

Referenced by build_peer().

08168 {
08169    struct sockaddr_in sin;
08170    int nonlocal = 1;
08171    int port = IAX_DEFAULT_PORTNO;
08172    int sockfd = defaultsockfd;
08173    char *tmp;
08174    char *addr;
08175    char *portstr;
08176 
08177    tmp = ast_strdupa(srcaddr);
08178    if (!tmp) {
08179       ast_log(LOG_WARNING, "Out of memory!\n");
08180       return -1;
08181    }
08182 
08183    addr = strsep(&tmp, ":");
08184    portstr = tmp;
08185 
08186    if (portstr) {
08187       port = atoi(portstr);
08188       if (port < 1)
08189          port = IAX_DEFAULT_PORTNO;
08190    }
08191    
08192    if (!ast_get_ip(&sin, addr)) {
08193       struct ast_netsock *sock;
08194       int res;
08195 
08196       sin.sin_port = 0;
08197       sin.sin_family = AF_INET;
08198       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08199       if (res == 0) {
08200          /* ip address valid. */
08201          sin.sin_port = htons(port);
08202          sock = ast_netsock_find(netsock, &sin);
08203          if (sock) {
08204             sockfd = ast_netsock_sockfd(sock);
08205             nonlocal = 0;
08206          }
08207       }
08208    }
08209       
08210    peer->sockfd = sockfd;
08211 
08212    if (nonlocal) {
08213       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08214          srcaddr, peer->name);
08215       return -1;
08216    } else {
08217       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08218       return 0;
08219    }
08220 }

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

peer_status: Report Peer status in character string

Definition at line 1932 of file chan_iax2.c.

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

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

01933 {
01934    int res = 0;
01935    if (peer->maxms) {
01936       if (peer->lastms < 0) {
01937          ast_copy_string(status, "UNREACHABLE", statuslen);
01938       } else if (peer->lastms > peer->maxms) {
01939          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
01940          res = 1;
01941       } else if (peer->lastms) {
01942          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
01943          res = 1;
01944       } else {
01945          ast_copy_string(status, "UNKNOWN", statuslen);
01946       }
01947    } else { 
01948       ast_copy_string(status, "Unmonitored", statuslen);
01949       res = -1;
01950    }
01951    return res;
01952 }

static void prune_peers void   )  [static]
 

Definition at line 2186 of file chan_h323.c.

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

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

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

static void prune_users void   )  [static]
 

Definition at line 8623 of file chan_iax2.c.

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

08624 {
08625    struct iax2_user *user, *usernext, *userlast = NULL;
08626    ast_mutex_lock(&userl.lock);
08627    for (user=userl.users;user;) {
08628       usernext = user->next;
08629       if (ast_test_flag(user, IAX_DELME)) {
08630          destroy_user(user);
08631          if (userlast)
08632             userlast->next = usernext;
08633          else
08634             userl.users = usernext;
08635       } else
08636          userlast = user;
08637       user = usernext;
08638    }
08639    ast_mutex_unlock(&userl.lock);
08640 }

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

Definition at line 4942 of file chan_iax2.c.

References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), iaxdebug, ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.

Referenced by socket_read().

04943 {
04944    struct ast_iax2_full_hdr fh;
04945    char iabuf[INET_ADDRSTRLEN];
04946    fh.scallno = htons(src | IAX_FLAG_FULL);
04947    fh.dcallno = htons(dst);
04948    fh.ts = 0;
04949    fh.oseqno = 0;
04950    fh.iseqno = 0;
04951    fh.type = AST_FRAME_IAX;
04952    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04953    if (iaxdebug)
04954        iax_showframe(NULL, &fh, 0, sin, 0);
04955 #if 0
04956    if (option_debug)
04957 #endif   
04958       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04959          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst);
04960    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04961 }

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

Definition at line 2605 of file chan_iax2.c.

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

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

02606 {
02607    struct ast_variable *var;
02608    struct ast_variable *tmp;
02609    struct iax2_peer *peer=NULL;
02610    time_t regseconds, nowtime;
02611    int dynamic=0;
02612 
02613    if (peername)
02614       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02615    else {
02616       char iabuf[INET_ADDRSTRLEN];
02617       char porta[25];
02618       ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr);
02619       sprintf(porta, "%d", ntohs(sin->sin_port));
02620       var = ast_load_realtime("iaxpeers", "ipaddr", iabuf, "port", porta, NULL);
02621       if (var) {
02622          /* We'll need the peer name in order to build the structure! */
02623          tmp = var;
02624          while(tmp) {
02625             if (!strcasecmp(tmp->name, "name"))
02626                peername = tmp->value;
02627             tmp = tmp->next;
02628          }
02629       }
02630    }
02631    if (!var)
02632       return NULL;
02633 
02634    peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02635    
02636    if (!peer)
02637       return NULL;
02638 
02639    tmp = var;
02640    while(tmp) {
02641       /* Make sure it's not a user only... */
02642       if (!strcasecmp(tmp->name, "type")) {
02643          if (strcasecmp(tmp->value, "friend") &&
02644              strcasecmp(tmp->value, "peer")) {
02645             /* Whoops, we weren't supposed to exist! */
02646             destroy_peer(peer);
02647             peer = NULL;
02648             break;
02649          } 
02650       } else if (!strcasecmp(tmp->name, "regseconds")) {
02651          if (sscanf(tmp->value, "%ld", (time_t *)&regseconds) != 1)
02652             regseconds = 0;
02653       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02654          inet_aton(tmp->value, &(peer->addr.sin_addr));
02655       } else if (!strcasecmp(tmp->name, "port")) {
02656          peer->addr.sin_port = htons(atoi(tmp->value));
02657       } else if (!strcasecmp(tmp->name, "host")) {
02658          if (!strcasecmp(tmp->value, "dynamic"))
02659             dynamic = 1;
02660       }
02661       tmp = tmp->next;
02662    }
02663    if (!peer)
02664       return NULL;
02665 
02666    ast_variables_destroy(var);
02667 
02668    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02669       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02670       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02671          if (peer->expire > -1)
02672             ast_sched_del(sched, peer->expire);
02673          peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer);
02674       }
02675       ast_mutex_lock(&peerl.lock);
02676       peer->next = peerl.peers;
02677       peerl.peers = peer;
02678       ast_mutex_unlock(&peerl.lock);
02679       if (ast_test_flag(peer, IAX_DYNAMIC))
02680          reg_source_db(peer);
02681    } else {
02682       ast_set_flag(peer, IAX_TEMPONLY);   
02683    }
02684 
02685    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02686       time(&nowtime);
02687       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02688          memset(&peer->addr, 0, sizeof(peer->addr));
02689          realtime_update_peer(peer->name, &peer->addr, 0);
02690          if (option_debug)
02691             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02692                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02693       }
02694       else {
02695          if (option_debug)
02696             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02697                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02698       }
02699    }
02700 
02701    return peer;
02702 }

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

Definition at line 2745 of file chan_iax2.c.

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

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

02746 {
02747         char port[10];
02748         char ipaddr[20];
02749         char regseconds[20];
02750    
02751         snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02752         ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
02753         snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02754         ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL);
02755 }

static struct iax2_user* realtime_user const char *  username  )  [static]
 

Definition at line 2704 of file chan_iax2.c.

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

Referenced by check_access(), and find_user().

02705 {
02706    struct ast_variable *var;
02707    struct ast_variable *tmp;
02708    struct iax2_user *user=NULL;
02709 
02710    var = ast_load_realtime("iaxusers", "name", username, NULL);
02711    if (!var)
02712       return NULL;
02713 
02714    tmp = var;
02715    while(tmp) {
02716       /* Make sure it's not a peer only... */
02717       if (!strcasecmp(tmp->name, "type")) {
02718          if (strcasecmp(tmp->value, "friend") &&
02719              strcasecmp(tmp->value, "user")) {
02720             return NULL;
02721          } 
02722       }
02723       tmp = tmp->next;
02724    }
02725 
02726    user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02727    if (!user)
02728       return NULL;
02729 
02730    ast_variables_destroy(var);
02731 
02732    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02733       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02734       ast_mutex_lock(&userl.lock);
02735       user->next = userl.users;
02736       userl.users = user;
02737       ast_mutex_unlock(&userl.lock);
02738    } else {
02739       ast_set_flag(user, IAX_TEMPONLY);   
02740    }
02741 
02742    return user;
02743 }

static void reg_source_db struct iax2_peer p  )  [static]
 

Definition at line 5686 of file chan_iax2.c.

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

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

05687 {
05688    char data[80];
05689    struct in_addr in;
05690    char iabuf[INET_ADDRSTRLEN];
05691    char *c, *d;
05692    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05693       c = strchr(data, ':');
05694       if (c) {
05695          *c = '\0';
05696          c++;
05697          if (inet_aton(data, &in)) {
05698             d = strchr(c, ':');
05699             if (d) {
05700                *d = '\0';
05701                d++;
05702                if (option_verbose > 2)
05703                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05704                   ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d));
05705                iax2_poke_peer(p, 0);
05706                p->expiry = atoi(d);
05707                memset(&p->addr, 0, sizeof(p->addr));
05708                p->addr.sin_family = AF_INET;
05709                p->addr.sin_addr = in;
05710                p->addr.sin_port = htons(atoi(c));
05711                if (p->expire > -1)
05712                   ast_sched_del(sched, p->expire);
05713                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05714                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05715                if (iax2_regfunk)
05716                   iax2_regfunk(p->name, 1);
05717                register_peer_exten(p, 1);
05718             }              
05719                
05720          }
05721       }
05722    }
05723 }

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

Definition at line 5637 of file chan_iax2.c.

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

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

05638 {
05639    char multi[256];
05640    char *stringp, *ext;
05641    if (!ast_strlen_zero(regcontext)) {
05642       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
05643       stringp = multi;
05644       while((ext = strsep(&stringp, "&"))) {
05645          if (onoff) {
05646             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05647                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), FREE, channeltype);
05648          } else
05649             ast_context_remove_extension(regcontext, ext, 1, NULL);
05650       }
05651    }
05652 }

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

Verify inbound registration.

Definition at line 5103 of file chan_iax2.c.

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

Referenced by handle_request_register(), and socket_read().

05104 {
05105    char requeststr[256] = "";
05106    char peer[256] = "";
05107    char md5secret[256] = "";
05108    char rsasecret[256] = "";
05109    char secret[256] = "";
05110    char iabuf[INET_ADDRSTRLEN];
05111    struct iax2_peer *p;
05112    struct ast_key *key;
05113    char *keyn;
05114    int x;
05115    int expire = 0;
05116 
05117    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05118    iaxs[callno]->peer[0] = '\0';
05119    if (ies->username)
05120       ast_copy_string(peer, ies->username, sizeof(peer));
05121    if (ies->password)
05122       ast_copy_string(secret, ies->password, sizeof(secret));
05123    if (ies->md5_result)
05124       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05125    if (ies->rsa_result)
05126       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05127    if (ies->refresh)
05128       expire = ies->refresh;
05129 
05130    if (ast_strlen_zero(peer)) {
05131       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05132       return -1;
05133    }
05134    /* We release the lock for the call to prevent a deadlock, but it's okay because
05135       only the current thread could possibly make it go away or make changes */
05136    ast_mutex_unlock(&iaxsl[callno]);
05137    /* SLD: first call to lookup peer during registration */
05138    p = find_peer(peer, 1);
05139    ast_mutex_lock(&iaxsl[callno]);
05140 
05141    if (!p) {
05142       if (authdebug)
05143          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05144       return -1;
05145    }
05146 
05147    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05148       if (authdebug)
05149          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05150       if (ast_test_flag(p, IAX_TEMPONLY))
05151          destroy_peer(p);
05152       return -1;
05153    }
05154 
05155    if (!ast_apply_ha(p->ha, sin)) {
05156       if (authdebug)
05157          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
05158       if (ast_test_flag(p, IAX_TEMPONLY))
05159          destroy_peer(p);
05160       return -1;
05161    }
05162    ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret));
05163    ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys));
05164    /* Check secret against what we have on file */
05165    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05166       if (!ast_strlen_zero(p->inkeys)) {
05167          char tmpkeys[256];
05168          char *stringp=NULL;
05169          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05170          stringp=tmpkeys;
05171          keyn = strsep(&stringp, ":");
05172          while(keyn) {
05173             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05174             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05175                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05176                break;
05177             } else if (!key) 
05178                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05179             keyn = strsep(&stringp, ":");
05180          }
05181          if (!keyn) {
05182             if (authdebug)
05183                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05184             if (ast_test_flag(p, IAX_TEMPONLY))
05185                destroy_peer(p);
05186             return -1;
05187          }
05188       } else {
05189          if (authdebug)
05190             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05191          if (ast_test_flag(p, IAX_TEMPONLY))
05192             destroy_peer(p);
05193          return -1;
05194       }
05195    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05196       /* They've provided a plain text password and we support that */
05197       if (strcmp(secret, p->secret)) {
05198          if (authdebug)
05199             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
05200          if (ast_test_flag(p, IAX_TEMPONLY))
05201             destroy_peer(p);
05202          return -1;
05203       } else
05204          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05205    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05206       struct MD5Context md5;
05207       unsigned char digest[16];
05208       char *tmppw, *stringp;
05209       
05210       tmppw = ast_strdupa(p->secret);
05211       stringp = tmppw;
05212       while((tmppw = strsep(&stringp, ";"))) {
05213          MD5Init(&md5);
05214          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05215          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05216          MD5Final(digest, &md5);
05217          for (x=0;x<16;x++)
05218             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05219          if (!strcasecmp(requeststr, md5secret)) 
05220             break;
05221       }
05222       if (tmppw) {
05223          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05224       } else {
05225          if (authdebug)
05226             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name, requeststr, md5secret);
05227          if (ast_test_flag(p, IAX_TEMPONLY))
05228             destroy_peer(p);
05229          return -1;
05230       }
05231    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05232       if (authdebug)
05233          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05234       if (ast_test_flag(p, IAX_TEMPONLY))
05235          destroy_peer(p);
05236       return -1;
05237    }
05238    ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer));
05239    /* Choose lowest expiry number */
05240    if (expire && (expire < iaxs[callno]->expiry)) 
05241       iaxs[callno]->expiry = expire;
05242 
05243    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05244 
05245    if (ast_test_flag(p, IAX_TEMPONLY))
05246       destroy_peer(p);
05247    return 0;
05248    
05249 }

static int registry_authrequest char *  name,
int  callno
[static]
 

Definition at line 5833 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, IAX_TEMPONLY, LOG_WARNING, and send_command().

Referenced by socket_read().

05834 {
05835    struct iax_ie_data ied;
05836    struct iax2_peer *p;
05837    /* SLD: third call to find_peer in registration */
05838    p = find_peer(name, 1);
05839    if (p) {
05840       memset(&ied, 0, sizeof(ied));
05841       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05842       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05843          /* Build the challenge */
05844          snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand());
05845          iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05846       }
05847       iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05848       if (ast_test_flag(p, IAX_TEMPONLY))
05849          destroy_peer(p);
05850       return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05851    } 
05852    ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05853    return 0;
05854 }

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

Definition at line 5856 of file chan_iax2.c.

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

Referenced by socket_read().

05857 {
05858    struct iax2_registry *reg;
05859    /* Start pessimistic */
05860    struct iax_ie_data ied;
05861    char peer[256] = "";
05862    char iabuf[INET_ADDRSTRLEN];
05863    char challenge[256] = "";
05864    int res;
05865    int authmethods = 0;
05866    if (ies->authmethods)
05867       authmethods = ies->authmethods;
05868    if (ies->username)
05869       ast_copy_string(peer, ies->username, sizeof(peer));
05870    if (ies->challenge)
05871       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05872    memset(&ied, 0, sizeof(ied));
05873    reg = iaxs[callno]->reg;
05874    if (reg) {
05875          if (inaddrcmp(&reg->addr, sin)) {
05876             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05877             return -1;
05878          }
05879          if (ast_strlen_zero(reg->secret)) {
05880             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05881             reg->regstate = REG_STATE_NOAUTH;
05882             return -1;
05883          }
05884          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05885          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05886          if (reg->secret[0] == '[') {
05887             char tmpkey[256];
05888             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05889             tmpkey[strlen(tmpkey) - 1] = '\0';
05890             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05891          } else
05892             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05893          if (!res) {
05894             reg->regstate = REG_STATE_AUTHSENT;
05895             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05896          } else
05897             return -1;
05898          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05899    } else   
05900       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05901    return -1;
05902 }

static char* regstate2str int  regstate  )  [static]
 

Definition at line 4370 of file chan_iax2.c.

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

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

04371 {
04372    switch(regstate) {
04373    case REG_STATE_UNREGISTERED:
04374       return "Unregistered";
04375    case REG_STATE_REGSENT:
04376       return "Request Sent";
04377    case REG_STATE_AUTHSENT:
04378       return "Auth. Sent";
04379    case REG_STATE_REGISTERED:
04380       return "Registered";
04381    case REG_STATE_REJECTED:
04382       return "Rejected";
04383    case REG_STATE_TIMEOUT:
04384       return "Timeout";
04385    case REG_STATE_NOAUTH:
04386       return "No Authentication";
04387    default:
04388       return "Unknown";
04389    }
04390 }

int reload void   ) 
 

Reload stuff.

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

Returns:
The return value is not used.

Definition at line 8996 of file chan_iax2.c.

References reload_config().

08997 {
08998    return reload_config();
08999 }

static int reload_config void   )  [static]
 

Definition at line 1995 of file chan_h323.c.

References ahp, ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, config, default_context, format, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, global_options, h323_signalling_port, h323debug, hp, IPTOS_MINCOST, ast_variable::lineno, ast_alias_list::lock, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, secret, tos, update_common_options(), user, userbyalias, userl, ast_user_list::users, usingGk, ast_variable::value, and VERBOSE_PREFIX_2.

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

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

static void reload_firmware void   )  [static]
 

Definition at line 1371 of file chan_iax2.c.

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

Referenced by load_module().

01372 {
01373    struct iax_firmware *cur, *curl, *curp;
01374    DIR *fwd;
01375    struct dirent *de;
01376    char dir[256];
01377    char fn[256];
01378    /* Mark all as dead */
01379    ast_mutex_lock(&waresl.lock);
01380    cur = waresl.wares;
01381    while(cur) {
01382       cur->dead = 1;
01383       cur = cur->next;
01384    }
01385    /* Now that we've freed them, load the new ones */
01386    snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_VAR_DIR);
01387    fwd = opendir(dir);
01388    if (fwd) {
01389       while((de = readdir(fwd))) {
01390          if (de->d_name[0] != '.') {
01391             snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01392             if (!try_firmware(fn)) {
01393                if (option_verbose > 1)
01394                   ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01395             }
01396          }
01397       }
01398       closedir(fwd);
01399    } else 
01400       ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01401 
01402    /* Clean up leftovers */
01403    cur = waresl.wares;
01404    curp = NULL;
01405    while(cur) {
01406       curl = cur;
01407       cur = cur->next;
01408       if (curl->dead) {
01409          if (curp) {
01410             curp->next = cur;
01411          } else {
01412             waresl.wares = cur;
01413          }
01414          destroy_firmware(curl);
01415       } else {
01416          curp = cur;
01417       }
01418    }
01419    ast_mutex_unlock(&waresl.lock);
01420 }

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

Definition at line 6347 of file chan_iax2.c.

References iax_frame::callno, and ies.

Referenced by socket_read().

06348 {
06349    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06350    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06351    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06352    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06353    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06354    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06355    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06356 }

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

Definition at line 2277 of file chan_iax2.c.

References iax_frame::af, ast_log(), ast_tvadd(), calc_rxstamp(), iax_frame::callno, ast_frame::delivery, iaxdebug, iaxs, chan_iax2_pvt::last, match(), MEMORY_SIZE, option_debug, chan_iax2_pvt::rxcore, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, and unwrap_timestamp().

Referenced by socket_read().

02278 {
02279 #ifdef NEWJB
02280    int type, len;
02281    int ret;
02282    int needfree = 0;
02283 #else
02284    int x;
02285    int ms;
02286    int delay;
02287    unsigned int orig_ts;
02288    int drops[MEMORY_SIZE];
02289    int min, max=0, prevjitterbuffer, maxone=0,y,z, match;
02290 
02291    /* Remember current jitterbuffer so we can log any change */
02292    prevjitterbuffer = iaxs[fr->callno]->jitterbuffer;
02293    /* Similarly for the frame timestamp */
02294    orig_ts = fr->ts;
02295 #endif
02296 
02297 #if 0
02298    if (option_debug && iaxdebug)
02299       ast_log(LOG_DEBUG, "schedule_delivery: ts=%d, last=%d, update=%d\n",
02300             fr->ts, iaxs[fr->callno]->last, updatehistory);
02301 #endif
02302 
02303    /* Attempt to recover wrapped timestamps */
02304    unwrap_timestamp(fr);
02305    
02306    if (updatehistory) {
02307 #ifndef NEWJB
02308 
02309       /* Attempt to spot a change of timebase on timestamps coming from the other side
02310          We detect by noticing a jump in consecutive timestamps that can't reasonably be explained
02311          by network jitter or reordering.  Sometimes, also, the peer stops sending us frames
02312          for a while - in this case this code might also resync us.  But that's not a bad thing.
02313          Be careful of non-voice frames which are timestamped differently (especially ACKS!)
02314          [that's why we only do this when updatehistory is true]
02315       */
02316       x = fr->ts - iaxs[fr->callno]->last;
02317       if (x > TS_GAP_FOR_JB_RESYNC || x < -TS_GAP_FOR_JB_RESYNC) {
02318          if (option_debug && iaxdebug)
02319             ast_log(LOG_DEBUG, "schedule_delivery: call=%d: TS jumped.  resyncing rxcore (ts=%d, last=%d)\n",
02320                      fr->callno, fr->ts, iaxs[fr->callno]->last);
02321          /* zap rxcore - calc_rxstamp will make a new one based on this frame */
02322          iaxs[fr->callno]->rxcore = ast_tv(0, 0);
02323          /* wipe "last" if stamps have jumped backwards */
02324          if (x<0)
02325             iaxs[fr->callno]->last = 0;
02326          /* should we also empty history? */
02327       }
02328       /* ms is a measure of the "lateness" of the frame relative to the "reference"
02329          frame we received.  (initially the very first, but also see code just above here).
02330          Understand that "ms" can easily be -ve if lag improves since the reference frame.
02331          Called by IAX thread, with iaxsl lock held. */
02332       ms = calc_rxstamp(iaxs[fr->callno], fr->ts) - fr->ts;
02333    
02334       /* Rotate our history queue of "lateness".  Don't worry about those initial
02335          zeros because the first entry will always be zero */
02336       for (x=0;x<MEMORY_SIZE - 1;x++) 
02337          iaxs[fr->callno]->history[x] = iaxs[fr->callno]->history[x+1];
02338       /* Add a history entry for this one */
02339       iaxs[fr->callno]->history[x] = ms;
02340 #endif
02341    }
02342 #ifndef NEWJB
02343    else
02344       ms = 0;
02345 #endif
02346 
02347 
02348    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02349    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02350       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02351    else {
02352 #if 0
02353       ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02354 #endif
02355       fr->af.delivery = ast_tv(0,0);
02356    }
02357 
02358 #ifndef NEWJB
02359    /* Initialize the minimum to reasonable values.  It's too much
02360       work to do the same for the maximum, repeatedly */
02361    min=iaxs[fr->callno]->history[0];
02362    for (z=0;z < iax2_dropcount + 1;z++) {
02363       /* Start very optimistic ;-) */
02364       max=-999999999;
02365       for (x=0;x<MEMORY_SIZE;x++) {
02366          if (max < iaxs[fr->callno]->history[x]) {
02367             /* We have a candidate new maximum value.  Make
02368                sure it's not in our drop list */
02369             match = 0;
02370             for (y=0;!match && (y<z);y++)
02371                match |= (drops[y] == x);
02372             if (!match) {
02373                /* It's not in our list, use it as the new maximum */
02374                max = iaxs[fr->callno]->history[x];
02375                maxone = x;
02376             }
02377             
02378          }
02379          if (!z) {
02380             /* On our first pass, find the minimum too */
02381             if (min > iaxs[fr->callno]->history[x])
02382                min = iaxs[fr->callno]->history[x];
02383          }
02384       }
02385 #if 1
02386       drops[z] = maxone;
02387 #endif
02388    }
02389 #endif
02390 
02391 #ifdef NEWJB
02392    type = JB_TYPE_CONTROL;
02393    len = 0;
02394 
02395    if(fr->af.frametype == AST_FRAME_VOICE) {
02396       type = JB_TYPE_VOICE;
02397       len = ast_codec_get_samples(&fr->af) / 8;
02398    } else if(fr->af.frametype == AST_FRAME_CNG) {
02399       type = JB_TYPE_SILENCE;
02400    }
02401 
02402    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02403       if (tsout)
02404          *tsout = fr->ts;
02405       __do_deliver(fr);
02406       return -1;
02407    }
02408 
02409    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02410     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02411    if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
02412        iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
02413        (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
02414                 jb_frame frame;
02415 
02416                 /* deliver any frames in the jb */
02417                 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK)
02418                         __do_deliver(frame.data);
02419 
02420       jb_reset(iaxs[fr->callno]->jb);
02421 
02422       if (iaxs[fr->callno]->jbid > -1)
02423                         ast_sched_del(sched, iaxs[fr->callno]->jbid);
02424 
02425       iaxs[fr->callno]->jbid = -1;
02426 
02427       /* deliver this frame now */
02428       if (tsout)
02429          *tsout = fr->ts;
02430       __do_deliver(fr);
02431       return -1;
02432 
02433    }
02434 
02435 
02436    /* insert into jitterbuffer */
02437    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02438    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02439          calc_rxstamp(iaxs[fr->callno],fr->ts));
02440    if (ret == JB_DROP) {
02441       needfree++;
02442    } else if (ret == JB_SCHED) {
02443       update_jbsched(iaxs[fr->callno]);
02444    }
02445 #else
02446    /* Just for reference, keep the "jitter" value, the difference between the
02447       earliest and the latest. */
02448    if (max >= min)
02449       iaxs[fr->callno]->jitter = max - min;  
02450    
02451    /* IIR filter for keeping track of historic jitter, but always increase
02452       historic jitter immediately for increase */
02453    
02454    if (iaxs[fr->callno]->jitter > iaxs[fr->callno]->historicjitter )
02455       iaxs[fr->callno]->historicjitter = iaxs[fr->callno]->jitter;
02456    else
02457       iaxs[fr->callno]->historicjitter = GAMMA * (double)iaxs[fr->callno]->jitter + (1-GAMMA) * 
02458          iaxs[fr->callno]->historicjitter;
02459 
02460    /* If our jitter buffer is too big (by a significant margin), then we slowly
02461       shrink it to avoid letting the change be perceived */
02462    if (max < iaxs[fr->callno]->jitterbuffer - max_jitter_buffer)
02463       iaxs[fr->callno]->jitterbuffer -= jittershrinkrate;
02464 
02465    /* If our jitter buffer headroom is too small (by a significant margin), then we slowly enlarge it */
02466    /* min_jitter_buffer should be SMALLER than max_jitter_buffer - leaving a "no mans land"
02467       in between - otherwise the jitterbuffer size will hunt up and down causing unnecessary
02468       disruption.  Set maxexcessbuffer to say 150msec, minexcessbuffer to say 50 */
02469    if (max > iaxs[fr->callno]->jitterbuffer - min_jitter_buffer)
02470       iaxs[fr->callno]->jitterbuffer += jittershrinkrate;
02471 
02472    /* If our jitter buffer is smaller than our maximum delay, grow the jitter
02473       buffer immediately to accomodate it (and a little more).  */
02474    if (max > iaxs[fr->callno]->jitterbuffer)
02475       iaxs[fr->callno]->jitterbuffer = max 
02476          /* + ((float)iaxs[fr->callno]->jitter) * 0.1 */;
02477 
02478    /* update "min", just for RRs and stats */
02479    iaxs[fr->callno]->min = min; 
02480 
02481    /* Subtract the lateness from our jitter buffer to know how long to wait
02482       before sending our packet.  */
02483    delay = iaxs[fr->callno]->jitterbuffer - ms;
02484 
02485    /* Whatever happens, no frame waits longer than maxjitterbuffer */
02486    if (delay > maxjitterbuffer)
02487       delay = maxjitterbuffer;
02488    
02489    /* If jitter buffer is disabled then just pretend the frame is "right on time" */
02490    /* If frame came from trunk, also don't do any delay */
02491    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) || fromtrunk )
02492       delay = 0;
02493 
02494    if (option_debug && iaxdebug) {
02495       /* Log jitter stats for possible offline analysis */
02496       ast_log(LOG_DEBUG, "Jitter: call=%d ts=%d orig=%d last=%d %s: min=%d max=%d jb=%d %+d lateness=%d jbdelay=%d jitter=%d historic=%d\n",
02497                fr->callno, fr->ts, orig_ts, iaxs[fr->callno]->last,
02498                (fr->af.frametype == AST_FRAME_VOICE) ? "VOICE" : "CONTROL",
02499                min, max, iaxs[fr->callno]->jitterbuffer,
02500                iaxs[fr->callno]->jitterbuffer - prevjitterbuffer,
02501                ms, delay,
02502                iaxs[fr->callno]->jitter, iaxs[fr->callno]->historicjitter);
02503    }
02504 
02505    if (delay < 1) {
02506       /* Don't deliver it more than 4 ms late */
02507       if ((delay > -4) || (fr->af.frametype != AST_FRAME_VOICE)) {
02508          if (option_debug && iaxdebug)
02509             ast_log(LOG_DEBUG, "schedule_delivery: Delivering immediately (Calculated delay is %d)\n", delay);
02510          if (tsout)
02511             *tsout = fr->ts;
02512          __do_deliver(fr);
02513          return -1;
02514       } else {
02515          if (option_debug && iaxdebug)
02516             ast_log(LOG_DEBUG, "schedule_delivery: Dropping voice packet since %dms delay is too old\n", delay);
02517          iaxs[fr->callno]->frames_dropped++;
02518          needfree++;
02519       }
02520    } else {
02521       if (option_debug && iaxdebug)
02522          ast_log(LOG_DEBUG, "schedule_delivery: Scheduling delivery in %d ms\n", delay);
02523       fr->retrans = ast_sched_add(sched, delay, do_deliver, fr);
02524    }
02525 #endif
02526    if (tsout)
02527       *tsout = fr->ts;
02528    if (needfree) {
02529       /* Free our iax frame */
02530       iax2_frame_free(fr);
02531       return -1;
02532    }
02533    return 0;
02534 }

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

Definition at line 4695 of file chan_iax2.c.

References __send_command().

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

04696 {
04697    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04698 }

static int send_command_final struct chan_iax2_pvt ,
char  ,
int  ,
unsigned  int,
const unsigned char *  ,
int  ,
int 
[static]
 

Definition at line 4716 of file chan_iax2.c.

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

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

04717 {
04718    /* It is assumed that the callno has already been locked */
04719    iax2_predestroy_nolock(i->callno);
04720    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04721 }

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

Definition at line 4723 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_read().

04724 {
04725    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04726 }

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

Definition at line 4700 of file chan_iax2.c.

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

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

04701 {
04702    int res;
04703    ast_mutex_lock(&iaxsl[callno]);
04704    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04705    ast_mutex_unlock(&iaxsl[callno]);
04706    return res;
04707 }

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

Definition at line 4728 of file chan_iax2.c.

References __send_command().

Referenced by socket_read(), and try_transfer().

04729 {
04730    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04731 }

static int send_lagrq void *  data  )  [static]
 

Definition at line 812 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_LAGRQ, iaxs, and send_command().

Referenced by make_trunk().

00813 {
00814    int callno = (long)data;
00815    /* Ping only if it's real not if it's bridged */
00816    if (iaxs[callno]) {
00817 #ifdef BRIDGE_OPTIMIZATION
00818       if (!iaxs[callno]->bridgecallno)
00819 #endif      
00820          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
00821       return 1;
00822    } else
00823       return 0;
00824 }

static int send_packet struct iax_frame f  )  [static]
 

Definition at line 1500 of file chan_iax2.c.

References ast_inet_ntoa(), ast_log(), chan_iax2_pvt::callno, iax_frame::callno, handle_error(), iax_showframe(), iaxdebug, iaxs, LOG_DEBUG, LOG_WARNING, option_debug, iax_frame::transfer, and iax_frame::ts.

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

01501 {
01502    int res;
01503    char iabuf[INET_ADDRSTRLEN];
01504    /* Called with iaxsl held */
01505    if (!iaxs[f->callno])
01506       return -1;
01507    if (option_debug > 2 && iaxdebug)
01508       ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, f->callno, iaxs[f->callno]->peercallno, ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[f->callno]->addr.sin_addr), ntohs(iaxs[f->callno]->addr.sin_port));
01509    /* Don't send if there was an error, but return error instead */
01510    if (!f->callno) {
01511       ast_log(LOG_WARNING, "Call number = %d\n", f->callno);
01512       return -1;
01513    }
01514    if (iaxs[f->callno]->error)
01515       return -1;
01516    if (f->transfer) {
01517       if (iaxdebug)
01518          iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01519       res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer,
01520                sizeof(iaxs[f->callno]->transfer));
01521    } else {
01522       if (iaxdebug)
01523          iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01524       res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr,
01525                sizeof(iaxs[f->callno]->addr));
01526    }
01527    if (res < 0) {
01528       if (option_debug && iaxdebug)
01529          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01530       handle_error();
01531    } else
01532       res = 0;
01533    return res;
01534 }

static int send_ping void *  data  )  [static]
 

Definition at line 786 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_PING, iaxs, and send_command().

Referenced by make_trunk().

00787 {
00788    int callno = (long)data;
00789    /* Ping only if it's real, not if it's bridged */
00790    if (iaxs[callno]) {
00791 #ifdef BRIDGE_OPTIMIZATION
00792       if (!iaxs[callno]->bridgecallno)
00793 #endif
00794          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00795       return 1;
00796    } else
00797       return 0;
00798 }

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

Definition at line 6026 of file chan_iax2.c.

References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, trunkfreq, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.

Referenced by timing_read().

06027 {
06028    int res = 0;
06029    struct iax_frame *fr;
06030    struct ast_iax2_meta_hdr *meta;
06031    struct ast_iax2_meta_trunk_hdr *mth;
06032    int calls = 0;
06033    
06034    /* Point to frame */
06035    fr = (struct iax_frame *)tpeer->trunkdata;
06036    /* Point to meta data */
06037    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06038    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06039    if (tpeer->trunkdatalen) {
06040       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06041       meta->zeros = 0;
06042       meta->metacmd = IAX_META_TRUNK;
06043       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06044          meta->cmddata = IAX_META_TRUNK_MINI;
06045       else
06046          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06047       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06048       /* And the rest of the ast_iax2 header */
06049       fr->direction = DIRECTION_OUTGRESS;
06050       fr->retrans = -1;
06051       fr->transfer = 0;
06052       /* Any appropriate call will do */
06053       fr->data = fr->afdata;
06054       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06055       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06056       calls = tpeer->calls;
06057 #if 0
06058       ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
06059 #endif      
06060       /* Reset transmit trunk side data */
06061       tpeer->trunkdatalen = 0;
06062       tpeer->calls = 0;
06063    }
06064    if (res < 0)
06065       return res;
06066    return calls;
06067 }

static int set_config char *  config_file,
int  reload
[static]
 

Definition at line 8703 of file chan_iax2.c.

References accountcode, amaflags, ast_category_browse(), ast_cdr_amaflags2int(), ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_bind(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_str2tos(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), autokill, build_peer(), build_user(), capability, cfg, channeltype, DEFAULT_MAXMS, defaultsockfd, delayreject, format, get_encrypt_methods(), global_rtautoclear, globalflags, iax2_capability, iax2_encryption, iax2_register(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxcompat, io, jittershrinkrate, lagrq_time, language, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_WARNING, max_jitter_buffer, max_reg_expire, maxauthreq, maxjitterbuffer, maxjitterinterps, min_jitter_buffer, min_reg_expire, ast_variable::name, netsock, iax2_peer::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, ping_time, portno, prefs, reg_source_db(), regcontext, resyncthreshold, set_timing(), socket_read(), tos, trunkfreq, user, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.

Referenced by load_module(), and reload().

08704 {
08705    struct ast_config *cfg;
08706    int capability=iax2_capability;
08707    struct ast_variable *v;
08708    char *cat;
08709    char *utype;
08710    char *tosval;
08711    int format;
08712    int portno = IAX_DEFAULT_PORTNO;
08713    int  x;
08714    struct iax2_user *user;
08715    struct iax2_peer *peer;
08716    struct ast_netsock *ns;
08717 #if 0
08718    static unsigned short int last_port=0;
08719 #endif
08720 
08721    cfg = ast_config_load(config_file);
08722    
08723    if (!cfg) {
08724       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
08725       return -1;
08726    }
08727 
08728    /* Reset global codec prefs */   
08729    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
08730    
08731    /* Reset Global Flags */
08732    memset(&globalflags, 0, sizeof(globalflags));
08733    ast_set_flag(&globalflags, IAX_RTUPDATE);
08734 
08735 #ifdef SO_NO_CHECK
08736    nochecksums = 0;
08737 #endif
08738 
08739    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08740    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08741 
08742    maxauthreq = 0;
08743 
08744    v = ast_variable_browse(cfg, "general");
08745 
08746    /* Seed initial tos value */
08747    tosval = ast_variable_retrieve(cfg, "general", "tos");
08748    if (tosval) {
08749       if (ast_str2tos(tosval, &tos))
08750          ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n");
08751    }
08752    while(v) {
08753       if (!strcasecmp(v->name, "bindport")){ 
08754          if (reload)
08755             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
08756          else
08757             portno = atoi(v->value);
08758       } else if (!strcasecmp(v->name, "pingtime")) 
08759          ping_time = atoi(v->value);
08760       else if (!strcasecmp(v->name, "nochecksums")) {
08761 #ifdef SO_NO_CHECK
08762          if (ast_true(v->value))
08763             nochecksums = 1;
08764          else
08765             nochecksums = 0;
08766 #else
08767          if (ast_true(v->value))
08768             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
08769 #endif
08770       }
08771       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
08772          maxjitterbuffer = atoi(v->value);
08773 #ifdef NEWJB
08774       else if (!strcasecmp(v->name, "resyncthreshold")) 
08775          resyncthreshold = atoi(v->value);
08776       else if (!strcasecmp(v->name, "maxjitterinterps")) 
08777          maxjitterinterps = atoi(v->value);
08778 #endif
08779       else if (!strcasecmp(v->name, "jittershrinkrate")) 
08780          jittershrinkrate = atoi(v->value);
08781       else if (!strcasecmp(v->name, "maxexcessbuffer")) 
08782          max_jitter_buffer = atoi(v->value);
08783       else if (!strcasecmp(v->name, "minexcessbuffer")) 
08784          min_jitter_buffer = atoi(v->value);
08785       else if (!strcasecmp(v->name, "lagrqtime")) 
08786          lagrq_time = atoi(v->value);
08787       else if (!strcasecmp(v->name, "dropcount")) 
08788          iax2_dropcount = atoi(v->value);
08789       else if (!strcasecmp(v->name, "maxregexpire")) 
08790          max_reg_expire = atoi(v->value);
08791       else if (!strcasecmp(v->name, "minregexpire")) 
08792          min_reg_expire = atoi(v->value);
08793       else if (!strcasecmp(v->name, "bindaddr")) {
08794          if (reload) {
08795             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
08796          } else {
08797             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
08798                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
08799             } else {
08800                if (option_verbose > 1) {
08801                   if (strchr(v->value, ':'))
08802                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
08803                   else
08804                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
08805                }
08806                if (defaultsockfd < 0) 
08807                   defaultsockfd = ast_netsock_sockfd(ns);
08808                ast_netsock_unref(ns);
08809             }
08810          }
08811       } else if (!strcasecmp(v->name, "authdebug"))
08812          authdebug = ast_true(v->value);
08813       else if (!strcasecmp(v->name, "encryption"))
08814          iax2_encryption = get_encrypt_methods(v->value);
08815       else if (!strcasecmp(v->name, "notransfer"))
08816          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
08817       else if (!strcasecmp(v->name, "codecpriority")) {
08818          if(!strcasecmp(v->value, "caller"))
08819             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
08820          else if(!strcasecmp(v->value, "disabled"))
08821             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08822          else if(!strcasecmp(v->value, "reqonly")) {
08823             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
08824             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08825          }
08826       } else if (!strcasecmp(v->name, "jitterbuffer"))
08827          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
08828       else if (!strcasecmp(v->name, "forcejitterbuffer"))
08829          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
08830       else if (!strcasecmp(v->name, "delayreject"))
08831          delayreject = ast_true(v->value);
08832       else if (!strcasecmp(v->name, "mailboxdetail"))
08833          ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL);   
08834       else if (!strcasecmp(v->name, "rtcachefriends"))
08835          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
08836       else if (!strcasecmp(v->name, "rtignoreregexpire"))
08837          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
08838       else if (!strcasecmp(v->name, "rtupdate"))
08839          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
08840       else if (!strcasecmp(v->name, "trunktimestamps"))
08841          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
08842       else if (!strcasecmp(v->name, "rtautoclear")) {
08843          int i = atoi(v->value);
08844          if(i > 0)
08845             global_rtautoclear = i;
08846          else
08847             i = 0;
08848          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
08849       } else if (!strcasecmp(v->name, "trunkfreq")) {
08850          trunkfreq = atoi(v->value);
08851          if (trunkfreq < 10)
08852             trunkfreq = 10;
08853       } else if (!strcasecmp(v->name, "autokill")) {
08854          if (sscanf(v->value, "%d", &x) == 1) {
08855             if (x >= 0)
08856                autokill = x;
08857             else
08858                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
08859          } else if (ast_true(v->value)) {
08860             autokill = DEFAULT_MAXMS;
08861          } else {
08862             autokill = 0;
08863          }
08864       } else if (!strcasecmp(v->name, "bandwidth")) {
08865          if (!strcasecmp(v->value, "low")) {
08866             capability = IAX_CAPABILITY_LOWBANDWIDTH;
08867          } else if (!strcasecmp(v->value, "medium")) {
08868             capability = IAX_CAPABILITY_MEDBANDWIDTH;
08869          } else if (!strcasecmp(v->value, "high")) {
08870             capability = IAX_CAPABILITY_FULLBANDWIDTH;
08871          } else
08872             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
08873       } else if (!strcasecmp(v->name, "allow")) {
08874          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
08875       } else if (!strcasecmp(v->name, "disallow")) {
08876          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
08877       } else if (!strcasecmp(v->name, "register")) {
08878          iax2_register(v->value, v->lineno);
08879       } else if (!strcasecmp(v->name, "iaxcompat")) {
08880          iaxcompat = ast_true(v->value);
08881       } else if (!strcasecmp(v->name, "regcontext")) {
08882          ast_copy_string(regcontext, v->value, sizeof(regcontext));
08883          /* Create context if it doesn't exist already */
08884          if (!ast_context_find(regcontext))
08885             ast_context_create(NULL, regcontext, channeltype);
08886       } else if (!strcasecmp(v->name, "tos")) {
08887          if (ast_str2tos(v->value, &tos))
08888             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
08889       } else if (!strcasecmp(v->name, "accountcode")) {
08890          ast_copy_string(accountcode, v->value, sizeof(accountcode));
08891       } else if (!strcasecmp(v->name, "amaflags")) {
08892          format = ast_cdr_amaflags2int(v->value);
08893          if (format < 0) {
08894             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08895          } else {
08896             amaflags = format;
08897          }
08898       } else if (!strcasecmp(v->name, "language")) {
08899                         ast_copy_string(language, v->value, sizeof(language));
08900       } else if (!strcasecmp(v->name, "maxauthreq")) {
08901          maxauthreq = atoi(v->value);
08902          if (maxauthreq < 0)
08903             maxauthreq = 0;
08904       } /*else if (strcasecmp(v->name,"type")) */
08905       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08906       v = v->next;
08907    }
08908    
08909    if (defaultsockfd < 0) {
08910       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
08911          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
08912       } else {
08913          if (option_verbose > 1)
08914             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
08915          defaultsockfd = ast_netsock_sockfd(ns);
08916          ast_netsock_unref(ns);
08917       }
08918    }
08919    
08920    if (min_reg_expire > max_reg_expire) {
08921       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
08922          min_reg_expire, max_reg_expire, max_reg_expire);
08923       min_reg_expire = max_reg_expire;
08924    }
08925    iax2_capability = capability;
08926    cat = ast_category_browse(cfg, NULL);
08927    while(cat) {
08928       if (strcasecmp(cat, "general")) {
08929          utype = ast_variable_retrieve(cfg, cat, "type");
08930          if (utype) {
08931             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
08932                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
08933                if (user) {
08934                   ast_mutex_lock(&userl.lock);
08935                   user->next = userl.users;
08936                   userl.users = user;
08937                   ast_mutex_unlock(&userl.lock);
08938                }
08939             }
08940             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
08941                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
08942                if (peer) {
08943                   ast_mutex_lock(&peerl.lock);
08944                   peer->next = peerl.peers;
08945                   peerl.peers = peer;
08946                   ast_mutex_unlock(&peerl.lock);
08947                   if (ast_test_flag(peer, IAX_DYNAMIC))
08948                      reg_source_db(peer);
08949                }
08950             } else if (strcasecmp(utype, "user")) {
08951                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
08952             }
08953          } else
08954             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
08955       }
08956       cat = ast_category_browse(cfg, cat);
08957    }
08958    ast_config_destroy(cfg);
08959    set_timing();
08960    return capability;
08961 }

static void set_timing void   )  [static]
 

Definition at line 8686 of file chan_iax2.c.

References ast_log(), LOG_WARNING, timingfd, and trunkfreq.

Referenced by set_config().

08687 {
08688 #ifdef IAX_TRUNKING
08689    int bs = trunkfreq * 8;
08690    if (timingfd > -1) {
08691       if (
08692 #ifdef ZT_TIMERACK
08693          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08694 #endif         
08695          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08696          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08697    }
08698 #endif
08699 }

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

Definition at line 6358 of file chan_iax2.c.

References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, check_access(), check_provisioning(), complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, ast_frame::data, ast_frame::datalen, decrypt_frame(), delayreject, dp_lookup(), EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, format, ast_frame::frametype, handle_error(), ast_iax2_queue::head, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy_nolock(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_frame(), iax2_send(), iax2_vnak(), IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iaxcompat, iaxdebug, iaxfrdup2(), iaxq, iaxsl, ies, inaddrcmp(), iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, ast_iax2_queue::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_debug, option_verbose, iax_frame::oseqno, iax2_dpcache::peer, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), ast_frame::src, stop_stuff(), ast_frame::subclass, test_losspct, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, vnak_retransmit(), ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros.

Referenced by network_thread(), and set_config().

06359 {
06360    struct sockaddr_in sin;
06361    int res;
06362    int updatehistory=1;
06363    int new = NEW_PREVENT;
06364    unsigned char buf[4096]; 
06365    void *ptr;
06366    socklen_t len = sizeof(sin);
06367    int dcallno = 0;
06368    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf;
06369    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf;
06370    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf;
06371    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf;
06372    struct ast_iax2_meta_trunk_hdr *mth;
06373    struct ast_iax2_meta_trunk_entry *mte;
06374    struct ast_iax2_meta_trunk_mini *mtm;
06375    struct iax_frame *fr;
06376    struct iax_frame *cur;
06377    char iabuf[INET_ADDRSTRLEN];
06378    struct ast_frame f;
06379    struct ast_channel *c;
06380    struct iax2_dpcache *dp;
06381    struct iax2_peer *peer;
06382    struct iax2_trunk_peer *tpeer;
06383    struct timeval rxtrunktime;
06384    struct iax_ies ies;
06385    struct iax_ie_data ied0, ied1;
06386    int format;
06387    int exists;
06388    int minivid = 0;
06389    unsigned int ts;
06390    char empty[32]="";      /* Safety measure */
06391    struct iax_frame *duped_fr;
06392    char host_pref_buf[128];
06393    char caller_pref_buf[128];
06394    struct ast_codec_pref pref;
06395    char *using_prefs = "mine";
06396 
06397    /* allocate an iax_frame with 4096 bytes of data buffer */
06398    fr = alloca(sizeof(*fr) + 4096);
06399    fr->callno = 0;
06400    
06401    res = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr *) &sin, &len);
06402    if (res < 0) {
06403       if (errno != ECONNREFUSED)
06404          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06405       handle_error();
06406       return 1;
06407    }
06408    if(test_losspct) { /* simulate random loss condition */
06409       if( (100.0*rand()/(RAND_MAX+1.0)) < test_losspct) 
06410          return 1;
06411  
06412    }
06413    if (res < sizeof(*mh)) {
06414       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06415       return 1;
06416    }
06417    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06418       if (res < sizeof(*vh)) {
06419          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
06420          return 1;
06421       }
06422 
06423       /* This is a video frame, get call number */
06424       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
06425       minivid = 1;
06426    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06427       unsigned char metatype;
06428 
06429       if (res < sizeof(*meta)) {
06430          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
06431          return 1;
06432       }
06433 
06434       /* This is a meta header */
06435       switch(meta->metacmd) {
06436       case IAX_META_TRUNK:
06437          if (res < (sizeof(*meta) + sizeof(*mth))) {
06438             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06439                sizeof(*meta) + sizeof(*mth));
06440             return 1;
06441          }
06442          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06443          ts = ntohl(mth->ts);
06444          metatype = meta->cmddata;
06445          res -= (sizeof(*meta) + sizeof(*mth));
06446          ptr = mth->data;
06447          tpeer = find_tpeer(&sin, fd);
06448          if (!tpeer) {
06449             ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
06450             return 1;
06451          }
06452          tpeer->trunkact = ast_tvnow();
06453          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06454             tpeer->rxtrunktime = tpeer->trunkact;
06455          rxtrunktime = tpeer->rxtrunktime;
06456          ast_mutex_unlock(&tpeer->lock);
06457          while(res >= sizeof(*mte)) {
06458             /* Process channels */
06459             unsigned short callno, trunked_ts, len;
06460 
06461             if (metatype == IAX_META_TRUNK_MINI) {
06462                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06463                ptr += sizeof(*mtm);
06464                res -= sizeof(*mtm);
06465                len = ntohs(mtm->len);
06466                callno = ntohs(mtm->mini.callno);
06467                trunked_ts = ntohs(mtm->mini.ts);
06468             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06469                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06470                ptr += sizeof(*mte);
06471                res -= sizeof(*mte);
06472                len = ntohs(mte->len);
06473                callno = ntohs(mte->callno);
06474                trunked_ts = 0;
06475             } else {
06476                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
06477                break;
06478             }
06479             /* Stop if we don't have enough data */
06480             if (len > res)
06481                break;
06482             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
06483             if (fr->callno) {
06484                ast_mutex_lock(&iaxsl[fr->callno]);
06485                /* If it's a valid call, deliver the contents.  If not, we
06486                   drop it, since we don't have a scallno to use for an INVAL */
06487                /* Process as a mini frame */
06488                f.frametype = AST_FRAME_VOICE;
06489                if (iaxs[fr->callno]) {
06490                   if (iaxs[fr->callno]->voiceformat > 0) {
06491                      f.subclass = iaxs[fr->callno]->voiceformat;
06492                      f.datalen = len;
06493                      if (f.datalen >= 0) {
06494                         if (f.datalen)
06495                            f.data = ptr;
06496                         else
06497                            f.data = NULL;
06498                         if(trunked_ts) {
06499                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06500                         } else
06501                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06502                         /* Don't pass any packets until we're started */
06503                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06504                            /* Common things */
06505                            f.src = "IAX2";
06506                            f.mallocd = 0;
06507                            f.offset = 0;
06508                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06509                               f.samples = ast_codec_get_samples(&f);
06510                            else
06511                               f.samples = 0;
06512                            fr->outoforder = 0;
06513                            iax_frame_wrap(fr, &f);
06514 #ifdef BRIDGE_OPTIMIZATION
06515                            if (iaxs[fr->callno]->bridgecallno) {
06516                               forward_delivery(fr);
06517                            } else {
06518                               duped_fr = iaxfrdup2(fr);
06519                               if (duped_fr) {
06520                                  schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06521                               }
06522                            }
06523 #else
06524                            duped_fr = iaxfrdup2(fr);
06525                            if (duped_fr) {
06526                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06527                            }
06528 #endif
06529                            if (iaxs[fr->callno]->last < fr->ts) {
06530                               iaxs[fr->callno]->last = fr->ts;
06531 #if 1
06532                               if (option_debug)
06533                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06534 #endif
06535                            }
06536                         }
06537                      } else {
06538                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06539                      }
06540                   } else {
06541                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06542                      iax2_vnak(fr->callno);
06543                   }
06544                }
06545                ast_mutex_unlock(&iaxsl[fr->callno]);
06546             }
06547             ptr += len;
06548             res -= len;
06549          }
06550          
06551       }
06552       return 1;
06553    }
06554 
06555 #ifdef DEBUG_SUPPORT
06556    if (iaxdebug && (res >= sizeof(*fh)))
06557       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06558 #endif
06559    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06560       if (res < sizeof(*fh)) {
06561          ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port));
06562          return 1;
06563       }
06564 
06565       /* Get the destination call number */
06566       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06567       /* Retrieve the type and subclass */
06568       f.frametype = fh->type;
06569       if (f.frametype == AST_FRAME_VIDEO) {
06570          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06571       } else {
06572          f.subclass = uncompress_subclass(fh->csub);
06573       }
06574       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06575                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06576                          (f.subclass == IAX_COMMAND_REGREL)))
06577          new = NEW_ALLOW;
06578    } else {
06579       /* Don't know anything about it yet */
06580       f.frametype = AST_FRAME_NULL;
06581       f.subclass = 0;
06582    }
06583 
06584    if (!fr->callno)
06585       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
06586 
06587    if (fr->callno > 0) 
06588       ast_mutex_lock(&iaxsl[fr->callno]);
06589 
06590    if (!fr->callno || !iaxs[fr->callno]) {
06591       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
06592          frame, reply with an inval */
06593       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06594          /* We can only raw hangup control frames */
06595          if (((f.subclass != IAX_COMMAND_INVAL) &&
06596              (f.subclass != IAX_COMMAND_TXCNT) &&
06597              (f.subclass != IAX_COMMAND_TXACC) &&
06598              (f.subclass != IAX_COMMAND_FWDOWNL))||
06599              (f.frametype != AST_FRAME_IAX))
06600             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06601             fd);
06602       }
06603       if (fr->callno > 0) 
06604          ast_mutex_unlock(&iaxsl[fr->callno]);
06605       return 1;
06606    }
06607    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06608       if (decrypt_frame(fr->callno, fh, &f, &res)) {
06609          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06610          ast_mutex_unlock(&iaxsl[fr->callno]);
06611          return 1;
06612       }
06613 #ifdef DEBUG_SUPPORT
06614       else if (iaxdebug)
06615          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
06616 #endif
06617    }
06618 
06619    /* count this frame */
06620    iaxs[fr->callno]->frames_received++;
06621 
06622    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
06623       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
06624       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
06625       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06626    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06627       if (option_debug  && iaxdebug)
06628          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06629       /* Check if it's out of order (and not an ACK or INVAL) */
06630       fr->oseqno = fh->oseqno;
06631       fr->iseqno = fh->iseqno;
06632       fr->ts = ntohl(fh->ts);
06633 #ifdef IAXTESTS
06634       if (test_resync) {
06635          if (option_debug)
06636             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
06637          fr->ts += test_resync;
06638       }
06639 #endif /* IAXTESTS */
06640 #if 0
06641       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06642            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06643                         (f.subclass == IAX_COMMAND_NEW ||
06644                          f.subclass == IAX_COMMAND_AUTHREQ ||
06645                          f.subclass == IAX_COMMAND_ACCEPT ||
06646                          f.subclass == IAX_COMMAND_REJECT))      ) )
06647 #endif
06648       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06649          updatehistory = 0;
06650       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
06651          (iaxs[fr->callno]->iseqno ||
06652             ((f.subclass != IAX_COMMAND_TXCNT) &&
06653             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
06654             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
06655             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
06656             (f.subclass != IAX_COMMAND_TXACC)) ||
06657             (f.frametype != AST_FRAME_IAX))) {
06658          if (
06659           ((f.subclass != IAX_COMMAND_ACK) &&
06660            (f.subclass != IAX_COMMAND_INVAL) &&
06661            (f.subclass != IAX_COMMAND_TXCNT) &&
06662            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
06663            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
06664            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
06665            (f.subclass != IAX_COMMAND_TXACC) &&
06666            (f.subclass != IAX_COMMAND_VNAK)) ||
06667            (f.frametype != AST_FRAME_IAX)) {
06668             /* If it's not an ACK packet, it's out of order. */
06669             if (option_debug)
06670                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
06671                iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
06672             if (iaxs[fr->callno]->iseqno > fr->oseqno) {
06673                /* If we've already seen it, ack it XXX There's a border condition here XXX */
06674                if ((f.frametype != AST_FRAME_IAX) || 
06675                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06676                   if (option_debug)
06677                      ast_log(LOG_DEBUG, "Acking anyway\n");
06678                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
06679                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
06680                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06681                }
06682             } else {
06683                /* Send a VNAK requesting retransmission */
06684                iax2_vnak(fr->callno);
06685             }
06686             ast_mutex_unlock(&iaxsl[fr->callno]);
06687             return 1;
06688          }
06689       } else {
06690          /* Increment unless it's an ACK or VNAK */
06691          if (((f.subclass != IAX_COMMAND_ACK) &&
06692              (f.subclass != IAX_COMMAND_INVAL) &&
06693              (f.subclass != IAX_COMMAND_TXCNT) &&
06694              (f.subclass != IAX_COMMAND_TXACC) &&
06695             (f.subclass != IAX_COMMAND_VNAK)) ||
06696              (f.frametype != AST_FRAME_IAX))
06697             iaxs[fr->callno]->iseqno++;
06698       }
06699       /* A full frame */
06700       if (res < sizeof(*fh)) {
06701          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
06702          ast_mutex_unlock(&iaxsl[fr->callno]);
06703          return 1;
06704       }
06705       f.datalen = res - sizeof(*fh);
06706 
06707       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
06708          from the real peer, not the transfer peer */
06709       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06710           ((f.subclass != IAX_COMMAND_INVAL) ||
06711            (f.frametype != AST_FRAME_IAX))) {
06712          unsigned char x;
06713          /* XXX This code is not very efficient.  Surely there is a better way which still
06714                 properly handles boundary conditions? XXX */
06715          /* First we have to qualify that the ACKed value is within our window */
06716          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
06717             if (fr->iseqno == x)
06718                break;
06719          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
06720             /* The acknowledgement is within our window.  Time to acknowledge everything
06721                that it says to */
06722             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
06723                /* Ack the packet with the given timestamp */
06724                if (option_debug && iaxdebug)
06725                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
06726                ast_mutex_lock(&iaxq.lock);
06727                for (cur = iaxq.head; cur ; cur = cur->next) {
06728                   /* If it's our call, and our timestamp, mark -1 retries */
06729                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
06730                      cur->retries = -1;
06731                      /* Destroy call if this is the end */
06732                      if (cur->final) { 
06733                         if (iaxdebug && option_debug)
06734                            ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
06735                         iax2_destroy_nolock(fr->callno);
06736                      }
06737                   }
06738                }
06739                ast_mutex_unlock(&iaxq.lock);
06740             }
06741             /* Note how much we've received acknowledgement for */
06742             if (iaxs[fr->callno])
06743                iaxs[fr->callno]->rseqno = fr->iseqno;
06744             else {
06745                /* Stop processing now */
06746                ast_mutex_unlock(&iaxsl[fr->callno]);
06747                return 1;
06748             }
06749          } else
06750             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
06751       }
06752       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
06753          ((f.frametype != AST_FRAME_IAX) || 
06754           ((f.subclass != IAX_COMMAND_TXACC) &&
06755            (f.subclass != IAX_COMMAND_TXCNT)))) {
06756          /* Only messages we accept from a transfer host are TXACC and TXCNT */
06757          ast_mutex_unlock(&iaxsl[fr->callno]);
06758          return 1;
06759       }
06760 
06761       if (f.datalen) {
06762          if (f.frametype == AST_FRAME_IAX) {
06763             if (iax_parse_ies(&ies, buf + sizeof(*fh), f.datalen)) {
06764                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
06765                ast_mutex_unlock(&iaxsl[fr->callno]);
06766                return 1;
06767             }
06768             f.data = NULL;
06769          } else
06770             f.data = buf + sizeof(*fh);
06771       } else {
06772          if (f.frametype == AST_FRAME_IAX)
06773             f.data = NULL;
06774          else
06775             f.data = empty;
06776          memset(&ies, 0, sizeof(ies));
06777       }
06778       if (f.frametype == AST_FRAME_VOICE) {
06779          if (f.subclass != iaxs[fr->callno]->voiceformat) {
06780                iaxs[fr->callno]->voiceformat = f.subclass;
06781                ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
06782                if (iaxs[fr->callno]->owner) {
06783                   int orignative;
06784 retryowner:
06785                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
06786                      ast_mutex_unlock(&iaxsl[fr->callno]);
06787                      usleep(1);
06788                      ast_mutex_lock(&iaxsl[fr->callno]);
06789                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
06790                   }
06791                   if (iaxs[fr->callno]) {
06792                      if (iaxs[fr->callno]->owner) {
06793                         orignative = iaxs[fr->callno]->owner->nativeformats;
06794                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
06795                         if (iaxs[fr->callno]->owner->readformat)
06796                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
06797                         iaxs[fr->callno]->owner->nativeformats = orignative;
06798                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
06799                      }
06800                   } else {
06801                      ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
06802                      ast_mutex_unlock(&iaxsl[fr->callno]);
06803                      return 1;
06804                   }
06805                }
06806          }
06807       }
06808       if (f.frametype == AST_FRAME_VIDEO) {
06809          if (f.subclass != iaxs[fr->callno]->videoformat) {
06810             ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
06811             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
06812          }
06813       }
06814       if (f.frametype == AST_FRAME_IAX) {
06815          if (iaxs[fr->callno]->initid > -1) {
06816             /* Don't auto congest anymore since we've gotten something usefulb ack */
06817             ast_sched_del(sched, iaxs[fr->callno]->initid);
06818             iaxs[fr->callno]->initid = -1;
06819          }
06820          /* Handle the IAX pseudo frame itself */
06821          if (option_debug && iaxdebug)
06822             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
06823 
06824                         /* Update last ts unless the frame's timestamp originated with us. */
06825          if (iaxs[fr->callno]->last < fr->ts &&
06826                             f.subclass != IAX_COMMAND_ACK &&
06827                             f.subclass != IAX_COMMAND_PONG &&
06828                             f.subclass != IAX_COMMAND_LAGRP) {
06829             iaxs[fr->callno]->last = fr->ts;
06830             if (option_debug && iaxdebug)
06831                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06832          }
06833 
06834          switch(f.subclass) {
06835          case IAX_COMMAND_ACK:
06836             /* Do nothing */
06837             break;
06838          case IAX_COMMAND_QUELCH:
06839             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06840                     /* Generate Manager Hold event, if necessary*/
06841                if (iaxs[fr->callno]->owner) {
06842                   manager_event(EVENT_FLAG_CALL, "Hold",
06843                      "Channel: %s\r\n"
06844                      "Uniqueid: %s\r\n",
06845                      iaxs[fr->callno]->owner->name, 
06846                      iaxs[fr->callno]->owner->uniqueid);
06847                }
06848 
06849                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
06850                if (ies.musiconhold) {
06851                   if (iaxs[fr->callno]->owner &&
06852                      ast_bridged_channel(iaxs[fr->callno]->owner))
06853                         ast_moh_start(ast_bridged_channel(iaxs[fr->callno]->owner), NULL);
06854                }
06855             }
06856             break;
06857          case IAX_COMMAND_UNQUELCH:
06858             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06859                     /* Generate Manager Unhold event, if necessary*/
06860                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
06861                   manager_event(EVENT_FLAG_CALL, "Unhold",
06862                      "Channel: %s\r\n"
06863                      "Uniqueid: %s\r\n",
06864                      iaxs[fr->callno]->owner->name, 
06865                      iaxs[fr->callno]->owner->uniqueid);
06866                }
06867 
06868                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
06869                if (iaxs[fr->callno]->owner &&
06870                   ast_bridged_channel(iaxs[fr->callno]->owner))
06871                      ast_moh_stop(ast_bridged_channel(iaxs[fr->callno]->owner));
06872             }
06873             break;
06874          case IAX_COMMAND_TXACC:
06875             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
06876                /* Ack the packet with the given timestamp */
06877                ast_mutex_lock(&iaxq.lock);
06878                for (cur = iaxq.head; cur ; cur = cur->next) {
06879                   /* Cancel any outstanding txcnt's */
06880                   if ((fr->callno == cur->callno) && (cur->transfer))
06881                      cur->retries = -1;
06882                }
06883                ast_mutex_unlock(&iaxq.lock);
06884                memset(&ied1, 0, sizeof(ied1));
06885                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
06886                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
06887                iaxs[fr->callno]->transferring = TRANSFER_READY;
06888             }
06889             break;
06890          case IAX_COMMAND_NEW:
06891             /* Ignore if it's already up */
06892             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
06893                break;
06894             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
06895                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
06896             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
06897             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
06898                fr->callno = make_trunk(fr->callno, 1);
06899             }
06900             /* For security, always ack immediately */
06901             if (delayreject)
06902                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06903             if (check_access(fr->callno, &sin, &ies)) {
06904                /* They're not allowed on */
06905                auth_fail(fr->callno, IAX_COMMAND_REJECT);
06906                if (authdebug)
06907                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
06908                break;
06909             }
06910             /* This might re-enter the IAX code and need the lock */
06911             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
06912                ast_mutex_unlock(&iaxsl[fr->callno]);
06913                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
06914                ast_mutex_lock(&iaxsl[fr->callno]);
06915             } else
06916                exists = 0;
06917             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
06918                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
06919                   memset(&ied0, 0, sizeof(ied0));
06920                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
06921                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
06922                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06923                   if (authdebug)
06924                      ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
06925                } else {
06926                   /* Select an appropriate format */
06927 
06928                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06929                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06930                         using_prefs = "reqonly";
06931                      } else {
06932                         using_prefs = "disabled";
06933                      }
06934                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
06935                      memset(&pref, 0, sizeof(pref));
06936                      strcpy(caller_pref_buf, "disabled");
06937                      strcpy(host_pref_buf, "disabled");
06938                   } else {
06939                      using_prefs = "mine";
06940                      /* If the information elements are in here... use them */
06941                      if (ies.codec_prefs)
06942                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
06943                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06944                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
06945                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06946                            pref = iaxs[fr->callno]->rprefs;
06947                            using_prefs = "caller";
06948                         } else {
06949                            pref = iaxs[fr->callno]->prefs;
06950                         }
06951                      } else
06952                         pref = iaxs[fr->callno]->prefs;
06953                      
06954                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
06955                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
06956                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
06957                   }
06958                   if (!format) {
06959                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06960                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
06961                      if (!format) {
06962                         memset(&ied0, 0, sizeof(ied0));
06963                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06964                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06965                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06966                         if (authdebug) {
06967                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06968                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
06969                            else 
06970                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
06971                         }
06972                      } else {
06973                         /* Pick one... */
06974                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06975                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
06976                               format = 0;
06977                         } else {
06978                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06979                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
06980                               memset(&pref, 0, sizeof(pref));
06981                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06982                               strcpy(caller_pref_buf,"disabled");
06983                               strcpy(host_pref_buf,"disabled");
06984                            } else {
06985                               using_prefs = "mine";
06986                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06987                                  /* Do the opposite of what we tried above. */
06988                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06989                                     pref = iaxs[fr->callno]->prefs;                       
06990                                  } else {
06991                                     pref = iaxs[fr->callno]->rprefs;
06992                                     using_prefs = "caller";
06993                                  }
06994                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
06995                            
06996                               } else /* if no codec_prefs IE do it the old way */
06997                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
06998                            }
06999                         }
07000 
07001                         if (!format) {
07002                            memset(&ied0, 0, sizeof(ied0));
07003                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07004                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07005                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07006                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07007                            if (authdebug)
07008                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07009                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07010                            break;
07011                         }
07012                      }
07013                   }
07014                   if (format) {
07015                      /* No authentication required, let them in */
07016                      memset(&ied1, 0, sizeof(ied1));
07017                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07018                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07019                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07020                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07021                         if (option_verbose > 2) 
07022                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07023                                     "%srequested format = %s,\n"
07024                                     "%srequested prefs = %s,\n"
07025                                     "%sactual format = %s,\n"
07026                                     "%shost prefs = %s,\n"
07027                                     "%spriority = %s\n",
07028                                     ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 
07029                                     VERBOSE_PREFIX_4,
07030                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07031                                     VERBOSE_PREFIX_4,
07032                                     caller_pref_buf,
07033                                     VERBOSE_PREFIX_4,
07034                                     ast_getformatname(format), 
07035                                     VERBOSE_PREFIX_4,
07036                                     host_pref_buf, 
07037                                     VERBOSE_PREFIX_4,
07038                                     using_prefs);
07039                         
07040                         if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07041                            iax2_destroy_nolock(fr->callno);
07042                      } else {
07043                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07044                         /* If this is a TBD call, we're ready but now what...  */
07045                         if (option_verbose > 2)
07046                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
07047                      }
07048                   }
07049                }
07050                break;
07051             }
07052             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07053                merge_encryption(iaxs[fr->callno],ies.encmethods);
07054             else
07055                iaxs[fr->callno]->encmethods = 0;
07056             if (!authenticate_request(iaxs[fr->callno]))
07057                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07058             break;
07059          case IAX_COMMAND_DPREQ:
07060             /* Request status in the dialplan */
07061             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07062                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07063                if (iaxcompat) {
07064                   /* Spawn a thread for the lookup */
07065                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07066                } else {
07067                   /* Just look it up */
07068                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07069                }
07070             }
07071             break;
07072          case IAX_COMMAND_HANGUP:
07073             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07074             ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07075             /* Set hangup cause according to remote */
07076             if (ies.causecode && iaxs[fr->callno]->owner)
07077                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07078             /* Send ack immediately, before we destroy */
07079             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07080             iax2_destroy_nolock(fr->callno);
07081             break;
07082          case IAX_COMMAND_REJECT:
07083             memset(&f, 0, sizeof(f));
07084             f.frametype = AST_FRAME_CONTROL;
07085             f.subclass = AST_CONTROL_CONGESTION;
07086 
07087             /* Set hangup cause according to remote */
07088             if (ies.causecode && iaxs[fr->callno]->owner)
07089                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07090 
07091             iax2_queue_frame(fr->callno, &f);
07092             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07093                /* Send ack immediately, before we destroy */
07094                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07095                iax2_destroy_nolock(fr->callno);
07096                break;
07097             }
07098             if (iaxs[fr->callno]->owner) {
07099                if (authdebug)
07100                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ies.cause ? ies.cause : "<Unknown>");
07101             }
07102             ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", fr->callno);
07103             /* Send ack immediately, before we destroy */
07104             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07105             iaxs[fr->callno]->error = EPERM;
07106             iax2_destroy_nolock(fr->callno);
07107             break;
07108          case IAX_COMMAND_TRANSFER:
07109             if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07110                if (!strcmp(ies.called_number, ast_parking_ext())) {
07111                   if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07112                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07113                   } else
07114                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07115                } else {
07116                   if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07117                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07118                         ies.called_number, iaxs[fr->callno]->context);
07119                   else
07120                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name, 
07121                         ies.called_number, iaxs[fr->callno]->context);
07122                }
07123             } else
07124                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07125             break;
07126          case IAX_COMMAND_ACCEPT:
07127             /* Ignore if call is already up or needs authentication or is a TBD */
07128             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07129                break;
07130             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07131                /* Send ack immediately, before we destroy */
07132                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07133                iax2_destroy_nolock(fr->callno);
07134                break;
07135             }
07136             if (ies.format) {
07137                iaxs[fr->callno]->peerformat = ies.format;
07138             } else {
07139                if (iaxs[fr->callno]->owner)
07140                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07141                else
07142                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07143             }
07144             if (option_verbose > 2)
07145                ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
07146             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07147                memset(&ied0, 0, sizeof(ied0));
07148                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07149                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07150                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07151                if (authdebug)
07152                   ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07153             } else {
07154                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07155                if (iaxs[fr->callno]->owner) {
07156                   /* Switch us to use a compatible format */
07157                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07158                   if (option_verbose > 2)
07159                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07160 retryowner2:
07161                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07162                      ast_mutex_unlock(&iaxsl[fr->callno]);
07163                      usleep(1);
07164                      ast_mutex_lock(&iaxsl[fr->callno]);
07165                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07166                   }
07167                   
07168                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07169                      /* Setup read/write formats properly. */
07170                      if (iaxs[fr->callno]->owner->writeformat)
07171                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07172                      if (iaxs[fr->callno]->owner->readformat)
07173                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07174                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07175                   }
07176                }
07177             }
07178             ast_mutex_lock(&dpcache_lock);
07179             dp = iaxs[fr->callno]->dpentries;
07180             while(dp) {
07181                if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07182                   iax2_dprequest(dp, fr->callno);
07183                }
07184                dp = dp->peer;
07185             }
07186             ast_mutex_unlock(&dpcache_lock);
07187             break;
07188          case IAX_COMMAND_POKE:
07189             /* Send back a pong packet with the original timestamp */
07190             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07191             break;
07192          case IAX_COMMAND_PING:
07193 #ifdef BRIDGE_OPTIMIZATION
07194             if (iaxs[fr->callno]->bridgecallno) {
07195                /* If we're in a bridged call, just forward this */
07196                forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PING, fr->ts, NULL, 0, -1);
07197             } else {
07198                struct iax_ie_data pingied;
07199                construct_rr(iaxs[fr->callno], &pingied);
07200                /* Send back a pong packet with the original timestamp */
07201                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07202             }
07203 #else          
07204             {
07205                struct iax_ie_data pingied;
07206                construct_rr(iaxs[fr->callno], &pingied);
07207             /* Send back a pong packet with the original timestamp */
07208                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07209             }
07210 #endif         
07211             break;
07212          case IAX_COMMAND_PONG:
07213 #ifdef BRIDGE_OPTIMIZATION
07214             if (iaxs[fr->callno]->bridgecallno) {
07215                /* Forward to the other side of the bridge */
07216                forward_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07217             } else {
07218                /* Calculate ping time */
07219                iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07220             }
07221 #else
07222             /* Calculate ping time */
07223             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07224 #endif
07225             /* save RR info */
07226             save_rr(fr, &ies);
07227 
07228             if (iaxs[fr->callno]->peerpoke) {
07229                peer = iaxs[fr->callno]->peerpoke;
07230                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07231                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07232                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07233                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07234                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07235                   }
07236                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07237                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07238                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07239                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07240                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07241                   }
07242                }
07243                peer->lastms = iaxs[fr->callno]->pingtime;
07244                if (peer->smoothing && (peer->lastms > -1))
07245                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07246                else if (peer->smoothing && peer->lastms < 0)
07247                   peer->historicms = (0 + peer->historicms) / 2;
07248                else              
07249                   peer->historicms = iaxs[fr->callno]->pingtime;
07250 
07251                if (peer->pokeexpire > -1)
07252                   ast_sched_del(sched, peer->pokeexpire);
07253                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07254                iax2_destroy_nolock(fr->callno);
07255                peer->callno = 0;
07256                /* Try again eventually */
07257                   ast_log(LOG_DEBUG, "Peer lastms %d, historicms %d, maxms %d\n", peer->lastms, peer->historicms, peer->maxms);
07258                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07259                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07260                else
07261                   peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07262             }
07263             break;
07264          case IAX_COMMAND_LAGRQ:
07265          case IAX_COMMAND_LAGRP:
07266 #ifdef BRIDGE_OPTIMIZATION
07267             if (iaxs[fr->callno]->bridgecallno) {
07268                forward_command(iaxs[fr->callno], AST_FRAME_IAX, f.subclass, fr->ts, NULL, 0, -1);
07269             } else {
07270 #endif            
07271                f.src = "LAGRQ";
07272                f.mallocd = 0;
07273                f.offset = 0;
07274                f.samples = 0;
07275                iax_frame_wrap(fr, &f);
07276                if(f.subclass == IAX_COMMAND_LAGRQ) {
07277                    /* Received a LAGRQ - echo back a LAGRP */
07278                    fr->af.subclass = IAX_COMMAND_LAGRP;
07279                    iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07280                } else {
07281                    /* Received LAGRP in response to our LAGRQ */
07282                    unsigned int ts;
07283                    /* This is a reply we've been given, actually measure the difference */
07284                    ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07285                    iaxs[fr->callno]->lag = ts - fr->ts;
07286                    if (option_debug && iaxdebug)
07287                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07288                         ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07289                }
07290 #ifdef BRIDGE_OPTIMIZATION
07291             }
07292 #endif            
07293             break;
07294          case IAX_COMMAND_AUTHREQ:
07295             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07296                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07297                break;
07298             }
07299             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07300                ast_log(LOG_WARNING, 
07301                   "I don't know how to authenticate %s to %s\n", 
07302                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr));
07303             }
07304             break;
07305          case IAX_COMMAND_AUTHREP:
07306             /* For security, always ack immediately */
07307             if (delayreject)
07308                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07309             /* Ignore once we've started */
07310             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07311                ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07312                break;
07313             }
07314             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07315                if (authdebug)
07316                   ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
07317                memset(&ied0, 0, sizeof(ied0));
07318                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07319                break;
07320             }
07321             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07322                /* This might re-enter the IAX code and need the lock */
07323                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07324             } else
07325                exists = 0;
07326             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07327                if (authdebug)
07328                   ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07329                memset(&ied0, 0, sizeof(ied0));
07330                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07331                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07332                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07333             } else {
07334                /* Select an appropriate format */
07335                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07336                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07337                      using_prefs = "reqonly";
07338                   } else {
07339                      using_prefs = "disabled";
07340                   }
07341                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07342                   memset(&pref, 0, sizeof(pref));
07343                   strcpy(caller_pref_buf, "disabled");
07344                   strcpy(host_pref_buf, "disabled");
07345                } else {
07346                   using_prefs = "mine";
07347                   if (ies.codec_prefs)
07348                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07349                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07350                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07351                         pref = iaxs[fr->callno]->rprefs;
07352                         using_prefs = "caller";
07353                      } else {
07354                         pref = iaxs[fr->callno]->prefs;
07355                      }
07356                   } else /* if no codec_prefs IE do it the old way */
07357                      pref = iaxs[fr->callno]->prefs;
07358                
07359                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07360                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07361                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07362                }
07363                if (!format) {
07364                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07365                      ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
07366                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07367                   }
07368                   if (!format) {
07369                      if (authdebug) {
07370                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07371                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07372                         else
07373                            ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07374                      }
07375                      memset(&ied0, 0, sizeof(ied0));
07376                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07377                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07378                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07379                   } else {
07380                      /* Pick one... */
07381                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07382                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07383                            format = 0;
07384                      } else {
07385                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07386                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07387                            memset(&pref, 0, sizeof(pref));
07388                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07389                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07390                            strcpy(caller_pref_buf,"disabled");
07391                            strcpy(host_pref_buf,"disabled");
07392                         } else {
07393                            using_prefs = "mine";
07394                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07395                               /* Do the opposite of what we tried above. */
07396                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07397                                  pref = iaxs[fr->callno]->prefs;                 
07398                               } else {
07399                                  pref = iaxs[fr->callno]->rprefs;
07400                                  using_prefs = "caller";
07401                               }
07402                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07403                            } else /* if no codec_prefs IE do it the old way */
07404                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07405                         }
07406                      }
07407                      if (!format) {
07408                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07409                         if (authdebug) {
07410                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07411                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
07412                            else
07413                               ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
07414                         }
07415                         memset(&ied0, 0, sizeof(ied0));
07416                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07417                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07418                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07419                      }
07420                   }
07421                }
07422                if (format) {
07423                   /* Authentication received */
07424                   memset(&ied1, 0, sizeof(ied1));
07425                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07426                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07427                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07428                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07429                      if (option_verbose > 2) 
07430                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07431                                  "%srequested format = %s,\n"
07432                                  "%srequested prefs = %s,\n"
07433                                  "%sactual format = %s,\n"
07434                                  "%shost prefs = %s,\n"
07435                                  "%spriority = %s\n", 
07436                                  ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), 
07437                                  VERBOSE_PREFIX_4,
07438                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07439                                  VERBOSE_PREFIX_4,
07440                                  caller_pref_buf,
07441                                  VERBOSE_PREFIX_4,
07442                                  ast_getformatname(format),
07443                                  VERBOSE_PREFIX_4,
07444                                  host_pref_buf,
07445                                  VERBOSE_PREFIX_4,
07446                                  using_prefs);
07447 
07448                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07449                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07450                         iax2_destroy_nolock(fr->callno);
07451                   } else {
07452                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07453                      /* If this is a TBD call, we're ready but now what...  */
07454                      if (option_verbose > 2)
07455                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
07456                   }
07457                }
07458             }
07459             break;
07460          case IAX_COMMAND_DIAL:
07461             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07462                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07463                ast_copy_string(iaxs[fr->callno]->exten, ies.called_number ? ies.called_number : "s", sizeof(iaxs[fr->callno]->exten)); 
07464                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07465                   if (authdebug)
07466                      ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
07467                   memset(&ied0, 0, sizeof(ied0));
07468                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07469                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07470                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07471                } else {
07472                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07473                   if (option_verbose > 2) 
07474                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), iaxs[fr->callno]->peerformat);
07475                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07476                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07477                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07478                      iax2_destroy_nolock(fr->callno);
07479                }
07480             }
07481             break;
07482          case IAX_COMMAND_INVAL:
07483             iaxs[fr->callno]->error = ENOTCONN;
07484             ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07485             iax2_destroy_nolock(fr->callno);
07486             if (option_debug)
07487                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07488             break;
07489          case IAX_COMMAND_VNAK:
07490             ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07491             /* Force retransmission */
07492             vnak_retransmit(fr->callno, fr->iseqno);
07493             break;
07494          case IAX_COMMAND_REGREQ:
07495          case IAX_COMMAND_REGREL:
07496             /* For security, always ack immediately */
07497             if (delayreject)
07498                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07499             if (register_verify(fr->callno, &sin, &ies)) {
07500                /* Send delayed failure */
07501                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07502                break;
07503             }
07504             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
07505                if (f.subclass == IAX_COMMAND_REGREL)
07506                   memset(&sin, 0, sizeof(sin));
07507                if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
07508                   ast_log(LOG_WARNING, "Registry error\n");
07509                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
07510                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07511                break;
07512             }
07513             registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
07514             break;
07515          case IAX_COMMAND_REGACK:
07516             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
07517                ast_log(LOG_WARNING, "Registration failure\n");
07518             /* Send ack immediately, before we destroy */
07519             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07520             iax2_destroy_nolock(fr->callno);
07521             break;
07522          case IAX_COMMAND_REGREJ:
07523             if (iaxs[fr->callno]->reg) {
07524                if (authdebug) {
07525                   ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr));
07526                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
07527                }
07528                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
07529             }
07530             /* Send ack immediately, before we destroy */
07531             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07532             iax2_destroy_nolock(fr->callno);
07533             break;
07534          case IAX_COMMAND_REGAUTH:
07535             /* Authentication request */
07536             if (registry_rerequest(&ies, fr->callno, &sin)) {
07537                memset(&ied0, 0, sizeof(ied0));
07538                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07539                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07540                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07541             }
07542             break;
07543          case IAX_COMMAND_TXREJ:
07544             iaxs[fr->callno]->transferring = 0;
07545             if (option_verbose > 2) 
07546                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07547             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
07548             if (iaxs[fr->callno]->bridgecallno) {
07549                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
07550                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
07551                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07552                }
07553             }
07554             break;
07555          case IAX_COMMAND_TXREADY:
07556             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07557                iaxs[fr->callno]->transferring = TRANSFER_READY;
07558                if (option_verbose > 2) 
07559                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07560                if (iaxs[fr->callno]->bridgecallno) {
07561                   if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) {
07562                      if (option_verbose > 2) 
07563                         ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07564                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07565 
07566                      /* They're both ready, now release them. */
07567                      iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07568                      iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
07569                      ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
07570                      ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07571 
07572                      /* Stop doing lag & ping requests */
07573                      stop_stuff(fr->callno);
07574                      stop_stuff(iaxs[fr->callno]->bridgecallno);
07575 
07576                      memset(&ied0, 0, sizeof(ied0));
07577                      memset(&ied1, 0, sizeof(ied1));
07578                      iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07579                      iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07580                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
07581                      send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
07582 
07583                   }
07584                }
07585             }
07586             break;
07587          case IAX_COMMAND_TXREQ:
07588             try_transfer(iaxs[fr->callno], &ies);
07589             break;
07590          case IAX_COMMAND_TXCNT:
07591             if (iaxs[fr->callno]->transferring)
07592                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
07593             break;
07594          case IAX_COMMAND_TXREL:
07595             /* Send ack immediately, rather than waiting until we've changed addresses */
07596             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07597             complete_transfer(fr->callno, &ies);
07598             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
07599             break;   
07600          case IAX_COMMAND_DPREP:
07601             complete_dpreply(iaxs[fr->callno], &ies);
07602             break;
07603          case IAX_COMMAND_UNSUPPORT:
07604             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
07605             break;
07606          case IAX_COMMAND_FWDOWNL:
07607             /* Firmware download */
07608             memset(&ied0, 0, sizeof(ied0));
07609             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
07610             if (res < 0)
07611                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07612             else if (res > 0)
07613                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07614             else
07615                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07616             break;
07617          default:
07618             ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
07619             memset(&ied0, 0, sizeof(ied0));
07620             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
07621             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
07622          }
07623          /* Don't actually pass these frames along */
07624          if ((f.subclass != IAX_COMMAND_ACK) && 
07625            (f.subclass != IAX_COMMAND_TXCNT) && 
07626            (f.subclass != IAX_COMMAND_TXACC) && 
07627            (f.subclass != IAX_COMMAND_INVAL) &&
07628            (f.subclass != IAX_COMMAND_VNAK)) { 
07629             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07630                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07631          }
07632          ast_mutex_unlock(&iaxsl[fr->callno]);
07633          return 1;
07634       }
07635       /* Unless this is an ACK or INVAL frame, ack it */
07636       if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07637          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07638    } else if (minivid) {
07639       f.frametype = AST_FRAME_VIDEO;
07640       if (iaxs[fr->callno]->videoformat > 0) 
07641          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
07642       else {
07643          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
07644          iax2_vnak(fr->callno);
07645          ast_mutex_unlock(&iaxsl[fr->callno]);
07646          return 1;
07647       }
07648       f.datalen = res - sizeof(*vh);
07649       if (f.datalen)
07650          f.data = buf + sizeof(*vh);
07651       else
07652          f.data = NULL;
07653 #ifdef IAXTESTS
07654       if (test_resync) {
07655          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff);
07656       } else
07657 #endif /* IAXTESTS */
07658       fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff);
07659    } else {
07660       /* A mini frame */
07661       f.frametype = AST_FRAME_VOICE;
07662       if (iaxs[fr->callno]->voiceformat > 0)
07663          f.subclass = iaxs[fr->callno]->voiceformat;
07664       else {
07665          ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
07666          iax2_vnak(fr->callno);
07667          ast_mutex_unlock(&iaxsl[fr->callno]);
07668          return 1;
07669       }
07670       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
07671       if (f.datalen < 0) {
07672          ast_log(LOG_WARNING, "Datalen < 0?\n");
07673          ast_mutex_unlock(&iaxsl[fr->callno]);
07674          return 1;
07675       }
07676       if (f.datalen)
07677          f.data = buf + sizeof(*mh);
07678       else
07679          f.data = NULL;
07680 #ifdef IAXTESTS
07681       if (test_resync) {
07682          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
07683       } else
07684 #endif /* IAXTESTS */
07685       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
07686       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
07687    }
07688    /* Don't pass any packets until we're started */
07689    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07690       ast_mutex_unlock(&iaxsl[fr->callno]);
07691       return 1;
07692    }
07693    /* Common things */
07694    f.src = "IAX2";
07695    f.mallocd = 0;
07696    f.offset = 0;
07697    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
07698       f.samples = ast_codec_get_samples(&f);
07699       /* We need to byteswap incoming slinear samples from network byte order */
07700       if (f.subclass == AST_FORMAT_SLINEAR)
07701          ast_frame_byteswap_be(&f);
07702    } else
07703       f.samples = 0;
07704    iax_frame_wrap(fr, &f);
07705 
07706    /* If this is our most recent packet, use it as our basis for timestamping */
07707    if (iaxs[fr->callno]->last < fr->ts) {
07708       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
07709       fr->outoforder = 0;
07710    } else {
07711       if (option_debug && iaxdebug)
07712          ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
07713       fr->outoforder = -1;
07714    }
07715 #ifdef BRIDGE_OPTIMIZATION
07716    if (iaxs[fr->callno]->bridgecallno) {
07717       forward_delivery(fr);
07718    } else {
07719       duped_fr = iaxfrdup2(fr);
07720       if (duped_fr) {
07721          schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07722       }
07723    }
07724 #else
07725    duped_fr = iaxfrdup2(fr);
07726    if (duped_fr) {
07727       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07728    }
07729 #endif
07730 
07731    if (iaxs[fr->callno]->last < fr->ts) {
07732       iaxs[fr->callno]->last = fr->ts;
07733 #if 1
07734       if (option_debug && iaxdebug)
07735          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07736 #endif
07737    }
07738 
07739    /* Always run again */
07740    ast_mutex_unlock(&iaxsl[fr->callno]);
07741    return 1;
07742 }

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

Definition at line 6204 of file chan_iax2.c.

References ast_log(), ast_pthread_create, dp_lookup_thread(), LOG_WARNING, malloc, and strdup.

Referenced by socket_read().

06205 {
06206    pthread_t newthread;
06207    struct dpreq_data *dpr;
06208    dpr = malloc(sizeof(struct dpreq_data));
06209    if (dpr) {
06210       memset(dpr, 0, sizeof(struct dpreq_data));
06211       dpr->callno = callno;
06212       ast_copy_string(dpr->context, context, sizeof(dpr->context));
06213       ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06214       if (callerid)
06215          dpr->callerid = strdup(callerid);
06216       if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) {
06217          ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06218       }
06219    } else
06220       ast_log(LOG_WARNING, "Out of memory!\n");
06221 }

static int start_network_thread void   )  [static]
 

Definition at line 8108 of file chan_iax2.c.

References ast_pthread_create, netthreadid, and network_thread().

Referenced by load_module().

08109 {
08110    return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
08111 }

static int stop_stuff int  callno  )  [static]
 

Definition at line 5904 of file chan_iax2.c.

References ast_sched_del().

Referenced by socket_read().

05905 {
05906       if (iaxs[callno]->lagid > -1)
05907          ast_sched_del(sched, iaxs[callno]->lagid);
05908       iaxs[callno]->lagid = -1;
05909       if (iaxs[callno]->pingid > -1)
05910          ast_sched_del(sched, iaxs[callno]->pingid);
05911       iaxs[callno]->pingid = -1;
05912       if (iaxs[callno]->autoid > -1)
05913          ast_sched_del(sched, iaxs[callno]->autoid);
05914       iaxs[callno]->autoid = -1;
05915       if (iaxs[callno]->initid > -1)
05916          ast_sched_del(sched, iaxs[callno]->initid);
05917       iaxs[callno]->initid = -1;
05918       if (iaxs[callno]->authid > -1)
05919          ast_sched_del(sched, iaxs[callno]->authid);
05920       iaxs[callno]->authid = -1;
05921 #ifdef NEWJB
05922       if (iaxs[callno]->jbid > -1)
05923          ast_sched_del(sched, iaxs[callno]->jbid);
05924       iaxs[callno]->jbid = -1;
05925 #endif
05926       return 0;
05927 }

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

Definition at line 6077 of file chan_iax2.c.

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

Referenced by network_thread().

06078 {
06079    char buf[1024];
06080    int res;
06081    char iabuf[INET_ADDRSTRLEN];
06082    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06083    int processed = 0;
06084    int totalcalls = 0;
06085 #ifdef ZT_TIMERACK
06086    int x = 1;
06087 #endif
06088    struct timeval now;
06089    if (iaxtrunkdebug)
06090       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06091    gettimeofday(&now, NULL);
06092    if (events & AST_IO_PRI) {
06093 #ifdef ZT_TIMERACK
06094       /* Great, this is a timing interface, just call the ioctl */
06095       if (ioctl(fd, ZT_TIMERACK, &x)) 
06096          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06097       res = 0;
06098 #endif      
06099    } else {
06100       /* Read and ignore from the pseudo channel for timing */
06101       res = read(fd, buf, sizeof(buf));
06102       if (res < 1) {
06103          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06104          ast_mutex_unlock(&peerl.lock);
06105          return 1;
06106       }
06107    }
06108    /* For each peer that supports trunking... */
06109    ast_mutex_lock(&tpeerlock);
06110    tpeer = tpeers;
06111    while(tpeer) {
06112       processed++;
06113       res = 0;
06114       ast_mutex_lock(&tpeer->lock);
06115       /* We can drop a single tpeer per pass.  That makes all this logic
06116          substantially easier */
06117       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06118          /* Take it out of the list, but don't free it yet, because it
06119             could be in use */
06120          if (prev)
06121             prev->next = tpeer->next;
06122          else
06123             tpeers = tpeer->next;
06124          drop = tpeer;
06125       } else {
06126          res = send_trunk(tpeer, &now);
06127          if (iaxtrunkdebug)
06128             ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
06129       }     
06130       totalcalls += res;   
06131       res = 0;
06132       ast_mutex_unlock(&tpeer->lock);
06133       prev = tpeer;
06134       tpeer = tpeer->next;
06135    }
06136    ast_mutex_unlock(&tpeerlock);
06137    if (drop) {
06138       ast_mutex_lock(&drop->lock);
06139       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06140          because by the time they could get tpeerlock, we've already grabbed it */
06141       ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06142       free(drop->trunkdata);
06143       ast_mutex_unlock(&drop->lock);
06144       ast_mutex_destroy(&drop->lock);
06145       free(drop);
06146       
06147    }
06148    if (iaxtrunkdebug)
06149       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06150    iaxtrunkdebug =0;
06151    return 1;
06152 }

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

Definition at line 1486 of file chan_iax2.c.

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

Referenced by send_trunk().

01487 {
01488    int res;
01489    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01490                sizeof(*sin));
01491    if (res < 0) {
01492       if (option_debug)
01493          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01494       handle_error();
01495    } else
01496       res = 0;
01497    return res;
01498 }

static int try_firmware char *  s  )  [static]
 

Definition at line 1168 of file chan_iax2.c.

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

Referenced by reload_firmware().

01169 {
01170    struct stat stbuf;
01171    struct iax_firmware *cur;
01172    int ifd;
01173    int fd;
01174    int res;
01175    
01176    struct ast_iax2_firmware_header *fwh, fwh2;
01177    struct MD5Context md5;
01178    unsigned char sum[16];
01179    unsigned char buf[1024];
01180    int len, chunk;
01181    char *s2;
01182    char *last;
01183    s2 = alloca(strlen(s) + 100);
01184    if (!s2) {
01185       ast_log(LOG_WARNING, "Alloca failed!\n");
01186       return -1;
01187    }
01188    last = strrchr(s, '/');
01189    if (last)
01190       last++;
01191    else
01192       last = s;
01193    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)rand());
01194    res = stat(s, &stbuf);
01195    if (res < 0) {
01196       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01197       return -1;
01198    }
01199    /* Make sure it's not a directory */
01200    if (S_ISDIR(stbuf.st_mode))
01201       return -1;
01202    ifd = open(s, O_RDONLY);
01203    if (ifd < 0) {
01204       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01205       return -1;
01206    }
01207    fd = open(s2, O_RDWR | O_CREAT | O_EXCL);
01208    if (fd < 0) {
01209       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01210       close(ifd);
01211       return -1;
01212    }
01213    /* Unlink our newly created file */
01214    unlink(s2);
01215    
01216    /* Now copy the firmware into it */
01217    len = stbuf.st_size;
01218    while(len) {
01219       chunk = len;
01220       if (chunk > sizeof(buf))
01221          chunk = sizeof(buf);
01222       res = read(ifd, buf, chunk);
01223       if (res != chunk) {
01224          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01225          close(ifd);
01226          close(fd);
01227          return -1;
01228       }
01229       res = write(fd, buf, chunk);
01230       if (res != chunk) {
01231          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01232          close(ifd);
01233          close(fd);
01234          return -1;
01235       }
01236       len -= chunk;
01237    }
01238    close(ifd);
01239    /* Return to the beginning */
01240    lseek(fd, 0, SEEK_SET);
01241    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01242       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01243       close(fd);
01244       return -1;
01245    }
01246    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01247       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01248       close(fd);
01249       return -1;
01250    }
01251    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01252       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01253       close(fd);
01254       return -1;
01255    }
01256    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01257       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01258       close(fd);
01259       return -1;
01260    }
01261    fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01262    if (!fwh) {
01263       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01264       close(fd);
01265       return -1;
01266    }
01267    MD5Init(&md5);
01268    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01269    MD5Final(sum, &md5);
01270    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01271       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01272       munmap(fwh, stbuf.st_size);
01273       close(fd);
01274       return -1;
01275    }
01276    cur = waresl.wares;
01277    while(cur) {
01278       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01279          /* Found a candidate */
01280          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01281             /* The version we have on loaded is older, load this one instead */
01282             break;
01283          /* This version is no newer than what we have.  Don't worry about it.
01284             We'll consider it a proper load anyhow though */
01285          munmap(fwh, stbuf.st_size);
01286          close(fd);
01287          return 0;
01288       }
01289       cur = cur->next;
01290    }
01291    if (!cur) {
01292       /* Allocate a new one and link it */
01293       cur = malloc(sizeof(struct iax_firmware));
01294       if (cur) {
01295          memset(cur, 0, sizeof(struct iax_firmware));
01296          cur->fd = -1;
01297          cur->next = waresl.wares;
01298          waresl.wares = cur;
01299       }
01300    }
01301    if (cur) {
01302       if (cur->fwh) {
01303          munmap(cur->fwh, cur->mmaplen);
01304       }
01305       if (cur->fd > -1)
01306          close(cur->fd);
01307       cur->fwh = fwh;
01308       cur->fd = fd;
01309       cur->mmaplen = stbuf.st_size;
01310       cur->dead = 0;
01311    }
01312    return 0;
01313 }

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

Definition at line 5375 of file chan_iax2.c.

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

Referenced by socket_read().

05376 {
05377    int newcall = 0;
05378    char newip[256];
05379    struct iax_ie_data ied;
05380    struct sockaddr_in new;
05381    
05382    
05383    memset(&ied, 0, sizeof(ied));
05384    if (ies->apparent_addr)
05385       bcopy(ies->apparent_addr, &new, sizeof(new));
05386    if (ies->callno)
05387       newcall = ies->callno;
05388    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05389       ast_log(LOG_WARNING, "Invalid transfer request\n");
05390       return -1;
05391    }
05392    pvt->transfercallno = newcall;
05393    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05394    inet_aton(newip, &pvt->transfer.sin_addr);
05395    pvt->transfer.sin_family = AF_INET;
05396    pvt->transferring = TRANSFER_BEGIN;
05397    pvt->transferid = ies->transferid;
05398    if (ies->transferid)
05399       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05400    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05401    return 0; 
05402 }

static int uncompress_subclass unsigned char  csub  )  [static]
 

Definition at line 846 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), and socket_read().

00847 {
00848    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
00849    if (csub & IAX_FLAG_SC_LOG) {
00850       /* special case for 'compressed' -1 */
00851       if (csub == 0xff)
00852          return -1;
00853       else
00854          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
00855    }
00856    else
00857       return csub;
00858 }

int unload_module void   ) 
 

Cleanup all module structures, sockets, etc.

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

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

Definition at line 9655 of file chan_iax2.c.

References __unload_module(), ast_custom_function_unregister(), ast_mutex_destroy(), iaxpeer_function, iaxq, ast_firmware_list::lock, ast_peer_list::lock, ast_user_list::lock, ast_iax2_queue::lock, peerl, userl, and waresl.

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

Definition at line 3197 of file chan_iax2.c.

References ast_mutex_unlock(), and iaxsl.

Referenced by iax2_bridge().

03198 {
03199    ast_mutex_unlock(&iaxsl[callno1]);
03200    ast_mutex_unlock(&iaxsl[callno0]);
03201 }

static void unwrap_timestamp struct iax_frame fr  )  [static]
 

Definition at line 2160 of file chan_iax2.c.

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

Referenced by schedule_delivery().

02161 {
02162    int x;
02163 
02164    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02165       x = fr->ts - iaxs[fr->callno]->last;
02166       if (x < -50000) {
02167          /* Sudden big jump backwards in timestamp:
02168             What likely happened here is that miniframe timestamp has circled but we haven't
02169             gotten the update from the main packet.  We'll just pretend that we did, and
02170             update the timestamp appropriately. */
02171          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02172          if (option_debug && iaxdebug)
02173             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02174       }
02175       if (x > 50000) {
02176          /* Sudden apparent big jump forwards in timestamp:
02177             What's likely happened is this is an old miniframe belonging to the previous
02178             top-16-bit timestamp that has turned up out of order.
02179             Adjust the timestamp appropriately. */
02180          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02181          if (option_debug && iaxdebug)
02182             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02183       }
02184    }
02185 }

static void update_jbsched struct chan_iax2_pvt pvt  )  [static]
 

Definition at line 2190 of file chan_iax2.c.

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

Referenced by get_from_jb().

02190                                                       {
02191     int when;
02192 
02193     when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02194 
02195     when = jb_next(pvt->jb) - when;
02196 
02197     if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02198 
02199     if(when <= 0) {
02200       /* XXX should really just empty until when > 0.. */
02201       when = 1;
02202     }
02203 
02204     pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt);
02205 }

static void update_max_nontrunk void   )  [static]
 

Definition at line 995 of file chan_iax2.c.

References iaxs, and TRUNK_CALL_START.

00996 {
00997    int max = 1;
00998    int x;
00999    /* XXX Prolly don't need locks here XXX */
01000    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01001       if (iaxs[x])
01002          max = x + 1;
01003    }
01004    maxnontrunkcall = max;
01005    if (option_debug && iaxdebug)
01006       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01007 }

static void update_max_trunk void   )  [static]
 

Definition at line 981 of file chan_iax2.c.

References IAX_MAX_CALLS, iaxs, and TRUNK_CALL_START.

Referenced by iax2_destroy().

00982 {
00983    int max = TRUNK_CALL_START;
00984    int x;
00985    /* XXX Prolly don't need locks here XXX */
00986    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
00987       if (iaxs[x])
00988          max = x + 1;
00989    }
00990    maxtrunkcall = max;
00991    if (option_debug && iaxdebug)
00992       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
00993 }

static int update_packet struct iax_frame f  )  [static]
 

Definition at line 1724 of file chan_iax2.c.

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

Referenced by attempt_transmit().

01725 {
01726    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
01727    struct ast_iax2_full_hdr *fh = f->data;
01728    /* Mark this as a retransmission */
01729    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
01730    /* Update iseqno */
01731    f->iseqno = iaxs[f->callno]->iseqno;
01732    fh->iseqno = f->iseqno;
01733    return 0;
01734 }

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

Definition at line 5725 of file chan_iax2.c.

References iax2_peer::addr, ast_app_has_voicemail(), ast_app_messagecount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sched_add(), ast_sched_del(), ast_strlen_zero(), ast_test_flag, ast_verbose(), destroy_peer(), EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_MESSAGEDETAIL, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), LOG_WARNING, manager_event(), max_reg_expire, min_reg_expire, iax2_peer::name, option_verbose, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and VERBOSE_PREFIX_3.

Referenced by socket_read().

05726 {
05727    /* Called from IAX thread only, with proper iaxsl lock */
05728    struct iax_ie_data ied;
05729    struct iax2_peer *p;
05730    int msgcount;
05731    char data[80];
05732    char iabuf[INET_ADDRSTRLEN];
05733    int version;
05734 
05735    memset(&ied, 0, sizeof(ied));
05736 
05737    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05738    if (!(p = find_peer(name, 1))) {
05739       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05740       return -1;
05741    }
05742 
05743    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05744       if (sin->sin_addr.s_addr) {
05745          time_t nowtime;
05746          time(&nowtime);
05747          realtime_update_peer(name, sin, nowtime);
05748       } else
05749          realtime_update_peer(name, sin, 0);
05750    }
05751    if (inaddrcmp(&p->addr, sin)) {
05752       if (iax2_regfunk)
05753          iax2_regfunk(p->name, 1);
05754       /* Stash the IP address from which they registered */
05755       memcpy(&p->addr, sin, sizeof(p->addr));
05756       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05757       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05758          ast_db_put("IAX/Registry", p->name, data);
05759          if  (option_verbose > 2)
05760             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05761                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
05762          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05763          register_peer_exten(p, 1);
05764          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05765       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05766          if  (option_verbose > 2)
05767             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
05768                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05769          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05770          register_peer_exten(p, 0);
05771          ast_db_del("IAX/Registry", p->name);
05772          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05773       }
05774       /* Update the host */
05775       /* Verify that the host is really there */
05776       iax2_poke_peer(p, callno);
05777    }     
05778    /* Store socket fd */
05779    p->sockfd = fd;
05780    /* Setup the expiry */
05781    if (p->expire > -1)
05782       ast_sched_del(sched, p->expire);
05783    /* treat an unspecified refresh interval as the minimum */
05784    if (!refresh)
05785       refresh = min_reg_expire;
05786    if (refresh > max_reg_expire) {
05787       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05788          p->name, max_reg_expire, refresh);
05789       p->expiry = max_reg_expire;
05790    } else if (refresh < min_reg_expire) {
05791       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05792          p->name, min_reg_expire, refresh);
05793       p->expiry = min_reg_expire;
05794    } else {
05795       p->expiry = refresh;
05796    }
05797    if (p->expiry && sin->sin_addr.s_addr)
05798       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05799    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05800    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05801    if (sin->sin_addr.s_addr) {
05802       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05803       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05804       if (!ast_strlen_zero(p->mailbox)) {
05805          if (ast_test_flag(p, IAX_MESSAGEDETAIL)) {
05806             int new, old;
05807             ast_app_messagecount(p->mailbox, &new, &old);
05808             if (new > 255)
05809                new = 255;
05810             if (old > 255)
05811                old = 255;
05812             msgcount = (old << 8) | new;
05813          } else {
05814             msgcount = ast_app_has_voicemail(p->mailbox, NULL);
05815             if (msgcount)
05816                msgcount = 65535;
05817          }
05818          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05819       }
05820       if (ast_test_flag(p, IAX_HASCALLERID)) {
05821          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05822          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05823       }
05824    }
05825    version = iax_check_version(devtype);
05826    if (version) 
05827       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05828    if (ast_test_flag(p, IAX_TEMPONLY))
05829       destroy_peer(p);
05830    return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05831 }

int usecount void   ) 
 

Provides a usecount.

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

Returns:
The module's usecount.

Definition at line 9764 of file chan_iax2.c.

References usecnt.

09765 {
09766    return usecnt;
09767 }

static void vnak_retransmit int  callno,
int  last
[static]
 

Definition at line 6002 of file chan_iax2.c.

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

Referenced by socket_read().

06003 {
06004    struct iax_frame *f;
06005    ast_mutex_lock(&iaxq.lock);
06006    f = iaxq.head;
06007    while(f) {
06008       /* Send a copy immediately */
06009       if ((f->callno == callno) && iaxs[f->callno] &&
06010          (f->oseqno >= last)) {
06011          send_packet(f);
06012       }
06013       f = f->next;
06014    }
06015    ast_mutex_unlock(&iaxq.lock);
06016 }


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] [static]
 

Definition at line 225 of file chan_iax2.c.

Referenced by build_gateway(), check_access(), set_config(), and tds_log().

int amaflags = 0 [static]
 

Definition at line 226 of file chan_iax2.c.

Referenced by build_gateway(), and set_config().

int authdebug = 1 [static]
 

Definition at line 163 of file chan_iax2.c.

Referenced by register_verify().

int autokill = 0 [static]
 

Definition at line 164 of file chan_iax2.c.

Referenced by iax2_call(), and set_config().

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

Definition at line 143 of file chan_iax2.c.

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

Definition at line 145 of file chan_iax2.c.

char debug_jb_usage[] [static]
 

Initial value:

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

Definition at line 9554 of file chan_iax2.c.

char debug_trunk_usage[] [static]
 

Initial value:

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

Definition at line 9546 of file chan_iax2.c.

char debug_usage[] [static]
 

Initial value:

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

Definition at line 9538 of file chan_iax2.c.

int defaultsockfd = -1 [static]
 

Definition at line 179 of file chan_iax2.c.

Referenced by build_peer(), create_addr(), iax2_do_register(), load_module(), peer_set_srcaddr(), and set_config().

int delayreject = 0 [static]
 

Definition at line 227 of file chan_iax2.c.

Referenced by auth_fail(), set_config(), and socket_read().

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

Definition at line 141 of file chan_iax2.c.

struct iax2_dpcache * dpcache [static]
 

Referenced by find_cache(), and iax2_show_cache().

int global_rtautoclear = 120 [static]
 

Definition at line 272 of file chan_iax2.c.

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

struct ast_flags globalflags = { 0 } [static]
 

Definition at line 230 of file chan_iax2.c.

Referenced by build_peer(), build_user(), expire_registry(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), notify_new_message(), populate_defaults(), realtime_peer(), realtime_user(), send_trunk(), sendmail(), set_config(), update_registry(), and vm_execmain().

int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]
 

Definition at line 209 of file chan_iax2.c.

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

struct ast_cli_entry iax2_cli[] [static]
 

Definition at line 9580 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

int iax2_dropcount = DEFAULT_DROP [static]
 

Definition at line 211 of file chan_iax2.c.

int iax2_encryption = 0 [static]
 

Definition at line 228 of file chan_iax2.c.

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

enum { ... } iax2_flags
 

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

Definition at line 184 of file chan_iax2.c.

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

char iax2_reload_usage[] [static]
 

Initial value:

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

Definition at line 9500 of file chan_iax2.c.

enum { ... } iax2_state
 

struct ast_switch iax2_switch [static]
 

Definition at line 9474 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

const struct ast_channel_tech iax2_tech [static]
 

Definition at line 762 of file chan_iax2.c.

Referenced by __unload_module(), ast_iax2_new(), function_iaxpeer(), and load_module().

char iax2_test_losspct_usage[] [static]
 

Initial value:

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

Definition at line 9562 of file chan_iax2.c.

int iaxcompat = 0 [static]
 

Definition at line 165 of file chan_iax2.c.

Referenced by set_config(), and socket_read().

int iaxdebug = 0 [static]
 

Definition at line 213 of file chan_iax2.c.

Referenced by calc_rxstamp(), calc_timestamp(), decode_frame(), encrypt_frame(), iax2_do_debug(), iax2_do_register(), iax2_indicate(), iax2_no_debug(), iax2_send(), raw_hangup(), schedule_delivery(), send_packet(), socket_read(), and unwrap_timestamp().

int iaxdefaultdpcache = 10 * 60 [static]
 

Definition at line 167 of file chan_iax2.c.

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

int iaxdefaulttimeout = 5 [static]
 

Definition at line 169 of file chan_iax2.c.

Referenced by find_cache().

struct ast_custom_function iaxpeer_function
 

Definition at line 9412 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct ast_iax2_queue iaxq [static]
 

Referenced by attempt_transmit(), complete_transfer(), iax2_destroy(), iax2_show_stats(), iax2_transmit(), load_module(), network_thread(), socket_read(), unload_module(), and vnak_retransmit().

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static]
 

Definition at line 726 of file chan_iax2.c.

Referenced by __do_deliver(), attempt_transmit(), find_callno(), get_from_jb(), iax2_destroy(), iax2_predestroy(), iax2_queue_frame(), iax2_set_jitter(), iax_showframe(), make_trunk(), schedule_delivery(), send_lagrq(), send_packet(), send_ping(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), and update_packet().

ast_mutex_t iaxsl[IAX_MAX_CALLS] [static]
 

Definition at line 727 of file chan_iax2.c.

Referenced by ast_cli_netstats(), ast_iax2_new(), attempt_transmit(), auth_fail(), auth_reject(), auto_congest(), auto_hangup(), cache_get_callno_locked(), destroy_peer(), dp_lookup(), find_cache(), find_callno(), get_from_jb(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_destroy_nolock(), iax2_fixup(), iax2_hangup(), iax2_poke_peer(), iax2_predestroy(), iax2_predestroy_nolock(), iax2_provision(), iax2_queue_frame(), iax2_request(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), make_trunk(), register_verify(), send_command_locked(), socket_read(), and unlock_both().

int iaxtrunkdebug = 0 [static]
 

Definition at line 215 of file chan_iax2.c.

Referenced by iax2_do_trunk_debug(), iax2_no_trunk_debug(), and timing_read().

struct io_context* io [static]
 

Definition at line 206 of file chan_iax2.c.

char jitter_usage[] [static]
 

Definition at line 1855 of file chan_iax2.c.

int jittershrinkrate = 2 [static]
 

Definition at line 161 of file chan_iax2.c.

Referenced by set_config().

int lagrq_time = 10 [static]
 

Definition at line 153 of file chan_iax2.c.

Referenced by make_trunk(), and set_config().

char language[MAX_LANGUAGE] = "" [static]
 

Definition at line 147 of file chan_iax2.c.

struct timeval lastused[IAX_MAX_CALLS] [static]
 

Definition at line 728 of file chan_iax2.c.

Referenced by iax2_destroy(), and make_trunk().

int max_jitter_buffer = MAX_JITTER_BUFFER [static]
 

Definition at line 430 of file chan_iax2.c.

Referenced by iax2_set_jitter(), and set_config().

int max_reg_expire [static]
 

Definition at line 174 of file chan_iax2.c.

Referenced by set_config(), and update_registry().

int max_retries = 4 [static]
 

Definition at line 151 of file chan_iax2.c.

Referenced by attempt_transmit().

int maxauthreq = 0 [static]
 

Definition at line 150 of file chan_iax2.c.

Referenced by build_user(), and set_config().

int maxjitterbuffer = 1000 [static]
 

Definition at line 156 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

int maxjitterinterps = 10 [static]
 

Definition at line 159 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

int maxnontrunkcall = 1 [static]
 

Definition at line 155 of file chan_iax2.c.

Referenced by find_callno().

int maxtrunkcall = TRUNK_CALL_START [static]
 

Definition at line 154 of file chan_iax2.c.

int min_jitter_buffer = MIN_JITTER_BUFFER [static]
 

Definition at line 432 of file chan_iax2.c.

Referenced by set_config().

int min_reg_expire [static]
 

Definition at line 173 of file chan_iax2.c.

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

struct ast_netsock_list* netsock [static]
 

Definition at line 178 of file chan_iax2.c.

Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().

pthread_t netthreadid = AST_PTHREADT_NULL [static]
 

Definition at line 232 of file chan_iax2.c.

Referenced by __unload_module(), iax2_transmit(), and start_network_thread().

char no_debug_jb_usage[] [static]
 

Initial value:

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

Definition at line 9558 of file chan_iax2.c.

char no_debug_trunk_usage[] [static]
 

Initial value:

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

Definition at line 9550 of file chan_iax2.c.

char no_debug_usage[] [static]
 

Initial value:

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

Definition at line 9542 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]
 

Definition at line 7831 of file chan_iax2.c.

char* pdescrip [static]
 

Initial value:

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

Definition at line 7833 of file chan_iax2.c.

struct ast_peer_list peerl [static]
 

int ping_time = 20 [static]
 

Definition at line 152 of file chan_iax2.c.

Referenced by make_trunk(), and set_config().

struct ast_codec_pref prefs [static]
 

Definition at line 139 of file chan_iax2.c.

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

char prune_realtime_usage[] [static]
 

Initial value:

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

Definition at line 9496 of file chan_iax2.c.

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

Definition at line 7832 of file chan_iax2.c.

char regcontext[AST_MAX_CONTEXT] = "" [static]
 

Definition at line 148 of file chan_iax2.c.

Referenced by register_peer_exten(), reload_config(), set_config(), and sip_show_settings().

struct iax2_registry* registrations [static]
 

Definition at line 412 of file chan_iax2.c.

Referenced by delete_users(), iax2_register(), iax2_show_registry(), and load_module().

int resyncthreshold = 1000 [static]
 

Definition at line 158 of file chan_iax2.c.

Referenced by new_iax(), and set_config().

struct sched_context* sched [static]
 

Definition at line 207 of file chan_iax2.c.

char show_cache_usage[] [static]
 

Initial value:

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

Definition at line 9488 of file chan_iax2.c.

char show_channels_usage[] [static]
 

Initial value:

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

Definition at line 9516 of file chan_iax2.c.

char show_firmware_usage[] [static]
 

Initial value:

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

Definition at line 9530 of file chan_iax2.c.

char show_netstats_usage[] [static]
 

Initial value:

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

Definition at line 9520 of file chan_iax2.c.

char show_peer_usage[] [static]
 

Initial value:

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

Definition at line 9492 of file chan_iax2.c.

char show_peers_usage[] [static]
 

Initial value:

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

Definition at line 9524 of file chan_iax2.c.

char show_prov_usage[] [static]
 

Definition at line 9504 of file chan_iax2.c.

char show_reg_usage[] [static]
 

Initial value:

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

Definition at line 9534 of file chan_iax2.c.

char show_stats_usage[] [static]
 

Initial value:

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

Definition at line 9484 of file chan_iax2.c.

char show_users_usage[] [static]
 

Initial value:

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

Definition at line 9511 of file chan_iax2.c.

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

Definition at line 142 of file chan_iax2.c.

int test_losspct = 0 [static]
 

Definition at line 217 of file chan_iax2.c.

Referenced by iax2_test_losspct(), and socket_read().

int timingfd = -1 [static]
 

Definition at line 176 of file chan_iax2.c.

Referenced by build_peer(), build_user(), load_module(), network_thread(), and set_timing().

int tos = 0 [static]
 

Definition at line 171 of file chan_iax2.c.

struct iax2_trunk_peer * tpeers [static]
 

Referenced by find_tpeer(), and timing_read().

int trunkfreq = 20 [static]
 

Definition at line 162 of file chan_iax2.c.

Referenced by send_trunk(), set_config(), and set_timing().

int usecnt [static]
 

Definition at line 181 of file chan_iax2.c.

struct ast_user_list userl [static]
 

struct ast_firmware_list waresl [static]
 

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


Generated on Sat Nov 25 00:45:53 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6