Sun Aug 6 15:05:53 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

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"

Include dependency graph for chan_iax2.c:

Go to the source code of this file.

Data Structures

struct  ast_peer_list
 The peer list: Peers and Friends ---. More...
struct  ast_user_list
 The user list: Users and friends ---. More...

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 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)
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 []
enum { ... }  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(), and find_callno().

#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 GAMMA   (0.01)
 

Definition at line 137 of file chan_iax2.c.

Referenced by schedule_delivery().

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

Definition at line 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 cache_get_callno_locked(), and 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 find_callno(), and make_trunk().

#define NEW_ALLOW   1
 

Definition at line 949 of file chan_iax2.c.

Referenced by find_callno(), and socket_read().

#define NEW_FORCE   2
 

Definition at line 950 of file chan_iax2.c.

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

#define NEW_PREVENT   0
 

Definition at line 948 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 find_callno(), 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
 

Enumeration values:
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
 

Enumeration values:
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
 

Enumeration values:
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
 

Enumeration values:
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 1415 of file chan_iax2.c.

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

Referenced by get_from_jb(), and schedule_delivery().

01416 {
01417    /* Just deliver the packet by using queueing.  This is called by
01418      the IAX thread with the iaxsl lock held. */
01419    struct iax_frame *fr = data;
01420    fr->retrans = -1;
01421    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01422       iax2_queue_frame(fr->callno, &fr->af);
01423    /* Free our iax frame */
01424    iax2_frame_free(fr);
01425    /* And don't run again */
01426    return 0;
01427 }

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

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

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

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

04665 {
04666    struct ast_frame f;
04667    f.frametype = type;
04668    f.subclass = command;
04669    f.datalen = datalen;
04670    f.samples = 0;
04671    f.mallocd = 0;
04672    f.offset = 0;
04673    f.src = (char *)__FUNCTION__;
04674    f.data = (char *)data;
04675    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04676 }

static int __unload_module void   )  [static]
 

Definition at line 9599 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_destroy(), IAX_MAX_CALLS, iax_provision_unload(), netthreadid, and sched_context_destroy().

Referenced by load_module(), and unload_module().

09600 {
09601    int x;
09602    /* Cancel the network thread, close the net socket */
09603    if (netthreadid != AST_PTHREADT_NULL) {
09604       pthread_cancel(netthreadid);
09605       pthread_join(netthreadid, NULL);
09606    }
09607    ast_netsock_release(netsock);
09608    for (x=0;x<IAX_MAX_CALLS;x++)
09609       if (iaxs[x])
09610          iax2_destroy(x);
09611    ast_manager_unregister( "IAXpeers" );
09612    ast_manager_unregister( "IAXnetstats" );
09613    ast_unregister_application(papp);
09614    ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09615    ast_unregister_switch(&iax2_switch);
09616    ast_channel_unregister(&iax2_tech);
09617    delete_users();
09618    iax_provision_unload();
09619    sched_context_destroy(sched);
09620    return 0;
09621 }

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

Definition at line 4716 of file chan_iax2.c.

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

Referenced by check_access().

04717 {
04718    while(con) {
04719       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04720          return -1;
04721       con = con->next;
04722    }
04723    return 0;
04724 }

static int ast_cli_netstats int  fd,
int  limit_fmt
[static]
 

Definition at line 4483 of file chan_iax2.c.

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

Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().

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

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

Definition at line 3415 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_set_callerid(), 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_dnid, chan_iax2_pvt::cid_name, 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, 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().

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

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 1727 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, 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().

Referenced by network_thread().

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

static int auth_fail int  callno,
int  failcode
[static]
 

Definition at line 5926 of file chan_iax2.c.

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

Referenced by socket_read().

05927 {
05928    /* Schedule sending the authentication failure in one second, to prevent
05929       guessing */
05930    ast_mutex_lock(&iaxsl[callno]);
05931    iaxs[callno]->authfail = failcode;
05932    if (delayreject) {
05933       if (iaxs[callno]->authid > -1)
05934          ast_sched_del(sched, iaxs[callno]->authid);
05935       iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05936    } else
05937       auth_reject((void *)(long)callno);
05938    ast_mutex_unlock(&iaxsl[callno]);
05939    return 0;
05940 }

static int auth_reject void *  nothing  )  [static]
 

Definition at line 5904 of file chan_iax2.c.

References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, IAX_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().

05905 {
05906    /* Called from IAX thread only, without iaxs lock */
05907    int callno = (int)(long)(nothing);
05908    struct iax_ie_data ied;
05909    ast_mutex_lock(&iaxsl[callno]);
05910    if (iaxs[callno]) {
05911       iaxs[callno]->authid = -1;
05912       memset(&ied, 0, sizeof(ied));
05913       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05914          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05915          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05916       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05917          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05918          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05919       }
05920       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05921    }
05922    ast_mutex_unlock(&iaxsl[callno]);
05923    return 0;
05924 }

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

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

05235 {
05236    int res = -1;
05237    int x;
05238    char iabuf[INET_ADDRSTRLEN];
05239    if (!ast_strlen_zero(keyn)) {
05240       if (!(authmethods & IAX_AUTH_RSA)) {
05241          if (ast_strlen_zero(secret)) 
05242             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));
05243       } else if (ast_strlen_zero(challenge)) {
05244          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05245       } else {
05246          char sig[256];
05247          struct ast_key *key;
05248          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05249          if (!key) {
05250             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05251          } else {
05252             if (ast_sign(key, challenge, sig)) {
05253                ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n");
05254                res = -1;
05255             } else {
05256                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05257                res = 0;
05258             }
05259          }
05260       }
05261    } 
05262    /* Fall back */
05263    if (res && !ast_strlen_zero(secret)) {
05264       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05265          struct MD5Context md5;
05266          unsigned char digest[16];
05267          char digres[128];
05268          MD5Init(&md5);
05269          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05270          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05271          MD5Final(digest, &md5);
05272          /* If they support md5, authenticate with it.  */
05273          for (x=0;x<16;x++)
05274             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05275          if (ecx && dcx)
05276             build_enc_keys(digest, ecx, dcx);
05277          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05278          res = 0;
05279       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05280          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05281          res = 0;
05282       } else
05283          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);
05284    }
05285    return res;
05286 }

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

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

Referenced by socket_read().

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

static int authenticate_request struct chan_iax2_pvt p  )  [static]
 

Definition at line 4958 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, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, ast_user_list::lock, iax2_user::maxauthreq, iax2_user::name, iax2_user::next, send_command(), send_command_final(), user, userl, and ast_user_list::users.

Referenced by socket_read().

04959 {
04960    struct iax2_user *user = NULL;
04961    struct iax_ie_data ied;
04962    int res = -1, authreq_restrict = 0;
04963 
04964    memset(&ied, 0, sizeof(ied));
04965 
04966    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
04967    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04968       ast_mutex_lock(&userl.lock);
04969       user = userl.users;
04970       while (user) {
04971          if (!strcmp(user->name, p->username)) {
04972             if (user->curauthreq == user->maxauthreq)
04973                authreq_restrict = 1;
04974             else
04975                user->curauthreq++;
04976             break;
04977          }
04978          user = user->next;
04979       }
04980       ast_mutex_unlock(&userl.lock);
04981    }
04982 
04983    /* If the AUTHREQ limit test failed, send back an error */
04984    if (authreq_restrict) {
04985       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
04986       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
04987       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
04988       return 0;
04989    }
04990 
04991    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
04992    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
04993       snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
04994       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
04995    }
04996    if (p->encmethods)
04997       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
04998 
04999    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05000 
05001    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05002 
05003    if (p->encmethods)
05004       ast_set_flag(p, IAX_ENCRYPTED);
05005 
05006    return res;
05007 }

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

Definition at line 5009 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, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, key(), ast_user_list::lock, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, iax2_user::next, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, userl, chan_iax2_pvt::username, and ast_user_list::users.

Referenced by socket_read().

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

static int auto_congest void *  nothing  )  [static]
 

Definition at line 2852 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, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.

Referenced by iax2_call(), and sip_call().

02853 {
02854    int callno = PTR_TO_CALLNO(nothing);
02855    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02856    ast_mutex_lock(&iaxsl[callno]);
02857    if (iaxs[callno]) {
02858       iaxs[callno]->initid = -1;
02859       iax2_queue_frame(callno, &f);
02860       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02861    }
02862    ast_mutex_unlock(&iaxsl[callno]);
02863    return 0;
02864 }

static int auto_hangup void *  nothing  )  [static]
 

Definition at line 5942 of file chan_iax2.c.

References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, IAX_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().

05943 {
05944    /* Called from IAX thread only, without iaxs lock */
05945    int callno = (int)(long)(nothing);
05946    struct iax_ie_data ied;
05947    ast_mutex_lock(&iaxsl[callno]);
05948    if (iaxs[callno]) {
05949       iaxs[callno]->autoid = -1;
05950       memset(&ied, 0, sizeof(ied));
05951       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05952       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05953       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05954    }
05955    ast_mutex_unlock(&iaxsl[callno]);
05956    return 0;
05957 }

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

Definition at line 8088 of file chan_iax2.c.

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

Referenced by build_user().

08089 {
08090    struct iax2_context *con = malloc(sizeof(struct iax2_context));
08091    if (con) {
08092       ast_copy_string(con->context, context, sizeof(con->context));
08093       con->next = NULL;
08094    }
08095    return con;
08096 }

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

Definition at line 3798 of file chan_iax2.c.

References aes_decrypt_key128(), and aes_encrypt_key128().

Referenced by authenticate(), and decrypt_frame().

03799 {
03800    aes_encrypt_key128(digest, ecx);
03801    aes_decrypt_key128(digest, dcx);
03802 }

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

Definition at line 8199 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(), 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, timingfd, and ast_variable::value.

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

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

Definition at line 8389 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(), 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, iax2_user::name, ast_variable::next, iax2_user::next, timingfd, user, userl, ast_user_list::users, and ast_variable::value.

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

static int cache_get_callno_locked const char *  data  )  [static]
 

Definition at line 8974 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, chan_iax2_pvt::capability, create_addr(), find_callno(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_MAX_CALLS, IAX_PROTO_VERSION, iaxsl, LOG_WARNING, NEW_FORCE, chan_iax2_pvt::outkey, parse_dial_string(), chan_iax2_pvt::secret, secret, and send_command().

Referenced by find_cache().

08975 {
08976    struct sockaddr_in sin;
08977    int x;
08978    int callno;
08979    struct iax_ie_data ied;
08980    struct create_addr_info cai;
08981    struct parsed_dial_string pds;
08982    char *tmpstr;
08983 
08984    for (x=0; x<IAX_MAX_CALLS; x++) {
08985       /* Look for an *exact match* call.  Once a call is negotiated, it can only
08986          look up entries for a single context */
08987       if (!ast_mutex_trylock(&iaxsl[x])) {
08988          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
08989             return x;
08990          ast_mutex_unlock(&iaxsl[x]);
08991       }
08992    }
08993 
08994    /* No match found, we need to create a new one */
08995 
08996    memset(&cai, 0, sizeof(cai));
08997    memset(&ied, 0, sizeof(ied));
08998    memset(&pds, 0, sizeof(pds));
08999 
09000    tmpstr = ast_strdupa(data);
09001    parse_dial_string(tmpstr, &pds);
09002 
09003    /* Populate our address from the given */
09004    if (create_addr(pds.peer, &sin, &cai))
09005       return -1;
09006 
09007    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09008       pds.peer, pds.username, pds.password, pds.context);
09009 
09010    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
09011    if (callno < 1) {
09012       ast_log(LOG_WARNING, "Unable to create call\n");
09013       return -1;
09014    }
09015 
09016    ast_mutex_lock(&iaxsl[callno]);
09017    ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot));
09018    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09019 
09020    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09021    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09022    /* the string format is slightly different from a standard dial string,
09023       because the context appears in the 'exten' position
09024    */
09025    if (pds.exten)
09026       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09027    if (pds.username)
09028       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09029    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09030    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09031    /* Keep password handy */
09032    if (pds.password)
09033       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
09034    if (pds.key)
09035       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
09036    /* Start the call going */
09037    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09038 
09039    return callno;
09040 }

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

Definition at line 3661 of file chan_iax2.c.

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

03662 {
03663    /* Returns where in "receive time" we are.  That is, how many ms
03664       since we received (or would have received) the frame with timestamp 0 */
03665    int ms;
03666 #ifdef IAXTESTS
03667    int jit;
03668 #endif /* IAXTESTS */
03669    /* Setup rxcore if necessary */
03670    if (ast_tvzero(p->rxcore)) {
03671       p->rxcore = ast_tvnow();
03672       if (option_debug && iaxdebug)
03673          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03674                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03675       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03676 #if 1
03677       if (option_debug && iaxdebug)
03678          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03679                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03680 #endif
03681    }
03682 
03683    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03684 #ifdef IAXTESTS
03685    if (test_jit) {
03686       if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) {
03687          jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0));
03688          if ((int)(2.0 * rand() / (RAND_MAX + 1.0)))
03689             jit = -jit;
03690          ms += jit;
03691       }
03692    }
03693    if (test_late) {
03694       ms += test_late;
03695       test_late = 0;
03696    }
03697 #endif /* IAXTESTS */
03698    return ms;
03699 }

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

Definition at line 3517 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, and ast_frame::samples.

Referenced by iax2_send(), and socket_read().

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

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

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

03474 {
03475    unsigned long int mssincetx; /* unsigned to handle overflows */
03476    long int ms, pred;
03477 
03478    tpeer->trunkact = *tv;
03479    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03480    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03481       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03482       tpeer->txtrunktime = *tv;
03483       tpeer->lastsent = 999999;
03484    }
03485    /* Update last transmit time now */
03486    tpeer->lasttxtime = *tv;
03487    
03488    /* Calculate ms offset */
03489    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03490    /* Predict from last value */
03491    pred = tpeer->lastsent + sampms;
03492    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03493       ms = pred;
03494    
03495    /* We never send the same timestamp twice, so fudge a little if we must */
03496    if (ms == tpeer->lastsent)
03497       ms = tpeer->lastsent + 1;
03498    tpeer->lastsent = ms;
03499    return ms;
03500 }

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

Definition at line 4727 of file chan_iax2.c.

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

Referenced by socket_read().

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

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

Definition at line 6279 of file chan_iax2.c.

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

Referenced by socket_read().

06280 {
06281    unsigned int ourver;
06282    char rsi[80];
06283    snprintf(rsi, sizeof(rsi), "si-%s", si);
06284    if (iax_provision_version(&ourver, rsi, 1))
06285       return 0;
06286    if (option_debug)
06287       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06288    if (ourver != ver) 
06289       iax2_provision(sin, sockfd, NULL, rsi, 1);
06290    return 0;
06291 }

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

Definition at line 8117 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

Referenced by peer_set_srcaddr().

08118 {
08119    int sd;
08120    int res;
08121    
08122    sd = socket(AF_INET, SOCK_DGRAM, 0);
08123    if (sd < 0) {
08124       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08125       return -1;
08126    }
08127 
08128    res = bind(sd, sa, salen);
08129    if (res < 0) {
08130       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08131       close(sd);
08132       return 1;
08133    }
08134 
08135    close(sd);
08136    return 0;
08137 }

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

Definition at line 5387 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, iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iaxdefaultdpcache, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters.

Referenced by socket_read().

05388 {
05389    char exten[256] = "";
05390    int status = CACHE_FLAG_UNKNOWN;
05391    int expiry = iaxdefaultdpcache;
05392    int x;
05393    int matchmore = 0;
05394    struct iax2_dpcache *dp, *prev;
05395    
05396    if (ies->called_number)
05397       ast_copy_string(exten, ies->called_number, sizeof(exten));
05398 
05399    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05400       status = CACHE_FLAG_EXISTS;
05401    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05402       status = CACHE_FLAG_CANEXIST;
05403    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05404       status = CACHE_FLAG_NONEXISTENT;
05405 
05406    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05407       /* Don't really do anything with this */
05408    }
05409    if (ies->refresh)
05410       expiry = ies->refresh;
05411    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05412       matchmore = CACHE_FLAG_MATCHMORE;
05413    ast_mutex_lock(&dpcache_lock);
05414    prev = NULL;
05415    dp = pvt->dpentries;
05416    while(dp) {
05417       if (!strcmp(dp->exten, exten)) {
05418          /* Let them go */
05419          if (prev)
05420             prev->peer = dp->peer;
05421          else
05422             pvt->dpentries = dp->peer;
05423          dp->peer = NULL;
05424          dp->callno = 0;
05425          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05426          if (dp->flags & CACHE_FLAG_PENDING) {
05427             dp->flags &= ~CACHE_FLAG_PENDING;
05428             dp->flags |= status;
05429             dp->flags |= matchmore;
05430          }
05431          /* Wake up waiters */
05432          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05433             if (dp->waiters[x] > -1)
05434                write(dp->waiters[x], "asdf", 4);
05435       }
05436       prev = dp;
05437       dp = dp->peer;
05438    }
05439    ast_mutex_unlock(&dpcache_lock);
05440    return 0;
05441 }

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

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

02008 {
02009    int which = 0;
02010    struct iax2_peer *p;
02011    char *res = NULL;
02012 
02013    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02014    if(pos == 3) {
02015       ast_mutex_lock(&peerl.lock);
02016       for(p = peerl.peers ; p ; p = p->next) {
02017          if(!strncasecmp(p->name, word, strlen(word))) {
02018             if(++which > state) {
02019                res = strdup(p->name);
02020                break;
02021             }
02022          }
02023       }
02024       ast_mutex_unlock(&peerl.lock);
02025    }
02026 
02027    return res;
02028 }

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

Definition at line 5443 of file chan_iax2.c.

References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, ast_iax2_queue::head, iax2_frame_free(), iaxq, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, 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().

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

static unsigned char compress_subclass int  subclass  )  [static]
 

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

00818 {
00819    int x;
00820    int power=-1;
00821    /* If it's 128 or smaller, just return it */
00822    if (subclass < IAX_FLAG_SC_LOG)
00823       return subclass;
00824    /* Otherwise find its power */
00825    for (x = 0; x < IAX_MAX_SHIFT; x++) {
00826       if (subclass & (1 << x)) {
00827          if (power > -1) {
00828             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
00829             return 0;
00830          } else
00831             power = x;
00832       }
00833    }
00834    return power | IAX_FLAG_SC_LOG;
00835 }

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

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

06294 {
06295 #ifdef NEWJB
06296    jb_info stats;
06297    jb_getinfo(pvt->jb, &stats);
06298    
06299    memset(iep, 0, sizeof(*iep));
06300 
06301    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06302    if(stats.frames_in == 0) stats.frames_in = 1;
06303    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06304    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06305    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06306    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06307    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06308 #else
06309    memset(iep, 0, sizeof(*iep));
06310    iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter);
06311    iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received);
06312    if(!ast_test_flag(pvt, IAX_USEJITTERBUF)) 
06313       iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0);
06314    else
06315       iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min);
06316    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped);
06317    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */
06318    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */
06319 #endif
06320 }

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

Definition at line 2764 of file chan_iax2.c.

References iax2_peer::addr, ast_clear_flag, ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, 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, 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.

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

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

Definition at line 3852 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(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame().

03853 {
03854    int padding;
03855    unsigned char *workspace;
03856    workspace = alloca(*datalen);
03857    if (!workspace)
03858       return -1;
03859    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03860       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03861       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03862          return -1;
03863       /* Decrypt */
03864       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03865 
03866       padding = 16 + (workspace[15] & 0xf);
03867       if (option_debug && iaxdebug)
03868          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03869       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03870          return -1;
03871 
03872       *datalen -= padding;
03873       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03874       f->frametype = fh->type;
03875       if (f->frametype == AST_FRAME_VIDEO) {
03876          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03877       } else {
03878          f->subclass = uncompress_subclass(fh->csub);
03879       }
03880    } else {
03881       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03882       if (option_debug && iaxdebug)
03883          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03884       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03885          return -1;
03886       /* Decrypt */
03887       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03888       padding = 16 + (workspace[15] & 0x0f);
03889       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03890          return -1;
03891       *datalen -= padding;
03892       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03893    }
03894    return 0;
03895 }

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

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

03939 {
03940    int res=-1;
03941    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03942       /* Search for possible keys, given secrets */
03943       struct MD5Context md5;
03944       unsigned char digest[16];
03945       char *tmppw, *stringp;
03946       
03947       tmppw = ast_strdupa(iaxs[callno]->secret);
03948       stringp = tmppw;
03949       while((tmppw = strsep(&stringp, ";"))) {
03950          MD5Init(&md5);
03951          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03952          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03953          MD5Final(digest, &md5);
03954          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03955          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03956          if (!res) {
03957             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03958             break;
03959          }
03960       }
03961    } else 
03962       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03963    return res;
03964 }

static void delete_users void   )  [static]
 

Definition at line 8548 of file chan_iax2.c.

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

08549 {
08550    struct iax2_user *user;
08551    struct iax2_peer *peer;
08552    struct iax2_registry *reg, *regl;
08553 
08554    ast_mutex_lock(&userl.lock);
08555    for (user=userl.users;user;) {
08556       ast_set_flag(user, IAX_DELME);
08557       user = user->next;
08558    }
08559    ast_mutex_unlock(&userl.lock);
08560    for (reg = registrations;reg;) {
08561       regl = reg;
08562       reg = reg->next;
08563       if (regl->expire > -1) {
08564          ast_sched_del(sched, regl->expire);
08565       }
08566       if (regl->callno) {
08567          /* XXX Is this a potential lock?  I don't think so, but you never know */
08568          ast_mutex_lock(&iaxsl[regl->callno]);
08569          if (iaxs[regl->callno]) {
08570             iaxs[regl->callno]->reg = NULL;
08571             iax2_destroy_nolock(regl->callno);
08572          }
08573          ast_mutex_unlock(&iaxsl[regl->callno]);
08574       }
08575       free(regl);
08576    }
08577    registrations = NULL;
08578    ast_mutex_lock(&peerl.lock);
08579    for (peer=peerl.peers;peer;) {
08580       /* Assume all will be deleted, and we'll find out for sure later */
08581       ast_set_flag(peer, IAX_DELME);
08582       peer = peer->next;
08583    }
08584    ast_mutex_unlock(&peerl.lock);
08585 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 9727 of file chan_iax2.c.

References desc.

09728 {
09729    return (char *) desc;
09730 }

static void destroy_firmware struct iax_firmware cur  )  [static]
 

Definition at line 1149 of file chan_iax2.c.

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

Referenced by reload_firmware().

01150 {
01151    /* Close firmware */
01152    if (cur->fwh) {
01153       munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01154    }
01155    close(cur->fd);
01156    free(cur);
01157 }

static void destroy_peer struct iax2_peer peer  )  [static]
 

Definition at line 8617 of file chan_iax2.c.

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

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

08618 {
08619    int x;
08620    ast_free_ha(peer->ha);
08621    for (x=0;x<IAX_MAX_CALLS;x++) {
08622       ast_mutex_lock(&iaxsl[x]);
08623       if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
08624          iax2_destroy(x);
08625       }
08626       ast_mutex_unlock(&iaxsl[x]);
08627    }
08628    /* Delete it, it needs to disappear */
08629    if (peer->expire > -1)
08630       ast_sched_del(sched, peer->expire);
08631    if (peer->pokeexpire > -1)
08632       ast_sched_del(sched, peer->pokeexpire);
08633    if (peer->callno > 0)
08634       iax2_destroy(peer->callno);
08635    register_peer_exten(peer, 0);
08636    if (peer->dnsmgr)
08637       ast_dnsmgr_release(peer->dnsmgr);
08638    free(peer);
08639 }

static void destroy_user struct iax2_user user  )  [static]
 

Definition at line 8587 of file chan_iax2.c.

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

Referenced by check_access(), and prune_users().

08588 {
08589    ast_free_ha(user->ha);
08590    free_context(user->contexts);
08591    if(user->vars) {
08592       ast_variables_destroy(user->vars);
08593       user->vars = NULL;
08594    }
08595    free(user);
08596 }

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

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

06137 {
06138    unsigned short dpstatus = 0;
06139    struct iax_ie_data ied1;
06140    int mm;
06141 
06142    memset(&ied1, 0, sizeof(ied1));
06143    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06144    /* Must be started */
06145    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06146       dpstatus = IAX_DPSTATUS_EXISTS;
06147    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06148       dpstatus = IAX_DPSTATUS_CANEXIST;
06149    } else {
06150       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06151    }
06152    if (ast_ignore_pattern(context, callednum))
06153       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06154    if (mm)
06155       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06156    if (!skiplock)
06157       ast_mutex_lock(&iaxsl[callno]);
06158    if (iaxs[callno]) {
06159       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06160       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06161       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06162       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06163    }
06164    if (!skiplock)
06165       ast_mutex_unlock(&iaxsl[callno]);
06166 }

static void* dp_lookup_thread void *  data  )  [static]
 

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

06169 {
06170    /* Look up for dpreq */
06171    struct dpreq_data *dpr = data;
06172    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06173    if (dpr->callerid)
06174       free(dpr->callerid);
06175    free(dpr);
06176    return NULL;
06177 }

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

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

Referenced by iax2_send().

03898 {
03899    int padding;
03900    unsigned char *workspace;
03901    workspace = alloca(*datalen + 32);
03902    if (!workspace)
03903       return -1;
03904    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03905       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03906       if (option_debug && iaxdebug)
03907          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03908       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03909       padding = 16 + (padding & 0xf);
03910       memcpy(workspace, poo, padding);
03911       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03912       workspace[15] &= 0xf0;
03913       workspace[15] |= (padding & 0xf);
03914       if (option_debug && iaxdebug)
03915          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]);
03916       *datalen += padding;
03917       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03918       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03919          memcpy(poo, workspace + *datalen - 32, 32);
03920    } else {
03921       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03922       if (option_debug && iaxdebug)
03923          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03924       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03925       padding = 16 + (padding & 0xf);
03926       memcpy(workspace, poo, padding);
03927       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03928       workspace[15] &= 0xf0;
03929       workspace[15] |= (padding & 0x0f);
03930       *datalen += padding;
03931       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03932       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03933          memcpy(poo, workspace + *datalen - 32, 32);
03934    }
03935    return 0;
03936 }

static int expire_registry void *  data  )  [static]
 

Definition at line 5638 of file chan_iax2.c.

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

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

05639 {
05640    struct iax2_peer *p = data;
05641 
05642    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05643    /* Reset the address */
05644    memset(&p->addr, 0, sizeof(p->addr));
05645    /* Reset expire notice */
05646    p->expire = -1;
05647    /* Reset expiry value */
05648    p->expiry = min_reg_expire;
05649    if (!ast_test_flag(p, IAX_TEMPONLY))
05650       ast_db_del("IAX/Registry", p->name);
05651    register_peer_exten(p, 0);
05652    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05653    if (iax2_regfunk)
05654       iax2_regfunk(p->name, 0);
05655 
05656    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05657       ast_set_flag(p, IAX_DELME);
05658       prune_peers();
05659    }
05660 
05661    return 0;
05662 }

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

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

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

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

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

Definition at line 1047 of file chan_iax2.c.

References accountcode, chan_iax2_pvt::addr, amaflags, chan_iax2_pvt::amaflags, ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, host, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_USEJITTERBUF, iaxdebug, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, match(), maxnontrunkcall, maxtrunkcall, min_reg_expire, MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, ping_time, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, TRUNK_CALL_START, and update_max_nontrunk().

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

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

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

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

00852 {
00853    struct iax2_peer *peer;
00854    ast_mutex_lock(&peerl.lock);
00855    for(peer = peerl.peers; peer; peer = peer->next) {
00856       if (!strcasecmp(peer->name, name)) {
00857          break;
00858       }
00859    }
00860    ast_mutex_unlock(&peerl.lock);
00861    if(!peer && realtime)
00862       peer = realtime_peer(name, NULL);
00863    return peer;
00864 }

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

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

03702 {
03703    struct iax2_trunk_peer *tpeer;
03704    char iabuf[INET_ADDRSTRLEN];
03705    /* Finds and locks trunk peer */
03706    ast_mutex_lock(&tpeerlock);
03707    tpeer = tpeers;
03708    while(tpeer) {
03709       /* We don't lock here because tpeer->addr *never* changes */
03710       if (!inaddrcmp(&tpeer->addr, sin)) {
03711          ast_mutex_lock(&tpeer->lock);
03712          break;
03713       }
03714       tpeer = tpeer->next;
03715    }
03716    if (!tpeer) {
03717       tpeer = malloc(sizeof(struct iax2_trunk_peer));
03718       if (tpeer) {
03719          memset(tpeer, 0, sizeof(struct iax2_trunk_peer));
03720          ast_mutex_init(&tpeer->lock);
03721          tpeer->lastsent = 9999;
03722          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03723          tpeer->trunkact = ast_tvnow();
03724          ast_mutex_lock(&tpeer->lock);
03725          tpeer->next = tpeers;
03726          tpeer->sockfd = fd;
03727          tpeers = tpeer;
03728 #ifdef SO_NO_CHECK
03729          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03730 #endif
03731          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));
03732       }
03733    }
03734    ast_mutex_unlock(&tpeerlock);
03735    return tpeer;
03736 }

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

Definition at line 3502 of file chan_iax2.c.

References chan_iax2_pvt::rxcore.

Referenced by socket_read().

03503 {
03504    long ms; /* NOT unsigned */
03505    if (ast_tvzero(iaxs[callno]->rxcore)) {
03506       /* Initialize rxcore time if appropriate */
03507       gettimeofday(&iaxs[callno]->rxcore, NULL);
03508       /* Round to nearest 20ms so traces look pretty */
03509       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03510    }
03511    /* Calculate difference between trunk and channel */
03512    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03513    /* Return as the sum of trunk time and the difference between trunk and real time */
03514    return ms + ts;
03515 }

static void free_context struct iax2_context con  )  [static]
 

Definition at line 7928 of file chan_iax2.c.

References free, and iax2_context::next.

Referenced by build_user(), and destroy_user().

07929 {
07930    struct iax2_context *conl;
07931    while(con) {
07932       conl = con;
07933       con = con->next;
07934       free(conl);
07935    }
07936 }

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

Definition at line 9314 of file chan_iax2.c.

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

09315 {
09316    char *ret = NULL;
09317    struct iax2_peer *peer;
09318    char *peername, *colname;
09319    char iabuf[INET_ADDRSTRLEN];
09320 
09321    if (!(peername = ast_strdupa(data))) {
09322       ast_log(LOG_ERROR, "Memory Error!\n");
09323       return ret;
09324    }
09325 
09326    /* if our channel, return the IP address of the endpoint of current channel */
09327    if (!strcmp(peername,"CURRENTCHANNEL")) {
09328            unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
09329       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
09330       return buf;
09331    }
09332 
09333    if ((colname = strchr(peername, ':'))) {
09334       *colname = '\0';
09335       colname++;
09336    } else {
09337       colname = "ip";
09338    }
09339    if (!(peer = find_peer(peername, 1)))
09340       return ret;
09341 
09342    if (!strcasecmp(colname, "ip")) {
09343       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09344    } else  if (!strcasecmp(colname, "status")) {
09345       peer_status(peer, buf, len); 
09346    } else  if (!strcasecmp(colname, "mailbox")) {
09347       ast_copy_string(buf, peer->mailbox, len);
09348    } else  if (!strcasecmp(colname, "context")) {
09349       ast_copy_string(buf, peer->context, len);
09350    } else  if (!strcasecmp(colname, "expire")) {
09351       snprintf(buf, len, "%d", peer->expire);
09352    } else  if (!strcasecmp(colname, "dynamic")) {
09353       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09354    } else  if (!strcasecmp(colname, "callerid_name")) {
09355       ast_copy_string(buf, peer->cid_name, len);
09356    } else  if (!strcasecmp(colname, "callerid_num")) {
09357       ast_copy_string(buf, peer->cid_num, len);
09358    } else  if (!strcasecmp(colname, "codecs")) {
09359       ast_getformatname_multiple(buf, len -1, peer->capability);
09360    } else  if (!strncasecmp(colname, "codec[", 6)) {
09361       char *codecnum, *ptr;
09362       int index = 0, codec = 0;
09363       
09364       codecnum = strchr(colname, '[');
09365       *codecnum = '\0';
09366       codecnum++;
09367       if ((ptr = strchr(codecnum, ']'))) {
09368          *ptr = '\0';
09369       }
09370       index = atoi(codecnum);
09371       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09372          ast_copy_string(buf, ast_getformatname(codec), len);
09373       }
09374    }
09375    ret = buf;
09376 
09377    return ret;
09378 }

static int get_auth_methods char *  value  )  [static]
 

Definition at line 8098 of file chan_iax2.c.

References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.

Referenced by build_peer(), and build_user().

08099 {
08100    int methods = 0;
08101    if (strstr(value, "rsa"))
08102       methods |= IAX_AUTH_RSA;
08103    if (strstr(value, "md5"))
08104       methods |= IAX_AUTH_MD5;
08105    if (strstr(value, "plaintext"))
08106       methods |= IAX_AUTH_PLAINTEXT;
08107    return methods;
08108 }

static int get_encrypt_methods const char *  s  )  [static]
 

Definition at line 791 of file chan_iax2.c.

References ast_true(), and IAX_ENCRYPT_AES128.

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

00792 {
00793    int e;
00794    if (!strcasecmp(s, "aes128"))
00795       e = IAX_ENCRYPT_AES128;
00796    else if (ast_true(s))
00797       e = IAX_ENCRYPT_AES128;
00798    else
00799       e = 0;
00800    return e;
00801 }

static int get_from_jb void *  p  )  [static]
 

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

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

static int handle_error void   )  [static]
 

Definition at line 1443 of file chan_iax2.c.

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

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

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

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

Acknowledgment received for OUR registration.

Definition at line 5504 of file chan_iax2.c.

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

Referenced by socket_read().

05505 {
05506    struct iax2_registry *reg;
05507    /* Start pessimistic */
05508    char peer[256] = "";
05509    char msgstatus[40];
05510    int refresh = 0;
05511    char ourip[256] = "<Unspecified>";
05512    struct sockaddr_in oldus;
05513    struct sockaddr_in us;
05514    char iabuf[INET_ADDRSTRLEN];
05515    int oldmsgs;
05516 
05517    memset(&us, 0, sizeof(us));
05518    if (ies->apparent_addr)
05519       bcopy(ies->apparent_addr, &us, sizeof(us));
05520    if (ies->username)
05521       ast_copy_string(peer, ies->username, sizeof(peer));
05522    if (ies->refresh)
05523       refresh = ies->refresh;
05524    if (ies->calling_number) {
05525       /* We don't do anything with it really, but maybe we should */
05526    }
05527    reg = iaxs[callno]->reg;
05528    if (!reg) {
05529       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05530       return -1;
05531    }
05532    memcpy(&oldus, &reg->us, sizeof(oldus));
05533    oldmsgs = reg->messages;
05534    if (inaddrcmp(&reg->addr, sin)) {
05535       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05536       return -1;
05537    }
05538    memcpy(&reg->us, &us, sizeof(reg->us));
05539    reg->messages = ies->msgcount;
05540    /* always refresh the registration at the interval requested by the server
05541       we are registering to
05542    */
05543    reg->refresh = refresh;
05544    if (reg->expire > -1)
05545       ast_sched_del(sched, reg->expire);
05546    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05547    if ((inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) {
05548       if (reg->messages > 65534)
05549          snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
05550       else if (reg->messages > 1)
05551          snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
05552       else if (reg->messages > 0)
05553          snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
05554       else
05555          snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05556       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
05557       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);
05558       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));
05559    }
05560    reg->regstate = REG_STATE_REGISTERED;
05561    return 0;
05562 }

static int iax2_answer struct ast_channel c  )  [static]
 

Definition at line 3357 of file chan_iax2.c.

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

03358 {
03359    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03360    if (option_debug)
03361       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03362    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03363 }

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

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

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

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

Definition at line 2953 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, chan_iax2_pvt::context, context, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, 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, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, n, ast_channel::name, ast_channel::nativeformats, chan_iax2_pvt::outkey, create_addr_info::outkey, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, chan_iax2_pvt::secret, secret, send_command(), ast_channel::tech_pvt, chan_iax2_pvt::username, and username.

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

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

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

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

static unsigned int iax2_datetime char *  tz  )  [static]
 

Definition at line 2866 of file chan_iax2.c.

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

Referenced by iax2_call(), and update_registry().

02867 {
02868    time_t t;
02869    struct tm tm;
02870    unsigned int tmp;
02871    time(&t);
02872    localtime_r(&t, &tm);
02873    if (!ast_strlen_zero(tz))
02874       ast_localtime(&t, &tm, tz);
02875    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02876    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02877    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02878    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02879    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02880    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02881    return tmp;
02882 }

static void iax2_destroy int  callno  )  [static]
 

Definition at line 1601 of file chan_iax2.c.

References 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(), iax_frame::callno, iax2_user::curauthreq, jb_frame::data, free, ast_iax2_queue::head, iax2_frame_free(), IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxq, iaxsl, jb_destroy(), jb_getall(), JB_OK, lastused, ast_user_list::lock, LOG_NOTICE, iax2_user::name, iax_frame::next, iax2_user::next, chan_iax2_pvt::owner, iax_frame::retries, update_max_trunk(), user, userl, and ast_user_list::users.

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

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

static void iax2_destroy_nolock int  callno  )  [static]
 

Definition at line 1707 of file chan_iax2.c.

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

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

01708 {  
01709    /* Actually it's easier to unlock, kill it, and relock */
01710    ast_mutex_unlock(&iaxsl[callno]);
01711    iax2_destroy(callno);
01712    ast_mutex_lock(&iaxsl[callno]);
01713 }

static int iax2_devicestate void *  data  )  [static]
 

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

09404 {
09405    struct parsed_dial_string pds;
09406    char *tmp = ast_strdupa(data);
09407    struct iax2_peer *p;
09408    int res = AST_DEVICE_INVALID;
09409 
09410    memset(&pds, 0, sizeof(pds));
09411    parse_dial_string(tmp, &pds);
09412    if (!pds.peer || ast_strlen_zero(pds.peer))
09413       return res;
09414    
09415    if (option_debug > 2)
09416       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
09417 
09418    /* SLD: FIXME: second call to find_peer during registration */
09419    if (!(p = find_peer(pds.peer, 1)))
09420       return res;
09421 
09422    res = AST_DEVICE_UNAVAILABLE;
09423    if (option_debug > 2) 
09424       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09425          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09426    
09427    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09428        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09429       /* Peer is registered, or have default IP address
09430          and a valid registration */
09431       if (p->historicms == 0 || p->historicms <= p->maxms)
09432          /* let the core figure out whether it is in use or not */
09433          res = AST_DEVICE_UNKNOWN;  
09434    }
09435 
09436    if (ast_test_flag(p, IAX_TEMPONLY))
09437       destroy_peer(p);
09438 
09439    return res;
09440 }

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

Definition at line 2555 of file chan_iax2.c.

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

02556 {
02557    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
02558 }

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

Definition at line 4575 of file chan_iax2.c.

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

04576 {
04577    if (argc != 2)
04578       return RESULT_SHOWUSAGE;
04579    iaxdebug = 1;
04580    ast_cli(fd, "IAX2 Debugging Enabled\n");
04581    return RESULT_SUCCESS;
04582 }

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

Definition at line 4593 of file chan_iax2.c.

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

04594 {
04595    if (argc != 3)
04596       return RESULT_SHOWUSAGE;
04597 #ifdef NEWJB
04598    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04599 #endif
04600    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04601    return RESULT_SUCCESS;
04602 }

static int iax2_do_register struct iax2_registry reg  )  [static]
 

Definition at line 7719 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, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, iax2_registry::regstate, send_command(), and iax2_registry::username.

Referenced by iax2_do_register_s(), and load_module().

07720 {
07721    struct iax_ie_data ied;
07722    if (option_debug && iaxdebug)
07723       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07724    if (!reg->callno) {
07725       if (option_debug)
07726          ast_log(LOG_DEBUG, "Allocate call number\n");
07727       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
07728       if (reg->callno < 1) {
07729          ast_log(LOG_WARNING, "Unable to create call for registration\n");
07730          return -1;
07731       } else if (option_debug)
07732          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07733       iaxs[reg->callno]->reg = reg;
07734    }
07735    /* Schedule the next registration attempt */
07736    if (reg->expire > -1)
07737       ast_sched_del(sched, reg->expire);
07738    /* Setup the next registration a little early */
07739    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07740    /* Send the request */
07741    memset(&ied, 0, sizeof(ied));
07742    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07743    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07744    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07745    reg->regstate = REG_STATE_REGSENT;
07746    return 0;
07747 }

static int iax2_do_register_s void *  data  )  [static]
 

Definition at line 5350 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_ack_registry(), and iax2_do_register().

05351 {
05352    struct iax2_registry *reg = data;
05353    reg->expire = -1;
05354    iax2_do_register(reg);
05355    return 0;
05356 }

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

Definition at line 4584 of file chan_iax2.c.

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

04585 {
04586    if (argc != 3)
04587       return RESULT_SHOWUSAGE;
04588    iaxtrunkdebug = 1;
04589    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04590    return RESULT_SUCCESS;
04591 }

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

Definition at line 5959 of file chan_iax2.c.

References AST_FRAME_IAX, ast_sched_add(), ast_sched_del(), auto_hangup(), chan_iax2_pvt::autoid, 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().

05960 {
05961    struct iax_ie_data ied;
05962    /* Auto-hangup with 30 seconds of inactivity */
05963    if (iaxs[callno]->autoid > -1)
05964       ast_sched_del(sched, iaxs[callno]->autoid);
05965    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05966    memset(&ied, 0, sizeof(ied));
05967    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05968    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05969    dp->flags |= CACHE_FLAG_TRANSMITTED;
05970 }

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

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

09262 {
09263    char odata[256];
09264    char req[256];
09265    char *ncontext;
09266    char *dialstatus;
09267    struct iax2_dpcache *dp;
09268    struct ast_app *dial;
09269 #if 0
09270    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);
09271 #endif
09272    if (priority == 2) {
09273       /* Indicate status, can be overridden in dialplan */
09274       dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09275       if (dialstatus) {
09276          dial = pbx_findapp(dialstatus);
09277          if (dial) 
09278             pbx_exec(chan, dial, "", newstack);
09279       }
09280       return -1;
09281    } else if (priority != 1)
09282       return -1;
09283    ast_mutex_lock(&dpcache_lock);
09284    dp = find_cache(chan, data, context, exten, priority);
09285    if (dp) {
09286       if (dp->flags & CACHE_FLAG_EXISTS) {
09287          ast_copy_string(odata, data, sizeof(odata));
09288          ncontext = strchr(odata, '/');
09289          if (ncontext) {
09290             *ncontext = '\0';
09291             ncontext++;
09292             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09293          } else {
09294             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09295          }
09296          if (option_verbose > 2)
09297             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09298       } else {
09299          ast_mutex_unlock(&dpcache_lock);
09300          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09301          return -1;
09302       }
09303    }
09304    ast_mutex_unlock(&dpcache_lock);
09305    dial = pbx_findapp("Dial");
09306    if (dial) {
09307       return pbx_exec(chan, dial, req, newstack);
09308    } else {
09309       ast_log(LOG_WARNING, "No dial application registered\n");
09310    }
09311    return -1;
09312 }

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

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

09193 {
09194    struct iax2_dpcache *dp;
09195    int res = 0;
09196 #if 0
09197    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09198 #endif
09199    if ((priority != 1) && (priority != 2))
09200       return 0;
09201    ast_mutex_lock(&dpcache_lock);
09202    dp = find_cache(chan, data, context, exten, priority);
09203    if (dp) {
09204       if (dp->flags & CACHE_FLAG_EXISTS)
09205          res= 1;
09206    }
09207    ast_mutex_unlock(&dpcache_lock);
09208    if (!dp) {
09209       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09210    }
09211    return res;
09212 }

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

Definition at line 2577 of file chan_iax2.c.

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

02578 {
02579    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02580    ast_mutex_lock(&iaxsl[callno]);
02581    if (iaxs[callno])
02582       iaxs[callno]->owner = newchan;
02583    else
02584       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02585    ast_mutex_unlock(&iaxsl[callno]);
02586    return 0;
02587 }

static void iax2_frame_free struct iax_frame fr  )  [static]
 

Definition at line 1121 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(), iax2_destroy(), and schedule_delivery().

01122 {
01123    if (fr->retrans > -1)
01124       ast_sched_del(sched, fr->retrans);
01125    iax_frame_free(fr);
01126 }

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

Definition at line 866 of file chan_iax2.c.

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

Referenced by find_callno().

00867 {
00868    struct iax2_peer *peer;
00869    int res = 0;
00870 
00871    if (lockpeer)
00872       ast_mutex_lock(&peerl.lock);
00873    peer = peerl.peers;
00874    while (peer) {
00875       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
00876             (peer->addr.sin_port == sin.sin_port)) {
00877                ast_copy_string(host, peer->name, len);
00878                res = 1;
00879                break;
00880       }
00881       peer = peer->next;
00882    }
00883    if (lockpeer)
00884       ast_mutex_unlock(&peerl.lock);
00885    if (!peer) {
00886       peer = realtime_peer(NULL, &sin);
00887       if (peer) {
00888          ast_copy_string(host, peer->name, len);
00889          if (ast_test_flag(peer, IAX_TEMPONLY))
00890             destroy_peer(peer);
00891          res = 1;
00892       }
00893    }
00894 
00895    return res;
00896 }

static int iax2_getpeertrunk struct sockaddr_in  sin  )  [static]
 

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

03397 {
03398    struct iax2_peer *peer;
03399    int res = 0;
03400    ast_mutex_lock(&peerl.lock);
03401    peer = peerl.peers;
03402    while(peer) {
03403       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03404             (peer->addr.sin_port == sin.sin_port)) {
03405                res = ast_test_flag(peer, IAX_TRUNK);
03406                break;
03407       }
03408       peer = peer->next;
03409    }
03410    ast_mutex_unlock(&peerl.lock);
03411    return res;
03412 }

static int iax2_hangup struct ast_channel c  )  [static]
 

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

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

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

Definition at line 3365 of file chan_iax2.c.

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

03366 {
03367    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03368    if (option_debug && iaxdebug)
03369       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03370    return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
03371 }

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

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

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

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

Definition at line 4604 of file chan_iax2.c.

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

04605 {
04606    if (argc != 3)
04607       return RESULT_SHOWUSAGE;
04608    iaxdebug = 0;
04609    ast_cli(fd, "IAX2 Debugging Disabled\n");
04610    return RESULT_SUCCESS;
04611 }

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

Definition at line 4622 of file chan_iax2.c.

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

04623 {
04624    if (argc != 4)
04625       return RESULT_SHOWUSAGE;
04626 #ifdef NEWJB
04627    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04628    jb_debug_output("\n");
04629 #endif
04630    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04631    return RESULT_SUCCESS;
04632 }

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

Definition at line 4613 of file chan_iax2.c.

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

04614 {
04615    if (argc != 4)
04616       return RESULT_SHOWUSAGE;
04617    iaxtrunkdebug = 0;
04618    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04619    return RESULT_SUCCESS;
04620 }

static int iax2_poke_noanswer void *  data  )  [static]
 

Definition at line 7870 of file chan_iax2.c.

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

Referenced by iax2_poke_peer().

07871 {
07872    struct iax2_peer *peer = data;
07873    peer->pokeexpire = -1;
07874    if (peer->lastms > -1) {
07875       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07876       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07877       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07878    }
07879    if (peer->callno > 0)
07880       iax2_destroy(peer->callno);
07881    peer->callno = 0;
07882    peer->lastms = -1;
07883    /* Try again quickly */
07884    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07885    return 0;
07886 }

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

Definition at line 7888 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_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, send_command(), and iax2_peer::sockfd.

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

07889 {
07890    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07891       /* IF we have no IP, or this isn't to be monitored, return
07892         imeediately after clearing things out */
07893       peer->lastms = 0;
07894       peer->historicms = 0;
07895       peer->pokeexpire = -1;
07896       peer->callno = 0;
07897       return 0;
07898    }
07899    if (peer->callno > 0) {
07900       ast_log(LOG_NOTICE, "Still have a callno...\n");
07901       iax2_destroy(peer->callno);
07902    }
07903    if (heldcall)
07904       ast_mutex_unlock(&iaxsl[heldcall]);
07905    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
07906    if (heldcall)
07907       ast_mutex_lock(&iaxsl[heldcall]);
07908    if (peer->callno < 1) {
07909       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
07910       return -1;
07911    }
07912    if (peer->pokeexpire > -1)
07913       ast_sched_del(sched, peer->pokeexpire);
07914    /* Speed up retransmission times */
07915    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
07916    iaxs[peer->callno]->peerpoke = peer;
07917    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
07918    
07919    /* If the host is already unreachable then use the unreachable interval instead */
07920    if (peer->lastms < 0) {
07921       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
07922    } else
07923       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
07924 
07925    return 0;
07926 }

static int iax2_poke_peer_s void *  data  )  [static]
 

Definition at line 5993 of file chan_iax2.c.

References iax2_poke_peer(), and iax2_peer::pokeexpire.

Referenced by iax2_poke_noanswer(), and socket_read().

05994 {
05995    struct iax2_peer *peer = data;
05996    peer->pokeexpire = -1;
05997    iax2_poke_peer(peer, 0);
05998    return 0;
05999 }

static int iax2_predestroy int  callno  )  [static]
 

Definition at line 1528 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(), iax2_user::curauthreq, IAX_ALREADYGONE, IAX_MAXAUTHREQ, iaxsl, ast_user_list::lock, LOG_WARNING, iax2_user::name, iax2_user::next, chan_iax2_pvt::owner, ast_channel::tech_pvt, usecnt, usecnt_lock, user, userl, and ast_user_list::users.

Referenced by iax2_predestroy_nolock().

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

static int iax2_predestroy_nolock int  callno  )  [static]
 

Definition at line 1592 of file chan_iax2.c.

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

Referenced by iax2_hangup(), and send_command_final().

01593 {
01594    int res;
01595    ast_mutex_unlock(&iaxsl[callno]);
01596    res = iax2_predestroy(callno);
01597    ast_mutex_lock(&iaxsl[callno]);
01598    return res;
01599 }

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

Definition at line 7848 of file chan_iax2.c.

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

07849 {
07850    int force = 0;
07851    int res;
07852    if (argc < 4)
07853       return RESULT_SHOWUSAGE;
07854    if ((argc > 4)) {
07855       if (!strcasecmp(argv[4], "forced"))
07856          force = 1;
07857       else
07858          return RESULT_SHOWUSAGE;
07859    }
07860    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07861    if (res < 0)
07862       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07863    else if (res < 1)
07864       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07865    else
07866       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07867    return RESULT_SUCCESS;
07868 }

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

Definition at line 7749 of file chan_iax2.c.

References iax_prov_complete_template().

07750 {
07751    if (pos != 3)
07752       return NULL;
07753    return iax_prov_complete_template(line, word, pos, state);
07754 }

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

Definition at line 7756 of file chan_iax2.c.

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

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

07757 {
07758    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
07759       is found for template */
07760    struct iax_ie_data provdata;
07761    struct iax_ie_data ied;
07762    unsigned int sig;
07763    struct sockaddr_in sin;
07764    int callno;
07765    struct create_addr_info cai;
07766 
07767    memset(&cai, 0, sizeof(cai));
07768 
07769    if (option_debug)
07770       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07771 
07772    if (iax_provision_build(&provdata, &sig, template, force)) {
07773       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07774       return 0;
07775    }
07776 
07777    if (end) {
07778       memcpy(&sin, end, sizeof(sin));
07779       cai.sockfd = sockfd;
07780    } else if (create_addr(dest, &sin, &cai))
07781       return -1;
07782 
07783    /* Build the rest of the message */
07784    memset(&ied, 0, sizeof(ied));
07785    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07786 
07787    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07788    if (!callno)
07789       return -1;
07790 
07791    ast_mutex_lock(&iaxsl[callno]);
07792    if (iaxs[callno]) {
07793       /* Schedule autodestruct in case they don't ever give us anything back */
07794       if (iaxs[callno]->autoid > -1)
07795          ast_sched_del(sched, iaxs[callno]->autoid);
07796       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07797       ast_set_flag(iaxs[callno], IAX_PROVISION);
07798       /* Got a call number now, so go ahead and send the provisioning information */
07799       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07800    }
07801    ast_mutex_unlock(&iaxsl[callno]);
07802 
07803    return 1;
07804 }

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

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

01854 {
01855    struct iax2_peer *peer;
01856 
01857    if (argc != 4)
01858         return RESULT_SHOWUSAGE;
01859    if (!strcmp(argv[3],"all")) {
01860       reload_config();
01861       ast_cli(fd, "OK cache is flushed.\n");
01862    } else if ((peer = find_peer(argv[3], 0))) {
01863       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
01864          ast_set_flag(peer, IAX_RTAUTOCLEAR);
01865          expire_registry(peer);
01866          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
01867       } else {
01868          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
01869       }
01870    } else {
01871       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
01872    }
01873    
01874    return RESULT_SUCCESS;
01875 }

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

Definition at line 1128 of file chan_iax2.c.

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

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

01129 {
01130    /* Assumes lock for callno is already held... */
01131    for (;;) {
01132       if (iaxs[callno] && iaxs[callno]->owner) {
01133          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01134             /* Avoid deadlock by pausing and trying again */
01135             ast_mutex_unlock(&iaxsl[callno]);
01136             usleep(1);
01137             ast_mutex_lock(&iaxsl[callno]);
01138          } else {
01139             ast_queue_frame(iaxs[callno]->owner, f);
01140             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01141             break;
01142          }
01143       } else
01144          break;
01145    }
01146    return 0;
01147 }

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

Definition at line 3141 of file chan_iax2.c.

References AST_FRAME_NULL, ast_log(), and LOG_NOTICE.

03142 {
03143    static struct ast_frame f = { AST_FRAME_NULL, };
03144    ast_log(LOG_NOTICE, "I should never be called!\n");
03145    return &f;
03146 }

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

Definition at line 5564 of file chan_iax2.c.

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

Referenced by set_config().

05565 {
05566    struct iax2_registry *reg;
05567    char copy[256];
05568    char *username, *hostname, *secret;
05569    char *porta;
05570    char *stringp=NULL;
05571    
05572    struct ast_hostent ahp; struct hostent *hp;
05573    if (!value)
05574       return -1;
05575    ast_copy_string(copy, value, sizeof(copy));
05576    stringp=copy;
05577    username = strsep(&stringp, "@");
05578    hostname = strsep(&stringp, "@");
05579    if (!hostname) {
05580       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
05581       return -1;
05582    }
05583    stringp=username;
05584    username = strsep(&stringp, ":");
05585    secret = strsep(&stringp, ":");
05586    stringp=hostname;
05587    hostname = strsep(&stringp, ":");
05588    porta = strsep(&stringp, ":");
05589    
05590    if (porta && !atoi(porta)) {
05591       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05592       return -1;
05593    }
05594    hp = ast_gethostbyname(hostname, &ahp);
05595    if (!hp) {
05596       ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
05597       return -1;
05598    }
05599    reg = malloc(sizeof(struct iax2_registry));
05600    if (reg) {
05601       memset(reg, 0, sizeof(struct iax2_registry));
05602       ast_copy_string(reg->username, username, sizeof(reg->username));
05603       if (secret)
05604          ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05605       reg->expire = -1;
05606       reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05607       reg->addr.sin_family = AF_INET;
05608       memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
05609       reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05610       reg->next = registrations;
05611       reg->callno = 0;
05612       registrations = reg;
05613    } else {
05614       ast_log(LOG_ERROR, "Out of memory\n");
05615       return -1;
05616    }
05617    return 0;
05618 }

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

Definition at line 8964 of file chan_iax2.c.

References reload_config().

08965 {
08966    return reload_config();
08967 }

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

Definition at line 7938 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(), fmt, chan_iax2_pvt::host, host, iax2_capability, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), ast_channel::readformat, and ast_channel::writeformat.

07939 {
07940    int callno;
07941    int res;
07942    int fmt, native;
07943    struct sockaddr_in sin;
07944    struct ast_channel *c;
07945    struct parsed_dial_string pds;
07946    struct create_addr_info cai;
07947    char *tmpstr;
07948 
07949    memset(&pds, 0, sizeof(pds));
07950    tmpstr = ast_strdupa(data);
07951    parse_dial_string(tmpstr, &pds);
07952 
07953    memset(&cai, 0, sizeof(cai));
07954    cai.capability = iax2_capability;
07955 
07956    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07957 
07958    if (!pds.peer) {
07959       ast_log(LOG_WARNING, "No peer given\n");
07960       return NULL;
07961    }
07962           
07963    
07964    /* Populate our address from the given */
07965    if (create_addr(pds.peer, &sin, &cai)) {
07966       *cause = AST_CAUSE_UNREGISTERED;
07967       return NULL;
07968    }
07969 
07970    if (pds.port)
07971       sin.sin_port = htons(atoi(pds.port));
07972 
07973    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07974    if (callno < 1) {
07975       ast_log(LOG_WARNING, "Unable to create call\n");
07976       *cause = AST_CAUSE_CONGESTION;
07977       return NULL;
07978    }
07979 
07980    ast_mutex_lock(&iaxsl[callno]);
07981 
07982    /* If this is a trunk, update it now */
07983    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
07984    if (ast_test_flag(&cai, IAX_TRUNK))
07985       callno = make_trunk(callno, 1);
07986    iaxs[callno]->maxtime = cai.maxtime;
07987    if (cai.found)
07988       ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host));
07989 
07990    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
07991 
07992    ast_mutex_unlock(&iaxsl[callno]);
07993 
07994    if (c) {
07995       /* Choose a format we can live with */
07996       if (c->nativeformats & format) 
07997          c->nativeformats &= format;
07998       else {
07999          native = c->nativeformats;
08000          fmt = format;
08001          res = ast_translator_best_choice(&fmt, &native);
08002          if (res < 0) {
08003             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08004                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08005             ast_hangup(c);
08006             return NULL;
08007          }
08008          c->nativeformats = native;
08009       }
08010       c->readformat = ast_best_codec(c->nativeformats);
08011       c->writeformat = c->readformat;
08012    }
08013 
08014    return c;
08015 }

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

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

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

Definition at line 2572 of file chan_iax2.c.

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

02573 {
02574    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02575 }

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

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

02568 {
02569    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02570 }

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

Definition at line 2560 of file chan_iax2.c.

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

02561 {
02562    
02563    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02564       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02565 }

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

Definition at line 1817 of file chan_iax2.c.

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

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

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

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

03113 {
03114    struct ast_option_header *h;
03115    int res;
03116 
03117    switch (option) {
03118    case AST_OPTION_TXGAIN:
03119    case AST_OPTION_RXGAIN:
03120       /* these two cannot be sent, because they require a result */
03121       errno = ENOSYS;
03122       return -1;
03123    default:
03124       h = malloc(datalen + sizeof(*h));
03125       if (h) {
03126          h->flag = AST_OPTION_FLAG_REQUEST;
03127          h->option = htons(option);
03128          memcpy(h->data, data, datalen);
03129          res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03130                     AST_CONTROL_OPTION, 0, (unsigned char *) h,
03131                     datalen + sizeof(*h), -1);
03132          free(h);
03133          return res;
03134       } else {
03135          ast_log(LOG_WARNING, "Out of memory\n");
03136          return -1;
03137       }
03138    }
03139 }

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

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

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

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

Definition at line 4417 of file chan_iax2.c.

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

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

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

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

04315 {
04316 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04317 #if !defined(__FreeBSD__)
04318 #define FORMAT "%-15.15s  %-15d %-15d\n"
04319 #else /* __FreeBSD__ */
04320 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04321 #endif /* __FreeBSD__ */
04322    struct iax_firmware *cur;
04323    if ((argc != 3) && (argc != 4))
04324       return RESULT_SHOWUSAGE;
04325    ast_mutex_lock(&waresl.lock);
04326    
04327    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04328    for (cur = waresl.wares;cur;cur = cur->next) {
04329       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04330          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04331             (int)ntohl(cur->fwh->datalen));
04332    }
04333    ast_mutex_unlock(&waresl.lock);
04334    return RESULT_SUCCESS;
04335 #undef FORMAT
04336 #undef FORMAT2
04337 }

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

Definition at line 4563 of file chan_iax2.c.

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

04564 {
04565    int numchans = 0;
04566    if (argc != 3)
04567       return RESULT_SHOWUSAGE;
04568    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04569    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04570    numchans = ast_cli_netstats(fd, 1);
04571    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04572    return RESULT_SUCCESS;
04573 }

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

Definition at line 1946 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, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.

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

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

Definition at line 4303 of file chan_iax2.c.

References __iax2_show_peers().

04304 {
04305    return __iax2_show_peers(0, fd, argc, argv);
04306 }

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

Definition at line 4375 of file chan_iax2.c.

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

04376 {
04377 #define FORMAT2 "%-20.20s  %-10.10s  %-20.20s %8.8s  %s\n"
04378 #define FORMAT "%-20.20s  %-10.10s  %-20.20s %8d  %s\n"
04379    struct iax2_registry *reg;
04380    char host[80];
04381    char perceived[80];
04382    char iabuf[INET_ADDRSTRLEN];
04383    if (argc != 3)
04384       return RESULT_SHOWUSAGE;
04385    ast_mutex_lock(&peerl.lock);
04386    ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
04387    for (reg = registrations;reg;reg = reg->next) {
04388       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04389       if (reg->us.sin_addr.s_addr) 
04390          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
04391       else
04392          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04393       ast_cli(fd, FORMAT, host, 
04394                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04395    }
04396    ast_mutex_unlock(&peerl.lock);
04397    return RESULT_SUCCESS;
04398 #undef FORMAT
04399 #undef FORMAT2
04400 }

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

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

02031 {
02032    struct iax_frame *cur;
02033    int cnt = 0, dead=0, final=0;
02034    if (argc != 3)
02035       return RESULT_SHOWUSAGE;
02036    for (cur = iaxq.head; cur ; cur = cur->next) {
02037       if (cur->retries < 0)
02038          dead++;
02039       if (cur->final)
02040          final++;
02041       cnt++;
02042    }
02043    ast_cli(fd, "    IAX Statistics\n");
02044    ast_cli(fd, "---------------------\n");
02045    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02046    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
02047    return RESULT_SUCCESS;
02048 }

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

Definition at line 4136 of file chan_iax2.c.

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

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

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

Definition at line 3148 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(), TRANSFER_BEGIN, and chan_iax2_pvt::transferring.

Referenced by iax2_bridge().

03149 {
03150    int res;
03151    struct iax_ie_data ied0;
03152    struct iax_ie_data ied1;
03153    unsigned int transferid = rand();
03154    memset(&ied0, 0, sizeof(ied0));
03155    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03156    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03157    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03158 
03159    memset(&ied1, 0, sizeof(ied1));
03160    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03161    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03162    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03163    
03164    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03165    if (res)
03166       return -1;
03167    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03168    if (res)
03169       return -1;
03170    iaxs[callno0]->transferring = TRANSFER_BEGIN;
03171    iaxs[callno1]->transferring = TRANSFER_BEGIN;
03172    return 0;
03173 }

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

Definition at line 1877 of file chan_iax2.c.

References RESULT_SHOWUSAGE, RESULT_SUCCESS, and test_losspct.

01878 {
01879        if (argc != 4)
01880                return RESULT_SHOWUSAGE;
01881 
01882        test_losspct = atoi(argv[3]);
01883 
01884        return RESULT_SUCCESS;
01885 }

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

Definition at line 3373 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, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.

03374 {
03375    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03376    struct iax_ie_data ied;
03377    char tmp[256], *context;
03378    ast_copy_string(tmp, dest, sizeof(tmp));
03379    context = strchr(tmp, '@');
03380    if (context) {
03381       *context = '\0';
03382       context++;
03383    }
03384    memset(&ied, 0, sizeof(ied));
03385    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03386    if (context)
03387       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03388    if (option_debug)
03389       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03390    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03391 }

static int iax2_transmit struct iax_frame fr  )  [static]
 

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

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

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

Definition at line 6044 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

06045 {
06046    /* Drop when trunk is about 5 seconds idle */
06047    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06048       return 1;
06049    return 0;
06050 }

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

Definition at line 3738 of file chan_iax2.c.

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

03739 {
03740    struct ast_frame *f;
03741    struct iax2_trunk_peer *tpeer;
03742    void *tmp, *ptr;
03743    struct ast_iax2_meta_trunk_entry *met;
03744    struct ast_iax2_meta_trunk_mini *mtm;
03745    char iabuf[INET_ADDRSTRLEN];
03746 
03747    f = &fr->af;
03748    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03749    if (tpeer) {
03750       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03751          /* Need to reallocate space */
03752          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03753             tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE);
03754             if (tmp) {
03755                tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03756                tpeer->trunkdata = tmp;
03757                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);
03758             } else {
03759                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));
03760                ast_mutex_unlock(&tpeer->lock);
03761                return -1;
03762             }
03763          } else {
03764             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));
03765             ast_mutex_unlock(&tpeer->lock);
03766             return -1;
03767          }
03768       }
03769 
03770       /* Append to meta frame */
03771       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03772       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03773          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03774          mtm->len = htons(f->datalen);
03775          mtm->mini.callno = htons(pvt->callno);
03776          mtm->mini.ts = htons(0xffff & fr->ts);
03777          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03778          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03779       } else {
03780          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03781          /* Store call number and length in meta header */
03782          met->callno = htons(pvt->callno);
03783          met->len = htons(f->datalen);
03784          /* Advance pointers/decrease length past trunk entry header */
03785          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03786          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03787       }
03788       /* Copy actual trunk data */
03789       memcpy(ptr, f->data, f->datalen);
03790       tpeer->trunkdatalen += f->datalen;
03791 
03792       tpeer->calls++;
03793       ast_mutex_unlock(&tpeer->lock);
03794    }
03795    return 0;
03796 }

static int iax2_vnak int  callno  )  [static]
 

Definition at line 5972 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().

Referenced by socket_read().

05973 {
05974    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
05975 }

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

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

04635 {
04636    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04637    int res = -1;
04638    ast_mutex_lock(&iaxsl[callno]);
04639    if (iaxs[callno]) {
04640    /* If there's an outstanding error, return failure now */
04641       if (!iaxs[callno]->error) {
04642          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04643             res = 0;
04644             /* Don't waste bandwidth sending null frames */
04645          else if (f->frametype == AST_FRAME_NULL)
04646             res = 0;
04647          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04648             res = 0;
04649          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04650             res = 0;
04651          else
04652          /* Simple, just queue for transmission */
04653             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04654       } else {
04655          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04656       }
04657    }
04658    /* If it's already gone, just return */
04659    ast_mutex_unlock(&iaxsl[callno]);
04660    return res;
04661 }

static int iax_check_version char *  dev  )  [static]
 

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

01307 {
01308    int res = 0;
01309    struct iax_firmware *cur;
01310    if (!ast_strlen_zero(dev)) {
01311       ast_mutex_lock(&waresl.lock);
01312       cur = waresl.wares;
01313       while(cur) {
01314          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01315             res = ntohs(cur->fwh->version);
01316             break;
01317          }
01318          cur = cur->next;
01319       }
01320       ast_mutex_unlock(&waresl.lock);
01321    }
01322    return res;
01323 }

static void iax_debug_output const char *  data  )  [static]
 

Definition at line 666 of file chan_iax2.c.

References ast_verbose(), and iaxdebug.

Referenced by load_module().

00667 {
00668    if (iaxdebug)
00669       ast_verbose("%s", data);
00670 }

static void iax_error_output const char *  data  )  [static]
 

Definition at line 672 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

00673 {
00674    ast_log(LOG_WARNING, "%s", data);
00675 }

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

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

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

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

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

06224 {
06225    struct iax_dual *d;
06226    struct ast_channel *chan1m, *chan2m;
06227    pthread_t th;
06228    chan1m = ast_channel_alloc(0);
06229    chan2m = ast_channel_alloc(0);
06230    if (chan2m && chan1m) {
06231       snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
06232       /* Make formats okay */
06233       chan1m->readformat = chan1->readformat;
06234       chan1m->writeformat = chan1->writeformat;
06235       ast_channel_masquerade(chan1m, chan1);
06236       /* Setup the extensions and such */
06237       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06238       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06239       chan1m->priority = chan1->priority;
06240       
06241       /* We make a clone of the peer channel too, so we can play
06242          back the announcement */
06243       snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name);
06244       /* Make formats okay */
06245       chan2m->readformat = chan2->readformat;
06246       chan2m->writeformat = chan2->writeformat;
06247       ast_channel_masquerade(chan2m, chan2);
06248       /* Setup the extensions and such */
06249       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06250       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06251       chan2m->priority = chan2->priority;
06252       if (ast_do_masquerade(chan2m)) {
06253          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06254          ast_hangup(chan2m);
06255          return -1;
06256       }
06257    } else {
06258       if (chan1m)
06259          ast_hangup(chan1m);
06260       if (chan2m)
06261          ast_hangup(chan2m);
06262       return -1;
06263    }
06264    d = malloc(sizeof(struct iax_dual));
06265    if (d) {
06266       memset(d, 0, sizeof(*d));
06267       d->chan1 = chan1m;
06268       d->chan2 = chan2m;
06269       if (!ast_pthread_create(&th, NULL, iax_park_thread, d))
06270          return 0;
06271       free(d);
06272    }
06273    return -1;
06274 }

static void* iax_park_thread void *  stuff  )  [static]
 

Definition at line 6203 of file chan_iax2.c.

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

Referenced by iax_park().

06204 {
06205    struct ast_channel *chan1, *chan2;
06206    struct iax_dual *d;
06207    struct ast_frame *f;
06208    int ext;
06209    int res;
06210    d = stuff;
06211    chan1 = d->chan1;
06212    chan2 = d->chan2;
06213    free(d);
06214    f = ast_read(chan1);
06215    if (f)
06216       ast_frfree(f);
06217    res = ast_park_call(chan1, chan2, 0, &ext);
06218    ast_hangup(chan2);
06219    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06220    return NULL;
06221 }

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

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

00934 {
00935    /* Malloc() a copy of a frame */
00936    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
00937    if (new) {
00938       memcpy(new, fr, sizeof(struct iax_frame));   
00939       iax_frame_wrap(new, &fr->af);
00940       new->data = NULL;
00941       new->datalen = 0;
00942       new->direction = DIRECTION_INGRESS;
00943       new->retrans = -1;
00944    }
00945    return new;
00946 }

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

Definition at line 702 of file chan_iax2.c.

References ast_verbose().

Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().

00703 {
00704    va_list args;
00705    char buf[1024];
00706 
00707    va_start(args, fmt);
00708    vsnprintf(buf, 1024, fmt, args);
00709    va_end(args);
00710 
00711    ast_verbose(buf);
00712 }

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

Definition at line 678 of file chan_iax2.c.

References ast_log(), and LOG_ERROR.

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

00679 {
00680    va_list args;
00681    char buf[1024];
00682 
00683    va_start(args, fmt);
00684    vsnprintf(buf, 1024, fmt, args);
00685    va_end(args);
00686 
00687    ast_log(LOG_ERROR, buf);
00688 }

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

Definition at line 690 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

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

00691 {
00692    va_list args;
00693    char buf[1024];
00694 
00695    va_start(args, fmt);
00696    vsnprintf(buf, 1024, fmt, args);
00697    va_end(args);
00698 
00699    ast_log(LOG_WARNING, buf);
00700 }

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

References ASTERISK_GPL_KEY.

09738 {
09739    return ASTERISK_GPL_KEY;
09740 }

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 9635 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_do_register(), iax2_poke_peer(), iax2_prov_app(), iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_provision_reload(), iax_set_error(), iax_set_output(), iaxq, iaxsl, 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(), iax2_peer::next, iax2_registry::next, option_verbose, peerl, ast_peer_list::peers, reload_firmware(), sched_context_create(), set_config(), iax2_peer::sockfd, start_network_thread(), timingfd, userl, VERBOSE_PREFIX_2, and waresl.

09636 {
09637    char *config = "iax.conf";
09638    int res = 0;
09639    int x;
09640    struct iax2_registry *reg;
09641    struct iax2_peer *peer;
09642    
09643    ast_custom_function_register(&iaxpeer_function);
09644 
09645    iax_set_output(iax_debug_output);
09646    iax_set_error(iax_error_output);
09647 #ifdef NEWJB
09648    jb_setoutput(jb_error_output, jb_warning_output, NULL);
09649 #endif
09650    
09651 #ifdef IAX_TRUNKING
09652 #ifdef ZT_TIMERACK
09653    timingfd = open("/dev/zap/timer", O_RDWR);
09654    if (timingfd < 0)
09655 #endif
09656       timingfd = open("/dev/zap/pseudo", O_RDWR);
09657    if (timingfd < 0) 
09658       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
09659 #endif      
09660 
09661    memset(iaxs, 0, sizeof(iaxs));
09662 
09663    for (x=0;x<IAX_MAX_CALLS;x++)
09664       ast_mutex_init(&iaxsl[x]);
09665    
09666    io = io_context_create();
09667    sched = sched_context_create();
09668    
09669    if (!io || !sched) {
09670       ast_log(LOG_ERROR, "Out of memory\n");
09671       return -1;
09672    }
09673 
09674    netsock = ast_netsock_list_alloc();
09675    if (!netsock) {
09676       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
09677       return -1;
09678    }
09679    ast_netsock_init(netsock);
09680 
09681    ast_mutex_init(&iaxq.lock);
09682    ast_mutex_init(&userl.lock);
09683    ast_mutex_init(&peerl.lock);
09684    ast_mutex_init(&waresl.lock);
09685    
09686    ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09687 
09688    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
09689    
09690    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
09691    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
09692 
09693    set_config(config, 0);
09694 
09695    if (ast_channel_register(&iax2_tech)) {
09696       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
09697       __unload_module();
09698       return -1;
09699    }
09700 
09701    if (ast_register_switch(&iax2_switch)) 
09702       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
09703 
09704    res = start_network_thread();
09705    if (!res) {
09706       if (option_verbose > 1) 
09707          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
09708    } else {
09709       ast_log(LOG_ERROR, "Unable to start network thread\n");
09710       ast_netsock_release(netsock);
09711    }
09712 
09713    for (reg = registrations; reg; reg = reg->next)
09714       iax2_do_register(reg);
09715    ast_mutex_lock(&peerl.lock);
09716    for (peer = peerl.peers; peer; peer = peer->next) {
09717       if (peer->sockfd < 0)
09718          peer->sockfd = defaultsockfd;
09719       iax2_poke_peer(peer, 0);
09720    }
09721    ast_mutex_unlock(&peerl.lock);
09722    reload_firmware();
09723    iax_provision_reload();
09724    return res;
09725 }

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

Definition at line 3175 of file chan_iax2.c.

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

Referenced by iax2_bridge().

03176 {
03177    ast_mutex_lock(&iaxsl[callno0]);
03178    while (ast_mutex_trylock(&iaxsl[callno1])) {
03179       ast_mutex_unlock(&iaxsl[callno0]);
03180       usleep(10);
03181       ast_mutex_lock(&iaxsl[callno0]);
03182    }
03183 }

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

Definition at line 1000 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, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, ping_time, chan_iax2_pvt::pingid, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().

Referenced by iax2_request(), and socket_read().

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

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

Definition at line 4307 of file chan_iax2.c.

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

Referenced by load_module().

04308 {
04309    ast_cli_netstats(s->fd, 0);
04310    ast_cli(s->fd, "\r\n");
04311    return RESULT_SUCCESS;
04312 }

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

Definition at line 4340 of file chan_iax2.c.

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

Referenced by load_module().

04341 {
04342    char *a[] = { "iax2", "show", "users" };
04343    int ret;
04344    char *id;
04345    id = astman_get_header(m,"ActionID");
04346    if (!ast_strlen_zero(id))
04347       ast_cli(s->fd, "ActionID: %s\r\n",id);
04348    ret = __iax2_show_peers(1, s->fd, 3, a );
04349    ast_cli(s->fd, "\r\n\r\n" );
04350    return ret;
04351 } /* /JDG */

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

Definition at line 952 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(), pbx_find_extension(), realtime_switch_common(), schedule_delivery(), and softhangup_exec().

00953 {
00954    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
00955       (cur->addr.sin_port == sin->sin_port)) {
00956       /* This is the main host */
00957       if ((cur->peercallno == callno) ||
00958          ((dcallno == cur->callno) && !cur->peercallno)) {
00959          /* That's us.  Be sure we keep track of the peer call number */
00960          return 1;
00961       }
00962    }
00963    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
00964        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
00965       /* We're transferring */
00966       if (dcallno == cur->callno)
00967          return 1;
00968    }
00969    return 0;
00970 }

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

Definition at line 3804 of file chan_iax2.c.

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

Referenced by decode_frame().

03805 {
03806 #if 0
03807    /* Debug with "fake encryption" */
03808    int x;
03809    if (len % 16)
03810       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03811    for (x=0;x<len;x++)
03812       dst[x] = src[x] ^ 0xff;
03813 #else 
03814    unsigned char lastblock[16] = { 0 };
03815    int x;
03816    while(len > 0) {
03817       aes_decrypt(src, dst, dcx);
03818       for (x=0;x<16;x++)
03819          dst[x] ^= lastblock[x];
03820       memcpy(lastblock, src, sizeof(lastblock));
03821       dst += 16;
03822       src += 16;
03823       len -= 16;
03824    }
03825 #endif
03826 }

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

Definition at line 3828 of file chan_iax2.c.

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

Referenced by encrypt_frame().

03829 {
03830 #if 0
03831    /* Debug with "fake encryption" */
03832    int x;
03833    if (len % 16)
03834       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03835    for (x=0;x<len;x++)
03836       dst[x] = src[x] ^ 0xff;
03837 #else
03838    unsigned char curblock[16] = { 0 };
03839    int x;
03840    while(len > 0) {
03841       for (x=0;x<16;x++)
03842          curblock[x] ^= src[x];
03843       aes_encrypt(curblock, dst, ecx);
03844       memcpy(curblock, dst, sizeof(curblock)); 
03845       dst += 16;
03846       src += 16;
03847       len -= 16;
03848    }
03849 #endif
03850 }

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

Definition at line 4946 of file chan_iax2.c.

References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.

Referenced by authenticate_reply(), and socket_read().

04947 {
04948    /* Select exactly one common encryption if there are any */
04949    p->encmethods &= enc;
04950    if (p->encmethods) {
04951       if (p->encmethods & IAX_ENCRYPT_AES128)
04952          p->encmethods = IAX_ENCRYPT_AES128;
04953       else
04954          p->encmethods = 0;
04955    }
04956 }

static void* network_thread void *  ignore  )  [static]
 

Definition at line 8017 of file chan_iax2.c.

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

Referenced by start_network_thread().

08018 {
08019    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08020       from the network, and queue them for delivery to the channels */
08021    int res, count;
08022    struct iax_frame *f, *freeme;
08023    if (timingfd > -1)
08024       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08025    for(;;) {
08026       /* Go through the queue, sending messages which have not yet been
08027          sent, and scheduling retransmissions if appropriate */
08028       ast_mutex_lock(&iaxq.lock);
08029       f = iaxq.head;
08030       count = 0;
08031       while(f) {
08032          freeme = NULL;
08033          if (!f->sentyet) {
08034             f->sentyet++;
08035             /* Send a copy immediately -- errors here are ok, so don't bother locking */
08036             if (iaxs[f->callno]) {
08037                send_packet(f);
08038                count++;
08039             } 
08040             if (f->retries < 0) {
08041                /* This is not supposed to be retransmitted */
08042                if (f->prev) 
08043                   f->prev->next = f->next;
08044                else
08045                   iaxq.head = f->next;
08046                if (f->next)
08047                   f->next->prev = f->prev;
08048                else
08049                   iaxq.tail = f->prev;
08050                iaxq.count--;
08051                /* Free the iax frame */
08052                freeme = f;
08053             } else {
08054                /* We need reliable delivery.  Schedule a retransmission */
08055                f->retries++;
08056                f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08057             }
08058          }
08059          f = f->next;
08060          if (freeme)
08061             iax_frame_free(freeme);
08062       }
08063       ast_mutex_unlock(&iaxq.lock);
08064       if (count >= 20)
08065          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08066 
08067       /* Now do the IO, and run scheduled tasks */
08068       res = ast_sched_wait(sched);
08069       if ((res > 1000) || (res < 0))
08070          res = 1000;
08071       res = ast_io_wait(io, res);
08072       if (res >= 0) {
08073          if (res >= 20)
08074             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08075          count = ast_sched_runq(sched);
08076          if (count >= 20)
08077             ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08078       }
08079    }
08080    return NULL;
08081 }

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

Definition at line 898 of file chan_iax2.c.

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

Referenced by find_callno().

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

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

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

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

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

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

Definition at line 8142 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, iax2_peer::sockfd, and strsep().

Referenced by build_peer().

08143 {
08144    struct sockaddr_in sin;
08145    int nonlocal = 1;
08146    int port = IAX_DEFAULT_PORTNO;
08147    int sockfd = defaultsockfd;
08148    char *tmp;
08149    char *addr;
08150    char *portstr;
08151 
08152    tmp = ast_strdupa(srcaddr);
08153    if (!tmp) {
08154       ast_log(LOG_WARNING, "Out of memory!\n");
08155       return -1;
08156    }
08157 
08158    addr = strsep(&tmp, ":");
08159    portstr = tmp;
08160 
08161    if (portstr) {
08162       port = atoi(portstr);
08163       if (port < 1)
08164          port = IAX_DEFAULT_PORTNO;
08165    }
08166    
08167    if (!ast_get_ip(&sin, addr)) {
08168       struct ast_netsock *sock;
08169       int res;
08170 
08171       sin.sin_port = 0;
08172       sin.sin_family = AF_INET;
08173       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08174       if (res == 0) {
08175          /* ip address valid. */
08176          sin.sin_port = htons(port);
08177          sock = ast_netsock_find(netsock, &sin);
08178          if (sock) {
08179             sockfd = ast_netsock_sockfd(sock);
08180             nonlocal = 0;
08181          }
08182       }
08183    }
08184       
08185    peer->sockfd = sockfd;
08186 
08187    if (nonlocal) {
08188       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08189          srcaddr, peer->name);
08190       return -1;
08191    } else {
08192       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08193       return 0;
08194    }
08195 }

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

peer_status: Report Peer status in character string

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

01924 {
01925    int res = 0;
01926    if (peer->maxms) {
01927       if (peer->lastms < 0) {
01928          ast_copy_string(status, "UNREACHABLE", statuslen);
01929       } else if (peer->lastms > peer->maxms) {
01930          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
01931          res = 1;
01932       } else if (peer->lastms) {
01933          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
01934          res = 1;
01935       } else {
01936          ast_copy_string(status, "UNKNOWN", statuslen);
01937       }
01938    } else { 
01939       ast_copy_string(status, "Unmonitored", statuslen);
01940       res = -1;
01941    }
01942    return res;
01943 }

static void prune_peers void   )  [static]
 

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

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

static void prune_users void   )  [static]
 

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

08599 {
08600    struct iax2_user *user, *usernext, *userlast = NULL;
08601    ast_mutex_lock(&userl.lock);
08602    for (user=userl.users;user;) {
08603       usernext = user->next;
08604       if (ast_test_flag(user, IAX_DELME)) {
08605          destroy_user(user);
08606          if (userlast)
08607             userlast->next = usernext;
08608          else
08609             userl.users = usernext;
08610       } else
08611          userlast = user;
08612       user = usernext;
08613    }
08614    ast_mutex_unlock(&userl.lock);
08615 }

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

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

04926 {
04927    struct ast_iax2_full_hdr fh;
04928    char iabuf[INET_ADDRSTRLEN];
04929    fh.scallno = htons(src | IAX_FLAG_FULL);
04930    fh.dcallno = htons(dst);
04931    fh.ts = 0;
04932    fh.oseqno = 0;
04933    fh.iseqno = 0;
04934    fh.type = AST_FRAME_IAX;
04935    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04936    if (iaxdebug)
04937        iax_showframe(NULL, &fh, 0, sin, 0);
04938 #if 0
04939    if (option_debug)
04940 #endif   
04941       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04942          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst);
04943    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04944 }

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

Definition at line 2595 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, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, ast_peer_list::lock, ast_variable::name, ast_variable::next, peerl, ast_peer_list::peers, reg_source_db(), ast_variable::value, and var.

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

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

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

Definition at line 2734 of file chan_iax2.c.

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

Referenced by update_peer(), and update_registry().

02735 {
02736    char port[10];
02737    char ipaddr[20];
02738    char regseconds[20];
02739    time_t nowtime;
02740    
02741    time(&nowtime);
02742    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);
02743    ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
02744    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02745    ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL);
02746 }

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

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

02694 {
02695    struct ast_variable *var;
02696    struct ast_variable *tmp;
02697    struct iax2_user *user=NULL;
02698 
02699    var = ast_load_realtime("iaxusers", "name", username, NULL);
02700    if (!var)
02701       return NULL;
02702 
02703    tmp = var;
02704    while(tmp) {
02705       /* Make sure it's not a peer only... */
02706       if (!strcasecmp(tmp->name, "type")) {
02707          if (strcasecmp(tmp->value, "friend") &&
02708              strcasecmp(tmp->value, "user")) {
02709             return NULL;
02710          } 
02711       }
02712       tmp = tmp->next;
02713    }
02714 
02715    user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02716    if (!user)
02717       return NULL;
02718 
02719    ast_variables_destroy(var);
02720 
02721    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02722       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02723       ast_mutex_lock(&userl.lock);
02724       user->next = userl.users;
02725       userl.users = user;
02726       ast_mutex_unlock(&userl.lock);
02727    } else {
02728       ast_set_flag(user, IAX_TEMPONLY);   
02729    }
02730 
02731    return user;
02732 }

static void reg_source_db struct iax2_peer p  )  [static]
 

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

05668 {
05669    char data[80];
05670    struct in_addr in;
05671    char iabuf[INET_ADDRSTRLEN];
05672    char *c, *d;
05673    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05674       c = strchr(data, ':');
05675       if (c) {
05676          *c = '\0';
05677          c++;
05678          if (inet_aton(data, &in)) {
05679             d = strchr(c, ':');
05680             if (d) {
05681                *d = '\0';
05682                d++;
05683                if (option_verbose > 2)
05684                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05685                   ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d));
05686                iax2_poke_peer(p, 0);
05687                p->expiry = atoi(d);
05688                memset(&p->addr, 0, sizeof(p->addr));
05689                p->addr.sin_family = AF_INET;
05690                p->addr.sin_addr = in;
05691                p->addr.sin_port = htons(atoi(c));
05692                if (p->expire > -1)
05693                   ast_sched_del(sched, p->expire);
05694                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05695                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05696                if (iax2_regfunk)
05697                   iax2_regfunk(p->name, 1);
05698                register_peer_exten(p, 1);
05699             }              
05700                
05701          }
05702       }
05703    }
05704 }

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

Definition at line 5620 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 destroy_peer(), expire_register(), expire_registry(), parse_register_contact(), reg_source_db(), sip_destroy_peer(), and update_registry().

05621 {
05622    char multi[256];
05623    char *stringp, *ext;
05624    if (!ast_strlen_zero(regcontext)) {
05625       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
05626       stringp = multi;
05627       while((ext = strsep(&stringp, "&"))) {
05628          if (onoff) {
05629             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05630                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype);
05631          } else
05632             ast_context_remove_extension(regcontext, ext, 1, NULL);
05633       }
05634    }
05635 }

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

Verify inbound registration.

Definition at line 5086 of file chan_iax2.c.

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

Referenced by handle_request_register(), and socket_read().

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

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

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

05809 {
05810    struct iax_ie_data ied;
05811    struct iax2_peer *p;
05812    /* SLD: third call to find_peer in registration */
05813    p = find_peer(name, 1);
05814    if (p) {
05815       memset(&ied, 0, sizeof(ied));
05816       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05817       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05818          /* Build the challenge */
05819          snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand());
05820          iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05821       }
05822       iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05823       if (ast_test_flag(p, IAX_TEMPONLY))
05824          destroy_peer(p);
05825       return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05826    } 
05827    ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05828    return 0;
05829 }

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

Definition at line 5831 of file chan_iax2.c.

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

Referenced by socket_read().

05832 {
05833    struct iax2_registry *reg;
05834    /* Start pessimistic */
05835    struct iax_ie_data ied;
05836    char peer[256] = "";
05837    char iabuf[INET_ADDRSTRLEN];
05838    char challenge[256] = "";
05839    int res;
05840    int authmethods = 0;
05841    if (ies->authmethods)
05842       authmethods = ies->authmethods;
05843    if (ies->username)
05844       ast_copy_string(peer, ies->username, sizeof(peer));
05845    if (ies->challenge)
05846       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05847    memset(&ied, 0, sizeof(ied));
05848    reg = iaxs[callno]->reg;
05849    if (reg) {
05850          if (inaddrcmp(&reg->addr, sin)) {
05851             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05852             return -1;
05853          }
05854          if (ast_strlen_zero(reg->secret)) {
05855             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05856             reg->regstate = REG_STATE_NOAUTH;
05857             return -1;
05858          }
05859          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05860          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05861          if (reg->secret[0] == '[') {
05862             char tmpkey[256];
05863             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05864             tmpkey[strlen(tmpkey) - 1] = '\0';
05865             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05866          } else
05867             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05868          if (!res) {
05869             reg->regstate = REG_STATE_AUTHSENT;
05870             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05871          } else
05872             return -1;
05873          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05874    } else   
05875       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05876    return -1;
05877 }

static char* regstate2str int  regstate  )  [static]
 

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

04354 {
04355    switch(regstate) {
04356    case REG_STATE_UNREGISTERED:
04357       return "Unregistered";
04358    case REG_STATE_REGSENT:
04359       return "Request Sent";
04360    case REG_STATE_AUTHSENT:
04361       return "Auth. Sent";
04362    case REG_STATE_REGISTERED:
04363       return "Registered";
04364    case REG_STATE_REJECTED:
04365       return "Rejected";
04366    case REG_STATE_TIMEOUT:
04367       return "Timeout";
04368    case REG_STATE_NOAUTH:
04369       return "No Authentication";
04370    default:
04371       return "Unknown";
04372    }
04373 }

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

References reload_config().

08970 {
08971    return reload_config();
08972 }

static int reload_config void   )  [static]
 

Definition at line 1998 of file chan_h323.c.

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

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

static void reload_firmware void   )  [static]
 

Definition at line 1362 of file chan_iax2.c.

References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), 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().

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

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

Definition at line 6322 of file chan_iax2.c.

References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.

Referenced by socket_read().

06323 {
06324    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06325    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06326    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06327    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06328    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06329    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06330    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06331 }

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

Definition at line 2268 of file chan_iax2.c.

References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_sched_add(), ast_sched_del(), ast_test_flag, ast_tvadd(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, GAMMA, iax2_dropcount, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxdebug, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, jittershrinkrate, chan_iax2_pvt::last, match(), max_jitter_buffer, maxjitterbuffer, MEMORY_SIZE, min_jitter_buffer, iax_frame::retrans, chan_iax2_pvt::rxcore, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, unwrap_timestamp(), and update_jbsched().

Referenced by socket_read().

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

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

Definition at line 4678 of file chan_iax2.c.

References __send_command().

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

04679 {
04680    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04681 }

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

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

04700 {
04701    /* It is assumed that the callno has already been locked */
04702    iax2_predestroy_nolock(i->callno);
04703    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04704 }

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

Definition at line 4706 of file chan_iax2.c.

References __send_command().

Referenced by iax2_vnak(), and socket_read().

04707 {
04708    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04709 }

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

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

04684 {
04685    int res;
04686    ast_mutex_lock(&iaxsl[callno]);
04687    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04688    ast_mutex_unlock(&iaxsl[callno]);
04689    return res;
04690 }

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

Definition at line 4711 of file chan_iax2.c.

References __send_command().

Referenced by socket_read(), and try_transfer().

04712 {
04713    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04714 }

static int send_lagrq void *  data  )  [static]
 

Definition at line 803 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_LAGRQ, and send_command().

Referenced by find_callno(), and make_trunk().

00804 {
00805    int callno = (long)data;
00806    /* Ping only if it's real not if it's bridged */
00807    if (iaxs[callno]) {
00808 #ifdef BRIDGE_OPTIMIZATION
00809       if (!iaxs[callno]->bridgecallno)
00810 #endif      
00811          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
00812       return 1;
00813    } else
00814       return 0;
00815 }

static int send_packet struct iax_frame f  )  [static]
 

Definition at line 1491 of file chan_iax2.c.

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

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

01492 {
01493    int res;
01494    char iabuf[INET_ADDRSTRLEN];
01495    /* Called with iaxsl held */
01496    if (!iaxs[f->callno])
01497       return -1;
01498    if (option_debug > 2 && iaxdebug)
01499       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));
01500    /* Don't send if there was an error, but return error instead */
01501    if (!f->callno) {
01502       ast_log(LOG_WARNING, "Call number = %d\n", f->callno);
01503       return -1;
01504    }
01505    if (iaxs[f->callno]->error)
01506       return -1;
01507    if (f->transfer) {
01508       if (iaxdebug)
01509          iax_showframe(f, NULL, 0, &iaxs[f->callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01510       res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->transfer,
01511                sizeof(iaxs[f->callno]->transfer));
01512    } else {
01513       if (iaxdebug)
01514          iax_showframe(f, NULL, 0, &iaxs[f->callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01515       res = sendto(iaxs[f->callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[f->callno]->addr,
01516                sizeof(iaxs[f->callno]->addr));
01517    }
01518    if (res < 0) {
01519       if (option_debug && iaxdebug)
01520          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01521       handle_error();
01522    } else
01523       res = 0;
01524    return res;
01525 }

static int send_ping void *  data  )  [static]
 

Definition at line 777 of file chan_iax2.c.

References AST_FRAME_IAX, IAX_COMMAND_PING, and send_command().

Referenced by find_callno(), and make_trunk().

00778 {
00779    int callno = (long)data;
00780    /* Ping only if it's real, not if it's bridged */
00781    if (iaxs[callno]) {
00782 #ifdef BRIDGE_OPTIMIZATION
00783       if (!iaxs[callno]->bridgecallno)
00784 #endif
00785          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00786       return 1;
00787    } else
00788       return 0;
00789 }

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

Definition at line 6001 of file chan_iax2.c.

References iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax_frame::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().

06002 {
06003    int res = 0;
06004    struct iax_frame *fr;
06005    struct ast_iax2_meta_hdr *meta;
06006    struct ast_iax2_meta_trunk_hdr *mth;
06007    int calls = 0;
06008    
06009    /* Point to frame */
06010    fr = (struct iax_frame *)tpeer->trunkdata;
06011    /* Point to meta data */
06012    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06013    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06014    if (tpeer->trunkdatalen) {
06015       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06016       meta->zeros = 0;
06017       meta->metacmd = IAX_META_TRUNK;
06018       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06019          meta->cmddata = IAX_META_TRUNK_MINI;
06020       else
06021          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06022       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06023       /* And the rest of the ast_iax2 header */
06024       fr->direction = DIRECTION_OUTGRESS;
06025       fr->retrans = -1;
06026       fr->transfer = 0;
06027       /* Any appropriate call will do */
06028       fr->data = fr->afdata;
06029       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06030       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06031       calls = tpeer->calls;
06032 #if 0
06033       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));
06034 #endif      
06035       /* Reset transmit trunk side data */
06036       tpeer->trunkdatalen = 0;
06037       tpeer->calls = 0;
06038    }
06039    if (res < 0)
06040       return res;
06041    return calls;
06042 }

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

Definition at line 8678 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(), authdebug, autokill, build_peer(), build_user(), capability, cfg, channeltype, DEFAULT_MAXMS, defaultsockfd, delayreject, format, get_encrypt_methods(), global_rtautoclear, iax2_capability, iax2_dropcount, 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, jittershrinkrate, lagrq_time, language, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_jitter_buffer, max_reg_expire, maxauthreq, maxjitterbuffer, maxjitterinterps, min_jitter_buffer, min_reg_expire, ast_variable::name, iax2_peer::next, iax2_user::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, ping_time, portno, 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().

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

static void set_timing void   )  [static]
 

Definition at line 8661 of file chan_iax2.c.

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

Referenced by set_config().

08662 {
08663 #ifdef IAX_TRUNKING
08664    int bs = trunkfreq * 8;
08665    if (timingfd > -1) {
08666       if (
08667 #ifdef ZT_TIMERACK
08668          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08669 #endif         
08670          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08671          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08672    }
08673 #endif
08674 }

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

Definition at line 6333 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(), authdebug, authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_frame::data, ast_frame::datalen, decrypt_frame(), delayreject, iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_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, iax_ies::iax_unknown, iaxcompat, iaxdebug, iaxfrdup2(), iaxq, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, iax2_peer::lastms, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, ast_iax2_queue::lock, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax_ies::musiconhold, iax2_peer::name, NEW_ALLOW, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_verbose, iax_frame::oseqno, iax2_dpcache::peer, chan_iax2_pvt::peercallno, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), schedule_delivery(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax_ies::serviceident, 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, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros.

Referenced by network_thread(), and set_config().

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

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

Definition at line 6179 of file chan_iax2.c.

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

Referenced by socket_read().

06180 {
06181    pthread_t newthread;
06182    struct dpreq_data *dpr;
06183    dpr = malloc(sizeof(struct dpreq_data));
06184    if (dpr) {
06185       memset(dpr, 0, sizeof(struct dpreq_data));
06186       dpr->callno = callno;
06187       ast_copy_string(dpr->context, context, sizeof(dpr->context));
06188       ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06189       if (callerid)
06190          dpr->callerid = strdup(callerid);
06191       if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) {
06192          ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06193       }
06194    } else
06195       ast_log(LOG_WARNING, "Out of memory!\n");
06196 }

static int start_network_thread void   )  [static]
 

Definition at line 8083 of file chan_iax2.c.

References ast_pthread_create, netthreadid, and network_thread().

Referenced by load_module().

08084 {
08085    return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
08086 }

static int stop_stuff int  callno  )  [static]
 

Definition at line 5879 of file chan_iax2.c.

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

Referenced by socket_read().

05880 {
05881       if (iaxs[callno]->lagid > -1)
05882          ast_sched_del(sched, iaxs[callno]->lagid);
05883       iaxs[callno]->lagid = -1;
05884       if (iaxs[callno]->pingid > -1)
05885          ast_sched_del(sched, iaxs[callno]->pingid);
05886       iaxs[callno]->pingid = -1;
05887       if (iaxs[callno]->autoid > -1)
05888          ast_sched_del(sched, iaxs[callno]->autoid);
05889       iaxs[callno]->autoid = -1;
05890       if (iaxs[callno]->initid > -1)
05891          ast_sched_del(sched, iaxs[callno]->initid);
05892       iaxs[callno]->initid = -1;
05893       if (iaxs[callno]->authid > -1)
05894          ast_sched_del(sched, iaxs[callno]->authid);
05895       iaxs[callno]->authid = -1;
05896 #ifdef NEWJB
05897       if (iaxs[callno]->jbid > -1)
05898          ast_sched_del(sched, iaxs[callno]->jbid);
05899       iaxs[callno]->jbid = -1;
05900 #endif
05901       return 0;
05902 }

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

Definition at line 6052 of file chan_iax2.c.

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

Referenced by network_thread().

06053 {
06054    char buf[1024];
06055    int res;
06056    char iabuf[INET_ADDRSTRLEN];
06057    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06058    int processed = 0;
06059    int totalcalls = 0;
06060 #ifdef ZT_TIMERACK
06061    int x = 1;
06062 #endif
06063    struct timeval now;
06064    if (iaxtrunkdebug)
06065       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06066    gettimeofday(&now, NULL);
06067    if (events & AST_IO_PRI) {
06068 #ifdef ZT_TIMERACK
06069       /* Great, this is a timing interface, just call the ioctl */
06070       if (ioctl(fd, ZT_TIMERACK, &x)) 
06071          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06072       res = 0;
06073 #endif      
06074    } else {
06075       /* Read and ignore from the pseudo channel for timing */
06076       res = read(fd, buf, sizeof(buf));
06077       if (res < 1) {
06078          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06079          ast_mutex_unlock(&peerl.lock);
06080          return 1;
06081       }
06082    }
06083    /* For each peer that supports trunking... */
06084    ast_mutex_lock(&tpeerlock);
06085    tpeer = tpeers;
06086    while(tpeer) {
06087       processed++;
06088       res = 0;
06089       ast_mutex_lock(&tpeer->lock);
06090       /* We can drop a single tpeer per pass.  That makes all this logic
06091          substantially easier */
06092       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06093          /* Take it out of the list, but don't free it yet, because it
06094             could be in use */
06095          if (prev)
06096             prev->next = tpeer->next;
06097          else
06098             tpeers = tpeer->next;
06099          drop = tpeer;
06100       } else {
06101          res = send_trunk(tpeer, &now);
06102          if (iaxtrunkdebug)
06103             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);
06104       }     
06105       totalcalls += res;   
06106       res = 0;
06107       ast_mutex_unlock(&tpeer->lock);
06108       prev = tpeer;
06109       tpeer = tpeer->next;
06110    }
06111    ast_mutex_unlock(&tpeerlock);
06112    if (drop) {
06113       ast_mutex_lock(&drop->lock);
06114       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06115          because by the time they could get tpeerlock, we've already grabbed it */
06116       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));
06117       free(drop->trunkdata);
06118       ast_mutex_unlock(&drop->lock);
06119       ast_mutex_destroy(&drop->lock);
06120       free(drop);
06121       
06122    }
06123    if (iaxtrunkdebug)
06124       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06125    iaxtrunkdebug =0;
06126    return 1;
06127 }

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

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

01478 {
01479    int res;
01480    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01481                sizeof(*sin));
01482    if (res < 0) {
01483       if (option_debug)
01484          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01485       handle_error();
01486    } else
01487       res = 0;
01488    return res;
01489 }

static int try_firmware char *  s  )  [static]
 

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

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

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

Definition at line 5358 of file chan_iax2.c.

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

Referenced by socket_read().

05359 {
05360    int newcall = 0;
05361    char newip[256];
05362    struct iax_ie_data ied;
05363    struct sockaddr_in new;
05364    
05365    
05366    memset(&ied, 0, sizeof(ied));
05367    if (ies->apparent_addr)
05368       bcopy(ies->apparent_addr, &new, sizeof(new));
05369    if (ies->callno)
05370       newcall = ies->callno;
05371    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05372       ast_log(LOG_WARNING, "Invalid transfer request\n");
05373       return -1;
05374    }
05375    pvt->transfercallno = newcall;
05376    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05377    inet_aton(newip, &pvt->transfer.sin_addr);
05378    pvt->transfer.sin_family = AF_INET;
05379    pvt->transferring = TRANSFER_BEGIN;
05380    pvt->transferid = ies->transferid;
05381    if (ies->transferid)
05382       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05383    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05384    return 0; 
05385 }

static int uncompress_subclass unsigned char  csub  )  [static]
 

Definition at line 837 of file chan_iax2.c.

References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.

Referenced by decode_frame(), and socket_read().

00838 {
00839    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
00840    if (csub & IAX_FLAG_SC_LOG) {
00841       /* special case for 'compressed' -1 */
00842       if (csub == 0xff)
00843          return -1;
00844       else
00845          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
00846    }
00847    else
00848       return csub;
00849 }

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

References __unload_module(), ast_custom_function_unregister(), ast_mutex_destroy(), 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 3185 of file chan_iax2.c.

References ast_mutex_unlock(), and iaxsl.

Referenced by iax2_bridge().

03186 {
03187    ast_mutex_unlock(&iaxsl[callno1]);
03188    ast_mutex_unlock(&iaxsl[callno0]);
03189 }

static void unwrap_timestamp struct iax_frame fr  )  [static]
 

Definition at line 2151 of file chan_iax2.c.

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

Referenced by schedule_delivery().

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

static void update_jbsched struct chan_iax2_pvt pvt  )  [static]
 

Definition at line 2181 of file chan_iax2.c.

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

Referenced by get_from_jb(), and schedule_delivery().

02181                                                       {
02182     int when;
02183 
02184     when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02185 
02186     when = jb_next(pvt->jb) - when;
02187 
02188     if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02189 
02190     if(when <= 0) {
02191       /* XXX should really just empty until when > 0.. */
02192       when = 1;
02193     }
02194 
02195     pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt);
02196 }

static void update_max_nontrunk void   )  [static]
 

Definition at line 986 of file chan_iax2.c.

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

Referenced by find_callno(), and make_trunk().

00987 {
00988    int max = 1;
00989    int x;
00990    /* XXX Prolly don't need locks here XXX */
00991    for (x=1;x<TRUNK_CALL_START - 1; x++) {
00992       if (iaxs[x])
00993          max = x + 1;
00994    }
00995    maxnontrunkcall = max;
00996    if (option_debug && iaxdebug)
00997       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
00998 }

static void update_max_trunk void   )  [static]
 

Definition at line 972 of file chan_iax2.c.

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

Referenced by iax2_destroy(), and make_trunk().

00973 {
00974    int max = TRUNK_CALL_START;
00975    int x;
00976    /* XXX Prolly don't need locks here XXX */
00977    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
00978       if (iaxs[x])
00979          max = x + 1;
00980    }
00981    maxtrunkcall = max;
00982    if (option_debug && iaxdebug)
00983       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
00984 }

static int update_packet struct iax_frame f  )  [static]
 

Definition at line 1715 of file chan_iax2.c.

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

Referenced by attempt_transmit().

01716 {
01717    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
01718    struct ast_iax2_full_hdr *fh = f->data;
01719    /* Mark this as a retransmission */
01720    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
01721    /* Update iseqno */
01722    f->iseqno = iaxs[f->callno]->iseqno;
01723    fh->iseqno = f->iseqno;
01724    return 0;
01725 }

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

Definition at line 5706 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(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_MESSAGEDETAIL, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), LOG_NOTICE, LOG_WARNING, manager_event(), 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().

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

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

References usecnt.

09733 {
09734    return usecnt;
09735 }

static void vnak_retransmit int  callno,
int  last
[static]
 

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

05978 {
05979    struct iax_frame *f;
05980    ast_mutex_lock(&iaxq.lock);
05981    f = iaxq.head;
05982    while(f) {
05983       /* Send a copy immediately */
05984       if ((f->callno == callno) && iaxs[f->callno] &&
05985          (f->oseqno >= last)) {
05986          send_packet(f);
05987       }
05988       f = f->next;
05989    }
05990    ast_mutex_unlock(&iaxq.lock);
05991 }


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] [static]
 

Definition at line 225 of file chan_iax2.c.

Referenced by build_device(), build_gateway(), check_access(), find_callno(), mkintf(), set_config(), setup_zap(), and tds_log().

int amaflags = 0 [static]
 

Definition at line 226 of file chan_iax2.c.

Referenced by build_device(), build_gateway(), find_callno(), mkintf(), set_config(), and setup_zap().

int authdebug = 1 [static]
 

Definition at line 163 of file chan_iax2.c.

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

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 9522 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 9514 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 9506 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.

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

int iax2_dropcount = DEFAULT_DROP [static]
 

Definition at line 211 of file chan_iax2.c.

Referenced by schedule_delivery(), and set_config().

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

enum { ... } iax2_state
 

struct ast_switch iax2_switch [static]
 

Definition at line 9442 of file chan_iax2.c.

const struct ast_channel_tech iax2_tech [static]
 

Definition at line 753 of file chan_iax2.c.

char iax2_test_losspct_usage[] [static]
 

Initial value:

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

Definition at line 9530 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(), find_callno(), iax2_bridge(), iax2_do_debug(), iax2_do_register(), iax2_indicate(), iax2_no_debug(), iax2_send(), iax_debug_output(), raw_hangup(), schedule_delivery(), send_packet(), socket_read(), unwrap_timestamp(), update_max_nontrunk(), and update_max_trunk().

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

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

Referenced by iax_showframe().

ast_mutex_t iaxsl[IAX_MAX_CALLS] [static]
 

Definition at line 718 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(), delete_users(), 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 1846 of file chan_iax2.c.

int jittershrinkrate = 2 [static]
 

Definition at line 161 of file chan_iax2.c.

Referenced by schedule_delivery(), and set_config().

int lagrq_time = 10 [static]
 

Definition at line 153 of file chan_iax2.c.

Referenced by find_callno(), 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 719 of file chan_iax2.c.

Referenced by find_callno(), 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(), schedule_delivery(), 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(), schedule_delivery(), 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(), and update_max_nontrunk().

int maxtrunkcall = TRUNK_CALL_START [static]
 

Definition at line 154 of file chan_iax2.c.

Referenced by find_callno(), and update_max_trunk().

int min_jitter_buffer = MIN_JITTER_BUFFER [static]
 

Definition at line 432 of file chan_iax2.c.

Referenced by schedule_delivery(), and set_config().

int min_reg_expire [static]
 

Definition at line 173 of file chan_iax2.c.

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

struct ast_netsock_list* netsock [static]
 

Definition at line 178 of file chan_iax2.c.

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 9526 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 9518 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 9510 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]
 

Definition at line 7806 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 7808 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 find_callno(), 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().

char prune_realtime_usage[] [static]
 

Initial value:

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

Definition at line 9464 of file chan_iax2.c.

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

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

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 9456 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 9484 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 9498 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 9488 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 9460 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 9492 of file chan_iax2.c.

char show_prov_usage[] [static]
 

Definition at line 9472 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 9502 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 9452 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 9479 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 Sun Aug 6 15:06:00 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.2