Mon Mar 20 08:20:19 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 <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "../jitterbuf.h"

Go to the source code of this file.

Data Structures

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

Defines

#define CACHE_FLAG_CANEXIST   (1 << 2)
#define CACHE_FLAG_EXISTS   (1 << 0)
#define CACHE_FLAG_MATCHMORE   (1 << 7)
#define CACHE_FLAG_NONEXISTENT   (1 << 1)
#define CACHE_FLAG_PENDING   (1 << 3)
#define CACHE_FLAG_TIMEOUT   (1 << 4)
#define CACHE_FLAG_TRANSMITTED   (1 << 5)
#define CACHE_FLAG_UNKNOWN   (1 << 6)
#define CALLNO_TO_PTR(a)   ((void *)(unsigned long)(a))
#define DEBUG_SUPPORT
#define DEFAULT_DROP   3
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_FREQ_OK   60 * 1000
#define DEFAULT_MAXMS   2000
#define DEFAULT_RETRY_TIME   1000
#define DEFAULT_TRUNKDATA   640 * 10
#define FORMAT   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
#define FORMAT   "%-20.20s %-10.10s %-20.20s %8d %s\n"
#define FORMAT   "%-15.15s %-15d %-15d\n"
#define FORMAT   "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
#define FORMAT   "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
#define FORMAT2   "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
#define FORMAT2   "%-20.20s %-10.10s %-20.20s %8.8s %s\n"
#define FORMAT2   "%-15.15s %-15.15s %-15.15s\n"
#define FORMAT2   "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
#define FORMAT2   "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
#define FORMATB   "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
#define 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)
}
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

int __do_deliver (void *data)
int __iax2_show_peers (int manager, int fd, int argc, char *argv[])
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)
int __unload_module (void)
int apply_context (struct iax2_context *con, char *context)
int ast_cli_netstats (int fd, int limit_fmt)
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)
int attempt_transmit (void *data)
int auth_fail (int callno, int failcode)
int auth_reject (void *nothing)
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)
int authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, char *override, char *okey)
int authenticate_request (struct chan_iax2_pvt *p)
int authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies)
int auto_congest (void *nothing)
int auto_hangup (void *nothing)
iax2_contextbuild_context (char *context)
void build_enc_keys (const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
iax2_peerbuild_peer (const char *name, struct ast_variable *v, int temponly)
iax2_userbuild_user (const char *name, struct ast_variable *v, int temponly)
int cache_get_callno_locked (const char *data)
unsigned int calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset)
unsigned int calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
unsigned int calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
int check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
int check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
int check_srcaddr (struct sockaddr *sa, socklen_t salen)
int complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
char * complete_iax2_show_peer (char *line, char *word, int pos, int state)
int complete_transfer (int callno, struct iax_ies *ies)
unsigned char compress_subclass (int subclass)
void construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
int create_addr (const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
int decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
int decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
void delete_users (void)
char * description ()
 Provides a description of the module.
void destroy_firmware (struct iax_firmware *cur)
void destroy_peer (struct iax2_peer *peer)
void destroy_user (struct iax2_user *user)
void dp_lookup (int callno, char *context, char *callednum, char *callerid, int skiplock)
void * dp_lookup_thread (void *data)
int encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
int expire_registry (void *data)
iax2_dpcachefind_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
int find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd)
iax2_peerfind_peer (const char *name, int realtime)
iax2_trunk_peerfind_tpeer (struct sockaddr_in *sin, int fd)
unsigned int fix_peerts (struct timeval *tv, int callno, unsigned int ts)
void free_context (struct iax2_context *con)
char * function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
int get_auth_methods (char *value)
int get_encrypt_methods (const char *s)
int get_from_jb (void *p)
int handle_error (void)
int iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno)
 Acknowledgment received for OUR registration.
int iax2_answer (struct ast_channel *c)
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)
int iax2_call (struct ast_channel *c, char *dest, int timeout)
int iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
unsigned int iax2_datetime (char *tz)
void iax2_destroy (int callno)
void iax2_destroy_nolock (int callno)
int iax2_devicestate (void *data)
int iax2_digit (struct ast_channel *c, char digit)
int iax2_do_debug (int fd, int argc, char *argv[])
int iax2_do_jb_debug (int fd, int argc, char *argv[])
int iax2_do_register (struct iax2_registry *reg)
int iax2_do_register_s (void *data)
int iax2_do_trunk_debug (int fd, int argc, char *argv[])
void iax2_dprequest (struct iax2_dpcache *dp, int callno)
int iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, int newstack, const char *data)
int iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
int iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan)
void iax2_frame_free (struct iax_frame *fr)
int iax2_getpeername (struct sockaddr_in sin, char *host, int len, int lockpeer)
int iax2_getpeertrunk (struct sockaddr_in sin)
int iax2_hangup (struct ast_channel *c)
int iax2_indicate (struct ast_channel *c, int condition)
int iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
int iax2_no_debug (int fd, int argc, char *argv[])
int iax2_no_jb_debug (int fd, int argc, char *argv[])
int iax2_no_trunk_debug (int fd, int argc, char *argv[])
int iax2_poke_noanswer (void *data)
int iax2_poke_peer (struct iax2_peer *peer, int heldcall)
int iax2_poke_peer_s (void *data)
int iax2_predestroy (int callno)
int iax2_predestroy_nolock (int callno)
int iax2_prov_app (struct ast_channel *chan, void *data)
int iax2_prov_cmd (int fd, int argc, char *argv[])
char * iax2_prov_complete_template_3rd (char *line, char *word, int pos, int state)
int iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
int iax2_prune_realtime (int fd, int argc, char *argv[])
int iax2_queue_frame (int callno, struct ast_frame *f)
ast_frameiax2_read (struct ast_channel *c)
int iax2_register (char *value, int lineno)
int iax2_reload (int fd, int argc, char *argv[])
ast_channeliax2_request (const char *type, int format, void *data, int *cause)
int iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
int iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen)
int iax2_sendimage (struct ast_channel *c, struct ast_frame *img)
int iax2_sendtext (struct ast_channel *c, const char *text)
int iax2_set_jitter (int fd, int argc, char *argv[])
int iax2_setoption (struct ast_channel *c, int option, void *data, int datalen)
int iax2_show_cache (int fd, int argc, char *argv[])
int iax2_show_channels (int fd, int argc, char *argv[])
int iax2_show_firmware (int fd, int argc, char *argv[])
int iax2_show_netstats (int fd, int argc, char *argv[])
int iax2_show_peer (int fd, int argc, char *argv[])
int iax2_show_peers (int fd, int argc, char *argv[])
int iax2_show_registry (int fd, int argc, char *argv[])
int iax2_show_stats (int fd, int argc, char *argv[])
int iax2_show_users (int fd, int argc, char *argv[])
int iax2_start_transfer (unsigned short callno0, unsigned short callno1)
int iax2_test_losspct (int fd, int argc, char *argv[])
int iax2_transfer (struct ast_channel *c, const char *dest)
int iax2_transmit (struct iax_frame *fr)
int iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now)
int iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr)
int iax2_vnak (int callno)
int iax2_write (struct ast_channel *c, struct ast_frame *f)
int iax_check_version (char *dev)
void iax_debug_output (const char *data)
void iax_error_output (const char *data)
int iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
int iax_park (struct ast_channel *chan1, struct ast_channel *chan2)
void * iax_park_thread (void *stuff)
iax_frameiaxfrdup2 (struct iax_frame *fr)
void jb_debug_output (const char *fmt,...)
void jb_error_output (const char *fmt,...)
void jb_warning_output (const char *fmt,...)
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
void lock_both (unsigned short callno0, unsigned short callno1)
int make_trunk (unsigned short callno, int locked)
int manager_iax2_show_netstats (struct mansession *s, struct message *m)
int manager_iax2_show_peers (struct mansession *s, struct message *m)
int match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
void memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
void memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
void merge_encryption (struct chan_iax2_pvt *p, unsigned int enc)
void * network_thread (void *ignore)
chan_iax2_pvtnew_iax (struct sockaddr_in *sin, int lockpeer, const char *host)
void parse_dial_string (char *data, struct parsed_dial_string *pds)
 Parses an IAX dial string into its component parts.
int peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr)
int peer_status (struct iax2_peer *peer, char *status, int statuslen)
 peer_status: Report Peer status in character string
void prune_peers (void)
void prune_users (void)
int raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
iax2_peerrealtime_peer (const char *peername, struct sockaddr_in *sin)
void realtime_update_peer (const char *peername, struct sockaddr_in *sin)
iax2_userrealtime_user (const char *username)
void reg_source_db (struct iax2_peer *p)
void register_peer_exten (struct iax2_peer *peer, int onoff)
int register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies)
 Verify inbound registration.
int registry_authrequest (char *name, int callno)
int registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin)
char * regstate2str (int regstate)
int reload (void)
 Reload stuff.
int reload_config (void)
void reload_firmware (void)
void save_rr (struct iax_frame *fr, struct iax_ies *ies)
int schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
int send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
int send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
int send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int)
int send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int)
int send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int)
int send_lagrq (void *data)
int send_packet (struct iax_frame *f)
int send_ping (void *data)
int send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now)
int set_config (char *config_file, int reload)
void set_timing (void)
int socket_read (int *id, int fd, short events, void *cbdata)
void spawn_dp_lookup (int callno, char *context, char *callednum, char *callerid)
int start_network_thread (void)
int stop_stuff (int callno)
int timing_read (int *id, int fd, short events, void *cbdata)
int transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
int try_firmware (char *s)
int try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies)
int uncompress_subclass (unsigned char csub)
int unload_module ()
 Cleanup all module structures, sockets, etc.
void unlock_both (unsigned short callno0, unsigned short callno1)
void unwrap_timestamp (struct iax_frame *fr)
void update_jbsched (struct chan_iax2_pvt *pvt)
void update_max_nontrunk (void)
void update_max_trunk (void)
int update_packet (struct iax_frame *f)
int update_registry (char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
int usecount ()
 Provides a usecount.
void vnak_retransmit (int callno, int last)

Variables

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

#define CACHE_FLAG_EXISTS   (1 << 0)
 

Extension exists

Definition at line 622 of file chan_iax2.c.

#define CACHE_FLAG_MATCHMORE   (1 << 7)
 

Matchmore

Definition at line 636 of file chan_iax2.c.

#define CACHE_FLAG_NONEXISTENT   (1 << 1)
 

Extension is nonexistent

Definition at line 624 of file chan_iax2.c.

#define CACHE_FLAG_PENDING   (1 << 3)
 

Waiting to hear back response

Definition at line 628 of file chan_iax2.c.

#define CACHE_FLAG_TIMEOUT   (1 << 4)
 

Timed out

Definition at line 630 of file chan_iax2.c.

#define CACHE_FLAG_TRANSMITTED   (1 << 5)
 

Request transmitted

Definition at line 632 of file chan_iax2.c.

#define CACHE_FLAG_UNKNOWN   (1 << 6)
 

Timeout

Definition at line 634 of file chan_iax2.c.

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

Definition at line 122 of file chan_iax2.c.

Referenced by ast_iax2_new(), and iax2_call().

#define DEBUG_SUPPORT
 

Definition at line 131 of file chan_iax2.c.

#define DEFAULT_DROP   3
 

Definition at line 126 of file chan_iax2.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000
 

Definition at line 202 of file chan_iax2.c.

Referenced by handle_response_peerpoke(), and sip_poke_noanswer().

#define DEFAULT_FREQ_OK   60 * 1000
 

Definition at line 201 of file chan_iax2.c.

Referenced by handle_response_peerpoke().

#define DEFAULT_MAXMS   2000
 

Definition at line 200 of file chan_iax2.c.

#define DEFAULT_RETRY_TIME   1000
 

Definition at line 124 of file chan_iax2.c.

#define DEFAULT_TRUNKDATA   640 * 10
 

40ms, uncompressed linear * 10 channels

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

Referenced by iax2_trunk_queue().

#define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
 

Definition at line 185 of file chan_iax2.c.

Referenced by cache_get_callno_locked().

#define IAX_CAPABILITY_LOWBANDWIDTH
 

Value:

(IAX_CAPABILITY_MEDBANDWIDTH &   \
                     ~AST_FORMAT_G726 &   \
                     ~AST_FORMAT_ADPCM)

Definition at line 192 of file chan_iax2.c.

#define IAX_CAPABILITY_LOWFREE
 

Value:

(IAX_CAPABILITY_LOWBANDWIDTH &      \
                      ~AST_FORMAT_G723_1)

Definition at line 196 of file chan_iax2.c.

#define IAX_CAPABILITY_MEDBANDWIDTH
 

Value:

Definition at line 187 of file chan_iax2.c.

#define IPTOS_MINCOST   0x02
 

Definition at line 105 of file chan_iax2.c.

#define MAX_JITTER_BUFFER   50
 

Definition at line 413 of file chan_iax2.c.

#define MAX_RETRY_TIME   10000
 

Definition at line 411 of file chan_iax2.c.

#define MAX_TIMESTAMP_SKEW   160
 

maximum difference between actual and predicted ts for sending

Definition at line 419 of file chan_iax2.c.

#define MAX_TRUNKDATA   640 * 200
 

40ms, uncompressed linear * 200 channels

Definition at line 417 of file chan_iax2.c.

Referenced by timing_read().

#define MEMORY_SIZE   100
 

Definition at line 125 of file chan_iax2.c.

Referenced by schedule_delivery().

#define MIN_JITTER_BUFFER   10
 

Definition at line 414 of file chan_iax2.c.

#define MIN_RETRY_TIME   100
 

Definition at line 410 of file chan_iax2.c.

#define MIN_REUSE_TIME   60
 

Definition at line 133 of file chan_iax2.c.

#define NEW_ALLOW   1
 

Definition at line 941 of file chan_iax2.c.

#define NEW_FORCE   2
 

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

Referenced by socket_read().

#define NEWJB
 

Definition at line 98 of file chan_iax2.c.

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

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

Referenced by update_max_nontrunk().

#define TS_GAP_FOR_JB_RESYNC   5000
 

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

00232      {
00233    IAX_STATE_STARTED =     (1 << 0),
00234    IAX_STATE_AUTHENTICATED =  (1 << 1),
00235    IAX_STATE_TBD =      (1 << 2)
00236 } 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

Definition at line 243 of file chan_iax2.c.

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

00375                    {
00376    REG_STATE_UNREGISTERED = 0,
00377    REG_STATE_REGSENT,
00378    REG_STATE_AUTHSENT,
00379    REG_STATE_REGISTERED,
00380    REG_STATE_REJECTED,
00381    REG_STATE_TIMEOUT,
00382    REG_STATE_NOAUTH
00383 };

enum iax_transfer_state
 

Enumeration values:
TRANSFER_NONE 
TRANSFER_BEGIN 
TRANSFER_READY 
TRANSFER_RELEASED 
TRANSFER_PASSTHROUGH 

Definition at line 385 of file chan_iax2.c.

00385                         {
00386    TRANSFER_NONE = 0,
00387    TRANSFER_BEGIN,
00388    TRANSFER_READY,
00389    TRANSFER_RELEASED,
00390    TRANSFER_PASSTHROUGH
00391 };


Function Documentation

int __do_deliver void *  data  )  [static]
 

Definition at line 1407 of file chan_iax2.c.

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

Referenced by get_from_jb(), and schedule_delivery().

01408 {
01409    /* Just deliver the packet by using queueing.  This is called by
01410      the IAX thread with the iaxsl lock held. */
01411    struct iax_frame *fr = data;
01412    fr->retrans = -1;
01413    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01414       iax2_queue_frame(fr->callno, &fr->af);
01415    /* Free our iax frame */
01416    iax2_frame_free(fr);
01417    /* And don't run again */
01418    return 0;
01419 }

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

Definition at line 4179 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, and iax2_peer::username.

Referenced by iax2_show_peers(), and manager_iax2_show_peers().

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

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

04647 {
04648    struct ast_frame f;
04649    f.frametype = type;
04650    f.subclass = command;
04651    f.datalen = datalen;
04652    f.samples = 0;
04653    f.mallocd = 0;
04654    f.offset = 0;
04655    f.src = (char *)__FUNCTION__;
04656    f.data = (char *)data;
04657    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04658 }

int __unload_module void   )  [static]
 

Definition at line 9499 of file chan_iax2.c.

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

Referenced by load_module(), and unload_module().

09500 {
09501    int x;
09502    /* Cancel the network thread, close the net socket */
09503    if (netthreadid != AST_PTHREADT_NULL) {
09504       pthread_cancel(netthreadid);
09505       pthread_join(netthreadid, NULL);
09506    }
09507    ast_netsock_release(netsock);
09508    for (x=0;x<IAX_MAX_CALLS;x++)
09509       if (iaxs[x])
09510          iax2_destroy(x);
09511    ast_manager_unregister( "IAXpeers" );
09512    ast_manager_unregister( "IAXnetstats" );
09513    ast_unregister_application(papp);
09514    ast_cli_unregister_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09515    ast_unregister_switch(&iax2_switch);
09516    ast_channel_unregister(&iax2_tech);
09517    delete_users();
09518    iax_provision_unload();
09519    sched_context_destroy(sched);
09520    return 0;
09521 }

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

Definition at line 4698 of file chan_iax2.c.

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

Referenced by check_access().

04699 {
04700    while(con) {
04701       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04702          return -1;
04703       con = con->next;
04704    }
04705    return 0;
04706 }

int ast_cli_netstats int  fd,
int  limit_fmt
[static]
 

Definition at line 4465 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, chan_iax2_pvt::bridgecallno, 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_USEJITTERBUF, iaxs, 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().

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

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

Definition at line 3390 of file chan_iax2.c.

References ast_channel::accountcode, chan_iax2_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, ast_best_codec(), ast_channel_alloc(), ast_hangup(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), ast_setstate(), ast_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, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, chan_iax2_pvt::cid_name, ast_callerid::cid_num, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_tns, ast_callerid::cid_ton, chan_iax2_pvt::context, ast_channel::context, chan_iax2_pvt::dnid, chan_iax2_pvt::exten, ast_channel::exten, chan_iax2_pvt::host, iaxs, 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, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.

Referenced by iax2_request(), and socket_read().

03391 {
03392    struct ast_channel *tmp;
03393    struct chan_iax2_pvt *i;
03394    struct ast_variable *v = NULL;
03395 
03396    /* Don't hold call lock */
03397    ast_mutex_unlock(&iaxsl[callno]);
03398    tmp = ast_channel_alloc(1);
03399    ast_mutex_lock(&iaxsl[callno]);
03400    i = iaxs[callno];
03401    if (i && tmp) {
03402       tmp->tech = &iax2_tech;
03403       snprintf(tmp->name, sizeof(tmp->name), "IAX2/%s-%d", i->host, i->callno);
03404       tmp->type = channeltype;
03405       /* We can support any format by default, until we get restricted */
03406       tmp->nativeformats = capability;
03407       tmp->readformat = ast_best_codec(capability);
03408       tmp->writeformat = ast_best_codec(capability);
03409       tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03410 
03411       if (!ast_strlen_zero(i->cid_num))
03412          tmp->cid.cid_num = strdup(i->cid_num);
03413       if (!ast_strlen_zero(i->cid_name))
03414          tmp->cid.cid_name = strdup(i->cid_name);
03415       if (!ast_strlen_zero(i->ani))
03416          tmp->cid.cid_ani = strdup(i->ani);
03417       if (!ast_strlen_zero(i->language))
03418          ast_copy_string(tmp->language, i->language, sizeof(tmp->language));
03419       if (!ast_strlen_zero(i->dnid))
03420          tmp->cid.cid_dnid = strdup(i->dnid);
03421       tmp->cid.cid_pres = i->calling_pres;
03422       tmp->cid.cid_ton = i->calling_ton;
03423       tmp->cid.cid_tns = i->calling_tns;
03424       if (!ast_strlen_zero(i->accountcode))
03425          ast_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
03426       if (i->amaflags)
03427          tmp->amaflags = i->amaflags;
03428       ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03429       ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03430       tmp->adsicpe = i->peeradsicpe;
03431       i->owner = tmp;
03432       i->capability = capability;
03433       ast_setstate(tmp, state);
03434       ast_mutex_lock(&usecnt_lock);
03435       usecnt++;
03436       ast_mutex_unlock(&usecnt_lock);
03437       ast_update_use_count();
03438       if (state != AST_STATE_DOWN) {
03439          if (ast_pbx_start(tmp)) {
03440             ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03441             ast_hangup(tmp);
03442             tmp = NULL;
03443          }
03444       }
03445       for (v = i->vars ; v ; v = v->next)
03446          pbx_builtin_setvar_helper(tmp,v->name,v->value);
03447       
03448    }
03449    return tmp;
03450 }

AST_MUTEX_DEFINE_STATIC dpcache_lock   ) 
 

AST_MUTEX_DEFINE_STATIC tpeerlock   ) 
 

AST_MUTEX_DEFINE_STATIC usecnt_lock   ) 
 

int attempt_transmit void *  data  )  [static]
 

Definition at line 1693 of file chan_iax2.c.

References iax_frame::af, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), attempt_transmit(), 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, iaxq, iaxs, iaxsl, ast_iax2_queue::lock, LOG_WARNING, iax_frame::next, iax_frame::oseqno, chan_iax2_pvt::owner, iax_frame::prev, iax2_registry::refresh, chan_iax2_pvt::reg, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_command(), send_packet(), ast_frame::subclass, ast_iax2_queue::tail, iax_frame::transfer, iax_frame::ts, and update_packet().

Referenced by attempt_transmit(), and network_thread().

01694 {
01695    /* Attempt to transmit the frame to the remote peer...
01696       Called without iaxsl held. */
01697    struct iax_frame *f = data;
01698    int freeme=0;
01699    int callno = f->callno;
01700    char iabuf[INET_ADDRSTRLEN];
01701    /* Make sure this call is still active */
01702    if (callno) 
01703       ast_mutex_lock(&iaxsl[callno]);
01704    if ((f->callno) && iaxs[f->callno]) {
01705       if ((f->retries < 0) /* Already ACK'd */ ||
01706           (f->retries >= max_retries) /* Too many attempts */) {
01707             /* Record an error if we've transmitted too many times */
01708             if (f->retries >= max_retries) {
01709                if (f->transfer) {
01710                   /* Transfer timeout */
01711                   send_command(iaxs[f->callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
01712                } else if (f->final) {
01713                   if (f->final) 
01714                      iax2_destroy_nolock(f->callno);
01715                } else {
01716                   if (iaxs[f->callno]->owner)
01717                      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);
01718                   iaxs[f->callno]->error = ETIMEDOUT;
01719                   if (iaxs[f->callno]->owner) {
01720                      struct ast_frame fr = { 0, };
01721                      /* Hangup the fd */
01722                      fr.frametype = AST_FRAME_CONTROL;
01723                      fr.subclass = AST_CONTROL_HANGUP;
01724                      iax2_queue_frame(f->callno, &fr);
01725                      /* Remember, owner could disappear */
01726                      if (iaxs[f->callno]->owner)
01727                         iaxs[f->callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
01728                   } else {
01729                      if (iaxs[f->callno]->reg) {
01730                         memset(&iaxs[f->callno]->reg->us, 0, sizeof(iaxs[f->callno]->reg->us));
01731                         iaxs[f->callno]->reg->regstate = REG_STATE_TIMEOUT;
01732                         iaxs[f->callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
01733                      }
01734                      iax2_destroy_nolock(f->callno);
01735                   }
01736                }
01737 
01738             }
01739             freeme++;
01740       } else {
01741          /* Update it if it needs it */
01742          update_packet(f);
01743          /* Attempt transmission */
01744          send_packet(f);
01745          f->retries++;
01746          /* Try again later after 10 times as long */
01747          f->retrytime *= 10;
01748          if (f->retrytime > MAX_RETRY_TIME)
01749             f->retrytime = MAX_RETRY_TIME;
01750          /* Transfer messages max out at one second */
01751          if (f->transfer && (f->retrytime > 1000))
01752             f->retrytime = 1000;
01753          f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
01754       }
01755    } else {
01756       /* Make sure it gets freed */
01757       f->retries = -1;
01758       freeme++;
01759    }
01760    if (callno)
01761       ast_mutex_unlock(&iaxsl[callno]);
01762    /* Do not try again */
01763    if (freeme) {
01764       /* Don't attempt delivery, just remove it from the queue */
01765       ast_mutex_lock(&iaxq.lock);
01766       if (f->prev) 
01767          f->prev->next = f->next;
01768       else
01769          iaxq.head = f->next;
01770       if (f->next)
01771          f->next->prev = f->prev;
01772       else
01773          iaxq.tail = f->prev;
01774       iaxq.count--;
01775       ast_mutex_unlock(&iaxq.lock);
01776       f->retrans = -1;
01777       /* Free the IAX frame */
01778       iax2_frame_free(f);
01779    }
01780    return 0;
01781 }

int auth_fail int  callno,
int  failcode
[static]
 

Definition at line 5854 of file chan_iax2.c.

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

Referenced by socket_read().

05855 {
05856    /* Schedule sending the authentication failure in one second, to prevent
05857       guessing */
05858    ast_mutex_lock(&iaxsl[callno]);
05859    iaxs[callno]->authfail = failcode;
05860    if (delayreject) {
05861       ast_mutex_lock(&iaxsl[callno]);
05862       if (iaxs[callno]->authid > -1)
05863          ast_sched_del(sched, iaxs[callno]->authid);
05864       iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05865       ast_mutex_unlock(&iaxsl[callno]);
05866    } else
05867       auth_reject((void *)(long)callno);
05868    ast_mutex_unlock(&iaxsl[callno]);
05869    return 0;
05870 }

int auth_reject void *  nothing  )  [static]
 

Definition at line 5832 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::authfail, chan_iax2_pvt::authid, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().

Referenced by auth_fail().

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

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 5162 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_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, key(), LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().

Referenced by authenticate_reply(), process_message(), and registry_rerequest().

05163 {
05164    int res = -1;
05165    int x;
05166    char iabuf[INET_ADDRSTRLEN];
05167    if (!ast_strlen_zero(keyn)) {
05168       if (!(authmethods & IAX_AUTH_RSA)) {
05169          if (ast_strlen_zero(secret)) 
05170             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));
05171       } else if (ast_strlen_zero(challenge)) {
05172          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05173       } else {
05174          char sig[256];
05175          struct ast_key *key;
05176          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05177          if (!key) {
05178             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05179          } else {
05180             if (ast_sign(key, challenge, sig)) {
05181                ast_log(LOG_NOTICE, "Unable to sign challenge withy key\n");
05182                res = -1;
05183             } else {
05184                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05185                res = 0;
05186             }
05187          }
05188       }
05189    } 
05190    /* Fall back */
05191    if (res && !ast_strlen_zero(secret)) {
05192       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05193          struct MD5Context md5;
05194          unsigned char digest[16];
05195          char digres[128];
05196          MD5Init(&md5);
05197          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05198          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05199          MD5Final(digest, &md5);
05200          /* If they support md5, authenticate with it.  */
05201          for (x=0;x<16;x++)
05202             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05203          if (ecx && dcx)
05204             build_enc_keys(digest, ecx, dcx);
05205          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05206          res = 0;
05207       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05208          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05209          res = 0;
05210       } else
05211          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);
05212    }
05213    return res;
05214 }

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

Definition at line 5216 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, chan_iax2_pvt::challenge, iax_ies::challenge, chan_iax2_pvt::dcx, destroy_peer(), chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_ies::encmethods, 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, chan_iax2_pvt::peer, 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().

05217 {
05218    struct iax2_peer *peer;
05219    /* Start pessimistic */
05220    int res = -1;
05221    int authmethods = 0;
05222    struct iax_ie_data ied;
05223    
05224    memset(&ied, 0, sizeof(ied));
05225    
05226    if (ies->username)
05227       ast_copy_string(p->username, ies->username, sizeof(p->username));
05228    if (ies->challenge)
05229       ast_copy_string(p->challenge, ies->challenge, sizeof(p->challenge));
05230    if (ies->authmethods)
05231       authmethods = ies->authmethods;
05232    if (authmethods & IAX_AUTH_MD5)
05233       merge_encryption(p, ies->encmethods);
05234    else
05235       p->encmethods = 0;
05236 
05237    /* Check for override RSA authentication first */
05238    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05239       /* Normal password authentication */
05240       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05241    } else {
05242       ast_mutex_lock(&peerl.lock);
05243       peer = peerl.peers;
05244       while(peer) {
05245          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05246                         /* No peer specified at our end, or this is the peer */
05247           && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05248                         /* No username specified in peer rule, or this is the right username */
05249           && (!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)))
05250                         /* No specified host, or this is our host */
05251          ) {
05252             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05253             if (!res)
05254                break;   
05255          }
05256          peer = peer->next;
05257       }
05258       ast_mutex_unlock(&peerl.lock);
05259       if (!peer) {
05260          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05261             that we're trying to authenticate *to* a realtime peer */
05262          if ((peer = realtime_peer(p->peer, NULL))) {
05263             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05264             if (ast_test_flag(peer, IAX_TEMPONLY))
05265                destroy_peer(peer);
05266          }
05267       }
05268    }
05269    if (ies->encmethods)
05270       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05271    if (!res)
05272       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05273    return res;
05274 }

int authenticate_request struct chan_iax2_pvt p  )  [static]
 

Definition at line 4933 of file chan_iax2.c.

References AST_FRAME_IAX, ast_set_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREQ, IAX_ENCRYPTED, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, send_command(), and chan_iax2_pvt::username.

Referenced by socket_read().

04934 {
04935    struct iax_ie_data ied;
04936    int res;
04937    memset(&ied, 0, sizeof(ied));
04938    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
04939    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
04940       snprintf(p->challenge, sizeof(p->challenge), "%d", rand());
04941       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
04942    }
04943    if (p->encmethods)
04944       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
04945    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
04946    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
04947    if (p->encmethods)
04948       ast_set_flag(p, IAX_ENCRYPTED);
04949    return res;
04950 }

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

Definition at line 4952 of file chan_iax2.c.

References ast_check_signature, ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, key(), LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, chan_iax2_pvt::state, and strsep().

Referenced by socket_read().

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

int auto_congest void *  nothing  )  [static]
 

Definition at line 2827 of file chan_iax2.c.

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

Referenced by iax2_call().

02828 {
02829    int callno = PTR_TO_CALLNO(nothing);
02830    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02831    ast_mutex_lock(&iaxsl[callno]);
02832    if (iaxs[callno]) {
02833       iaxs[callno]->initid = -1;
02834       iax2_queue_frame(callno, &f);
02835       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02836    }
02837    ast_mutex_unlock(&iaxsl[callno]);
02838    return 0;
02839 }

int auto_hangup void *  nothing  )  [static]
 

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

Referenced by iax2_dprequest(), and iax2_provision().

05873 {
05874    /* Called from IAX thread only, without iaxs lock */
05875    int callno = (int)(long)(nothing);
05876    struct iax_ie_data ied;
05877    ast_mutex_lock(&iaxsl[callno]);
05878    if (iaxs[callno]) {
05879       iaxs[callno]->autoid = -1;
05880       memset(&ied, 0, sizeof(ied));
05881       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05882       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05883       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05884    }
05885    ast_mutex_unlock(&iaxsl[callno]);
05886    return 0;
05887 }

struct iax2_context* build_context char *  context  )  [static]
 

Definition at line 7998 of file chan_iax2.c.

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

Referenced by build_user().

07999 {
08000    struct iax2_context *con = malloc(sizeof(struct iax2_context));
08001    if (con) {
08002       ast_copy_string(con->context, context, sizeof(con->context));
08003       con->next = NULL;
08004    }
08005    return con;
08006 }

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

Definition at line 3780 of file chan_iax2.c.

References aes_decrypt_key128(), and aes_encrypt_key128().

Referenced by authenticate(), and decrypt_frame().

03781 {
03782    aes_encrypt_key128(digest, ecx);
03783    aes_decrypt_key128(digest, dcx);
03784 }

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

Definition at line 8108 of file chan_iax2.c.

References iax2_peer::addr, 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(), iax2_peer::authmethods, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, free, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, ast_peer_list::lock, LOG_WARNING, iax2_peer::mailbox, malloc, iax2_peer::mask, iax2_peer::maxms, ast_variable::name, name, iax2_peer::name, ast_variable::next, iax2_peer::next, iax2_peer::outkey, peer_set_srcaddr(), iax2_peer::peercontext, peerl, ast_peer_list::peers, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, iax2_peer::regexten, sched, iax2_peer::secret, iax2_peer::smoothing, iax2_peer::sockfd, timingfd, iax2_peer::username, ast_variable::value, and iax2_peer::zonetag.

08109 {
08110    struct iax2_peer *peer;
08111    struct iax2_peer *prev;
08112    struct ast_ha *oldha = NULL;
08113    int maskfound=0;
08114    int found=0;
08115    prev = NULL;
08116    ast_mutex_lock(&peerl.lock);
08117    if (!temponly) {
08118       peer = peerl.peers;
08119       while(peer) {
08120          if (!strcmp(peer->name, name)) { 
08121             break;
08122          }
08123          prev = peer;
08124          peer = peer->next;
08125       }
08126    } else
08127       peer = NULL;   
08128    if (peer) {
08129       found++;
08130       oldha = peer->ha;
08131       peer->ha = NULL;
08132       /* Already in the list, remove it and it will be added back (or FREE'd) */
08133       if (prev) {
08134          prev->next = peer->next;
08135       } else {
08136          peerl.peers = peer->next;
08137       }
08138       ast_mutex_unlock(&peerl.lock);
08139    } else {
08140       ast_mutex_unlock(&peerl.lock);
08141       peer = malloc(sizeof(struct iax2_peer));
08142       if (peer) {
08143          memset(peer, 0, sizeof(struct iax2_peer));
08144          peer->expire = -1;
08145          peer->pokeexpire = -1;
08146          peer->sockfd = defaultsockfd;
08147       }
08148    }
08149    if (peer) {
08150       ast_copy_flags(peer, &globalflags, IAX_MESSAGEDETAIL | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08151       peer->encmethods = iax2_encryption;
08152       peer->secret[0] = '\0';
08153       if (!found) {
08154          ast_copy_string(peer->name, name, sizeof(peer->name));
08155          peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08156          peer->expiry = min_reg_expire;
08157       }
08158       peer->prefs = prefs;
08159       peer->capability = iax2_capability;
08160       peer->smoothing = 0;
08161       peer->pokefreqok = DEFAULT_FREQ_OK;
08162       peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08163       peer->context[0] = '\0';
08164       peer->peercontext[0] = '\0';
08165       while(v) {
08166          if (!strcasecmp(v->name, "secret")) {
08167             if (!ast_strlen_zero(peer->secret)) {
08168                strncpy(peer->secret + strlen(peer->secret), ";", sizeof(peer->secret)-strlen(peer->secret) - 1);
08169                strncpy(peer->secret + strlen(peer->secret), v->value, sizeof(peer->secret)-strlen(peer->secret) - 1);
08170             } else
08171                ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
08172          } else if (!strcasecmp(v->name, "mailbox")) {
08173             ast_copy_string(peer->mailbox, v->value, sizeof(peer->mailbox));
08174          } else if (!strcasecmp(v->name, "dbsecret")) {
08175             ast_copy_string(peer->dbsecret, v->value, sizeof(peer->dbsecret));
08176          } else if (!strcasecmp(v->name, "mailboxdetail")) {
08177             ast_set2_flag(peer, ast_true(v->value), IAX_MESSAGEDETAIL); 
08178          } else if (!strcasecmp(v->name, "trunk")) {
08179             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
08180             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08181                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08182                ast_clear_flag(peer, IAX_TRUNK);
08183             }
08184          } else if (!strcasecmp(v->name, "auth")) {
08185             peer->authmethods = get_auth_methods(v->value);
08186          } else if (!strcasecmp(v->name, "encryption")) {
08187             peer->encmethods = get_encrypt_methods(v->value);
08188          } else if (!strcasecmp(v->name, "notransfer")) {
08189             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
08190          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08191             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
08192          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08193             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
08194          } else if (!strcasecmp(v->name, "host")) {
08195             if (!strcasecmp(v->value, "dynamic")) {
08196                /* They'll register with us */
08197                ast_set_flag(peer, IAX_DYNAMIC); 
08198                if (!found) {
08199                   /* Initialize stuff iff we're not found, otherwise
08200                      we keep going with what we had */
08201                   memset(&peer->addr.sin_addr, 0, 4);
08202                   if (peer->addr.sin_port) {
08203                      /* If we've already got a port, make it the default rather than absolute */
08204                      peer->defaddr.sin_port = peer->addr.sin_port;
08205                      peer->addr.sin_port = 0;
08206                   }
08207                }
08208             } else {
08209                /* Non-dynamic.  Make sure we become that way if we're not */
08210                if (peer->expire > -1)
08211                   ast_sched_del(sched, peer->expire);
08212                peer->expire = -1;
08213                ast_clear_flag(peer, IAX_DYNAMIC);
08214                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08215                   free(peer);
08216                   return NULL;
08217                }
08218                if (!peer->addr.sin_port)
08219                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08220             }
08221             if (!maskfound)
08222                inet_aton("255.255.255.255", &peer->mask);
08223          } else if (!strcasecmp(v->name, "defaultip")) {
08224             if (ast_get_ip(&peer->defaddr, v->value)) {
08225                free(peer);
08226                return NULL;
08227             }
08228          } else if (!strcasecmp(v->name, "sourceaddress")) {
08229             peer_set_srcaddr(peer, v->value);
08230          } else if (!strcasecmp(v->name, "permit") ||
08231                   !strcasecmp(v->name, "deny")) {
08232             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08233          } else if (!strcasecmp(v->name, "mask")) {
08234             maskfound++;
08235             inet_aton(v->value, &peer->mask);
08236          } else if (!strcasecmp(v->name, "context")) {
08237             if (ast_strlen_zero(peer->context))
08238                ast_copy_string(peer->context, v->value, sizeof(peer->context));
08239          } else if (!strcasecmp(v->name, "regexten")) {
08240             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
08241          } else if (!strcasecmp(v->name, "peercontext")) {
08242             if (ast_strlen_zero(peer->peercontext))
08243                ast_copy_string(peer->peercontext, v->value, sizeof(peer->peercontext));
08244          } else if (!strcasecmp(v->name, "port")) {
08245             if (ast_test_flag(peer, IAX_DYNAMIC))
08246                peer->defaddr.sin_port = htons(atoi(v->value));
08247             else
08248                peer->addr.sin_port = htons(atoi(v->value));
08249          } else if (!strcasecmp(v->name, "username")) {
08250             ast_copy_string(peer->username, v->value, sizeof(peer->username));
08251          } else if (!strcasecmp(v->name, "allow")) {
08252             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08253          } else if (!strcasecmp(v->name, "disallow")) {
08254             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08255          } else if (!strcasecmp(v->name, "callerid")) {
08256             ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name),
08257                            peer->cid_num, sizeof(peer->cid_num));
08258             ast_set_flag(peer, IAX_HASCALLERID);   
08259          } else if (!strcasecmp(v->name, "sendani")) {
08260             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
08261          } else if (!strcasecmp(v->name, "inkeys")) {
08262             ast_copy_string(peer->inkeys, v->value, sizeof(peer->inkeys));
08263          } else if (!strcasecmp(v->name, "outkey")) {
08264             ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));
08265          } else if (!strcasecmp(v->name, "qualify")) {
08266             if (!strcasecmp(v->value, "no")) {
08267                peer->maxms = 0;
08268             } else if (!strcasecmp(v->value, "yes")) {
08269                peer->maxms = DEFAULT_MAXMS;
08270             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08271                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);
08272                peer->maxms = 0;
08273             }
08274          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08275             peer->smoothing = ast_true(v->value);
08276          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08277             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08278                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);
08279             }
08280          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08281             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08282                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);
08283             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08284          } else if (!strcasecmp(v->name, "timezone")) {
08285             ast_copy_string(peer->zonetag, v->value, sizeof(peer->zonetag));
08286          }/* else if (strcasecmp(v->name,"type")) */
08287          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08288          v=v->next;
08289       }
08290       if (!peer->authmethods)
08291          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08292       ast_clear_flag(peer, IAX_DELME); 
08293       /* Make sure these are IPv4 addresses */
08294       peer->addr.sin_family = AF_INET;
08295    }
08296    if (oldha)
08297       ast_free_ha(oldha);
08298    return peer;
08299 }

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

Definition at line 8302 of file chan_iax2.c.

References iax2_user::accountcode, iax2_user::amaflags, 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(), iax2_user::authmethods, build_context(), iax2_user::capability, iax2_user::cid_name, iax2_user::cid_num, iax2_user::contexts, iax2_user::dbsecret, iax2_user::encmethods, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_user::ha, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, language, iax2_user::language, ast_variable::lineno, ast_user_list::lock, LOG_WARNING, malloc, ast_variable::name, name, iax2_user::name, ast_variable::next, iax2_context::next, iax2_user::next, iax2_user::prefs, iax2_user::secret, timingfd, userl, ast_user_list::users, ast_variable::value, and iax2_user::vars.

08303 {
08304    struct iax2_user *prev, *user;
08305    struct iax2_context *con, *conl = NULL;
08306    struct ast_ha *oldha = NULL;
08307    struct iax2_context *oldcon = NULL;
08308    int format;
08309    char *varname = NULL, *varval = NULL;
08310    struct ast_variable *tmpvar = NULL;
08311    
08312    prev = NULL;
08313    ast_mutex_lock(&userl.lock);
08314    if (!temponly) {
08315       user = userl.users;
08316       while(user) {
08317          if (!strcmp(user->name, name)) { 
08318             break;
08319          }
08320          prev = user;
08321          user = user->next;
08322       }
08323    } else
08324       user = NULL;
08325    
08326    if (user) {
08327       oldha = user->ha;
08328       oldcon = user->contexts;
08329       user->ha = NULL;
08330       user->contexts = NULL;
08331       /* Already in the list, remove it and it will be added back (or FREE'd) */
08332       if (prev) {
08333          prev->next = user->next;
08334       } else {
08335          userl.users = user->next;
08336       }
08337       ast_mutex_unlock(&userl.lock);
08338    } else {
08339       ast_mutex_unlock(&userl.lock);
08340       user = malloc(sizeof(struct iax2_user));
08341       if (user)
08342          memset(user, 0, sizeof(struct iax2_user));
08343    }
08344    
08345    if (user) {
08346       memset(user, 0, sizeof(struct iax2_user));
08347       user->prefs = prefs;
08348       user->capability = iax2_capability;
08349       user->encmethods = iax2_encryption;
08350       ast_copy_string(user->name, name, sizeof(user->name));
08351       ast_copy_string(user->language, language, sizeof(user->language));
08352       ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
08353       while(v) {
08354          if (!strcasecmp(v->name, "context")) {
08355             con = build_context(v->value);
08356             if (con) {
08357                if (conl)
08358                   conl->next = con;
08359                else
08360                   user->contexts = con;
08361                conl = con;
08362             }
08363          } else if (!strcasecmp(v->name, "permit") ||
08364                   !strcasecmp(v->name, "deny")) {
08365             user->ha = ast_append_ha(v->name, v->value, user->ha);
08366          } else if (!strcasecmp(v->name, "setvar")) {
08367             varname = ast_strdupa(v->value);
08368             if (varname && (varval = strchr(varname,'='))) {
08369                *varval = '\0';
08370                varval++;
08371                if((tmpvar = ast_variable_new(varname, varval))) {
08372                   tmpvar->next = user->vars; 
08373                   user->vars = tmpvar;
08374                }
08375             }
08376          } else if (!strcasecmp(v->name, "allow")) {
08377             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08378          } else if (!strcasecmp(v->name, "disallow")) {
08379             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08380          } else if (!strcasecmp(v->name, "trunk")) {
08381             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
08382             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08383                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08384                ast_clear_flag(user, IAX_TRUNK);
08385             }
08386          } else if (!strcasecmp(v->name, "auth")) {
08387             user->authmethods = get_auth_methods(v->value);
08388          } else if (!strcasecmp(v->name, "encryption")) {
08389             user->encmethods = get_encrypt_methods(v->value);
08390          } else if (!strcasecmp(v->name, "notransfer")) {
08391             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
08392          } else if (!strcasecmp(v->name, "codecpriority")) {
08393             if(!strcasecmp(v->value, "caller"))
08394                ast_set_flag(user, IAX_CODEC_USER_FIRST);
08395             else if(!strcasecmp(v->value, "disabled"))
08396                ast_set_flag(user, IAX_CODEC_NOPREFS);
08397             else if(!strcasecmp(v->value, "reqonly")) {
08398                ast_set_flag(user, IAX_CODEC_NOCAP);
08399                ast_set_flag(user, IAX_CODEC_NOPREFS);
08400             }
08401          } else if (!strcasecmp(v->name, "jitterbuffer")) {
08402             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);  
08403          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08404             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);   
08405          } else if (!strcasecmp(v->name, "dbsecret")) {
08406             ast_copy_string(user->dbsecret, v->value, sizeof(user->dbsecret));
08407          } else if (!strcasecmp(v->name, "secret")) {
08408             if (!ast_strlen_zero(user->secret)) {
08409                strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
08410                strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1);
08411             } else
08412                ast_copy_string(user->secret, v->value, sizeof(user->secret));
08413          } else if (!strcasecmp(v->name, "callerid")) {
08414             ast_callerid_split(v->value, user->cid_name, sizeof(user->cid_name), user->cid_num, sizeof(user->cid_num));
08415             ast_set_flag(user, IAX_HASCALLERID);   
08416          } else if (!strcasecmp(v->name, "accountcode")) {
08417             ast_copy_string(user->accountcode, v->value, sizeof(user->accountcode));
08418          } else if (!strcasecmp(v->name, "language")) {
08419             ast_copy_string(user->language, v->value, sizeof(user->language));
08420          } else if (!strcasecmp(v->name, "amaflags")) {
08421             format = ast_cdr_amaflags2int(v->value);
08422             if (format < 0) {
08423                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08424             } else {
08425                user->amaflags = format;
08426             }
08427          } else if (!strcasecmp(v->name, "inkeys")) {
08428             ast_copy_string(user->inkeys, v->value, sizeof(user->inkeys));
08429          }/* else if (strcasecmp(v->name,"type")) */
08430          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08431          v = v->next;
08432       }
08433       if (!user->authmethods) {
08434          if (!ast_strlen_zero(user->secret)) {
08435             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08436             if (!ast_strlen_zero(user->inkeys))
08437                user->authmethods |= IAX_AUTH_RSA;
08438          } else if (!ast_strlen_zero(user->inkeys)) {
08439             user->authmethods = IAX_AUTH_RSA;
08440          } else {
08441             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08442          }
08443       }
08444       ast_clear_flag(user, IAX_DELME);
08445    }
08446    if (oldha)
08447       ast_free_ha(oldha);
08448    if (oldcon)
08449       free_context(oldcon);
08450    return user;
08451 }

int cache_get_callno_locked const char *  data  )  [static]
 

Definition at line 8863 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_PROTO_VERSION, iaxs, iaxsl, LOG_DEBUG, LOG_WARNING, NEW_FORCE, chan_iax2_pvt::outkey, parse_dial_string(), chan_iax2_pvt::secret, and send_command().

Referenced by find_cache().

08864 {
08865    struct sockaddr_in sin;
08866    int x;
08867    int callno;
08868    struct iax_ie_data ied;
08869    struct create_addr_info cai;
08870    struct parsed_dial_string pds;
08871    char *tmpstr;
08872 
08873    for (x=0; x<IAX_MAX_CALLS; x++) {
08874       /* Look for an *exact match* call.  Once a call is negotiated, it can only
08875          look up entries for a single context */
08876       if (!ast_mutex_trylock(&iaxsl[x])) {
08877          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
08878             return x;
08879          ast_mutex_unlock(&iaxsl[x]);
08880       }
08881    }
08882 
08883    /* No match found, we need to create a new one */
08884 
08885    memset(&cai, 0, sizeof(cai));
08886    memset(&ied, 0, sizeof(ied));
08887    memset(&pds, 0, sizeof(pds));
08888 
08889    tmpstr = ast_strdupa(data);
08890    parse_dial_string(tmpstr, &pds);
08891 
08892    /* Populate our address from the given */
08893    if (create_addr(pds.peer, &sin, &cai))
08894       return -1;
08895 
08896    ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
08897       pds.peer, pds.username, pds.password, pds.context);
08898 
08899    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
08900    if (callno < 1) {
08901       ast_log(LOG_WARNING, "Unable to create call\n");
08902       return -1;
08903    }
08904 
08905    ast_mutex_lock(&iaxsl[callno]);
08906    ast_copy_string(iaxs[callno]->dproot, data, sizeof(iaxs[callno]->dproot));
08907    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
08908 
08909    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
08910    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
08911    /* the string format is slightly different from a standard dial string,
08912       because the context appears in the 'exten' position
08913    */
08914    if (pds.exten)
08915       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
08916    if (pds.username)
08917       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
08918    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
08919    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
08920    /* Keep password handy */
08921    if (pds.password)
08922       ast_copy_string(iaxs[callno]->secret, pds.password, sizeof(iaxs[callno]->secret));
08923    if (pds.key)
08924       ast_copy_string(iaxs[callno]->outkey, pds.key, sizeof(iaxs[callno]->outkey));
08925    /* Start the call going */
08926    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
08927 
08928    return callno;
08929 }

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

Definition at line 3643 of file chan_iax2.c.

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

Referenced by ast_rtp_read(), and schedule_delivery().

03644 {
03645    /* Returns where in "receive time" we are.  That is, how many ms
03646       since we received (or would have received) the frame with timestamp 0 */
03647    int ms;
03648 #ifdef IAXTESTS
03649    int jit;
03650 #endif /* IAXTESTS */
03651    /* Setup rxcore if necessary */
03652    if (ast_tvzero(p->rxcore)) {
03653       p->rxcore = ast_tvnow();
03654       if (option_debug && iaxdebug)
03655          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03656                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03657       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03658 #if 1
03659       if (option_debug && iaxdebug)
03660          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03661                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03662 #endif
03663    }
03664 
03665    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03666 #ifdef IAXTESTS
03667    if (test_jit) {
03668       if (!test_jitpct || ((100.0 * rand() / (RAND_MAX + 1.0)) < test_jitpct)) {
03669          jit = (int)((float)test_jit * rand() / (RAND_MAX + 1.0));
03670          if ((int)(2.0 * rand() / (RAND_MAX + 1.0)))
03671             jit = -jit;
03672          ms += jit;
03673       }
03674    }
03675    if (test_late) {
03676       ms += test_late;
03677       test_late = 0;
03678    }
03679 #endif /* IAXTESTS */
03680    return ms;
03681 }

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

Definition at line 3496 of file chan_iax2.c.

References ast_log(), ast_tvadd(), ast_tvsub(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame::frametype, iaxdebug, iaxs, chan_iax2_pvt::lastsent, LOG_DEBUG, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, option_debug, chan_iax2_pvt::peercallno, and ast_frame::samples.

Referenced by iax2_send(), and socket_read().

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

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

Definition at line 3452 of file chan_iax2.c.

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

Referenced by send_trunk().

03453 {
03454    unsigned long int mssincetx; /* unsigned to handle overflows */
03455    long int ms, pred;
03456 
03457    tpeer->trunkact = *tv;
03458    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03459    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03460       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03461       tpeer->txtrunktime = *tv;
03462       tpeer->lastsent = 999999;
03463    }
03464    /* Update last transmit time now */
03465    tpeer->lasttxtime = *tv;
03466    
03467    /* Calculate ms offset */
03468    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03469    /* Predict from last value */
03470    pred = tpeer->lastsent + sampms;
03471    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03472       ms = pred;
03473    
03474    /* We never send the same timestamp twice, so fudge a little if we must */
03475    if (ms == tpeer->lastsent)
03476       ms = tpeer->lastsent + 1;
03477    tpeer->lastsent = ms;
03478    return ms;
03479 }

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

Definition at line 4709 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_set2_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, iax2_user::cid_name, chan_iax2_pvt::cid_name, iax2_user::cid_num, chan_iax2_pvt::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, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TEMPONLY, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, 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, 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, prefs, realtime_user(), chan_iax2_pvt::secret, iax2_user::secret, userl, chan_iax2_pvt::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().

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

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

Definition at line 6209 of file chan_iax2.c.

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

Referenced by socket_read().

06210 {
06211    unsigned int ourver;
06212    char rsi[80];
06213    snprintf(rsi, sizeof(rsi), "si-%s", si);
06214    if (iax_provision_version(&ourver, rsi, 1))
06215       return 0;
06216    if (option_debug)
06217       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06218    if (ourver != ver) 
06219       iax2_provision(sin, sockfd, NULL, rsi, 1);
06220    return 0;
06221 }

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

Definition at line 8027 of file chan_iax2.c.

References ast_log(), LOG_DEBUG, and LOG_ERROR.

Referenced by peer_set_srcaddr().

08028 {
08029    int sd;
08030    int res;
08031    
08032    sd = socket(AF_INET, SOCK_DGRAM, 0);
08033    if (sd < 0) {
08034       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08035       return -1;
08036    }
08037 
08038    res = bind(sd, sa, salen);
08039    if (res < 0) {
08040       ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08041       close(sd);
08042       return 1;
08043    }
08044 
08045    close(sd);
08046    return 0;
08047 }

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

Definition at line 5315 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_unlock(), iax_ies::called_number, iax2_dpcache::callno, chan_iax2_pvt::dpentries, iax_ies::dpstatus, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::orig, iax2_dpcache::peer, iax_ies::refresh, and iax2_dpcache::waiters.

Referenced by socket_read().

05316 {
05317    char exten[256] = "";
05318    int status = CACHE_FLAG_UNKNOWN;
05319    int expiry = iaxdefaultdpcache;
05320    int x;
05321    int matchmore = 0;
05322    struct iax2_dpcache *dp, *prev;
05323    
05324    if (ies->called_number)
05325       ast_copy_string(exten, ies->called_number, sizeof(exten));
05326 
05327    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05328       status = CACHE_FLAG_EXISTS;
05329    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05330       status = CACHE_FLAG_CANEXIST;
05331    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05332       status = CACHE_FLAG_NONEXISTENT;
05333 
05334    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05335       /* Don't really do anything with this */
05336    }
05337    if (ies->refresh)
05338       expiry = ies->refresh;
05339    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05340       matchmore = CACHE_FLAG_MATCHMORE;
05341    ast_mutex_lock(&dpcache_lock);
05342    prev = NULL;
05343    dp = pvt->dpentries;
05344    while(dp) {
05345       if (!strcmp(dp->exten, exten)) {
05346          /* Let them go */
05347          if (prev)
05348             prev->peer = dp->peer;
05349          else
05350             pvt->dpentries = dp->peer;
05351          dp->peer = NULL;
05352          dp->callno = 0;
05353          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05354          if (dp->flags & CACHE_FLAG_PENDING) {
05355             dp->flags &= ~CACHE_FLAG_PENDING;
05356             dp->flags |= status;
05357             dp->flags |= matchmore;
05358          }
05359          /* Wake up waiters */
05360          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05361             if (dp->waiters[x] > -1)
05362                write(dp->waiters[x], "asdf", 4);
05363       }
05364       prev = dp;
05365       dp = dp->peer;
05366    }
05367    ast_mutex_unlock(&dpcache_lock);
05368    return 0;
05369 }

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

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

01974 {
01975    int which = 0;
01976    struct iax2_peer *p;
01977    char *res = NULL;
01978 
01979    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
01980    if(pos == 3) {
01981       ast_mutex_lock(&peerl.lock);
01982       for(p = peerl.peers ; p ; p = p->next) {
01983          if(!strncasecmp(p->name, word, strlen(word))) {
01984             if(++which > state) {
01985                res = strdup(p->name);
01986                break;
01987             }
01988          }
01989       }
01990       ast_mutex_unlock(&peerl.lock);
01991    }
01992 
01993    return res;
01994 }

int complete_transfer int  callno,
struct iax_ies ies
[static]
 

Definition at line 5371 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, ast_iax2_queue::head, iax2_frame_free(), iaxq, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), 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, chan_iax2_pvt::transfercallno, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.

Referenced by socket_read().

05372 {
05373    int peercallno = 0;
05374    struct chan_iax2_pvt *pvt = iaxs[callno];
05375    struct iax_frame *cur;
05376 
05377    if (ies->callno)
05378       peercallno = ies->callno;
05379 
05380    if (peercallno < 1) {
05381       ast_log(LOG_WARNING, "Invalid transfer request\n");
05382       return -1;
05383    }
05384    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05385    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05386    /* Reset sequence numbers */
05387    pvt->oseqno = 0;
05388    pvt->rseqno = 0;
05389    pvt->iseqno = 0;
05390    pvt->aseqno = 0;
05391    pvt->peercallno = peercallno;
05392    pvt->transferring = TRANSFER_NONE;
05393    pvt->svoiceformat = -1;
05394    pvt->voiceformat = 0;
05395    pvt->svideoformat = -1;
05396    pvt->videoformat = 0;
05397    pvt->transfercallno = -1;
05398    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05399    memset(&pvt->offset, 0, sizeof(pvt->offset));
05400 #ifdef NEWJB
05401    {  /* reset jitterbuffer */
05402          jb_frame frame;
05403                while(jb_getall(pvt->jb,&frame) == JB_OK)
05404                   iax2_frame_free(frame.data);
05405 
05406       jb_reset(pvt->jb);
05407    }
05408 #else
05409    memset(&pvt->history, 0, sizeof(pvt->history));
05410    pvt->jitterbuffer = 0;
05411    pvt->jitter = 0;
05412    pvt->historicjitter = 0;
05413 #endif
05414    pvt->lag = 0;
05415    pvt->last = 0;
05416    pvt->lastsent = 0;
05417    pvt->nextpred = 0;
05418    pvt->pingtime = DEFAULT_RETRY_TIME;
05419    ast_mutex_lock(&iaxq.lock);
05420    for (cur = iaxq.head; cur ; cur = cur->next) {
05421       /* We must cancel any packets that would have been transmitted
05422          because now we're talking to someone new.  It's okay, they
05423          were transmitted to someone that didn't care anyway. */
05424       if (callno == cur->callno) 
05425          cur->retries = -1;
05426    }
05427    ast_mutex_unlock(&iaxq.lock);
05428    return 0; 
05429 }

unsigned char compress_subclass int  subclass  )  [static]
 

Definition at line 809 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by iax2_send(), and raw_hangup().

00810 {
00811    int x;
00812    int power=-1;
00813    /* If it's 128 or smaller, just return it */
00814    if (subclass < IAX_FLAG_SC_LOG)
00815       return subclass;
00816    /* Otherwise find its power */
00817    for (x = 0; x < IAX_MAX_SHIFT; x++) {
00818       if (subclass & (1 << x)) {
00819          if (power > -1) {
00820             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
00821             return 0;
00822          } else
00823             power = x;
00824       }
00825    }
00826    return power | IAX_FLAG_SC_LOG;
00827 }

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

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

06224 {
06225 #ifdef NEWJB
06226    jb_info stats;
06227    jb_getinfo(pvt->jb, &stats);
06228    
06229    memset(iep, 0, sizeof(*iep));
06230 
06231    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06232    if(stats.frames_in == 0) stats.frames_in = 1;
06233    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06234    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06235    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06236    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06237    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06238 #else
06239    memset(iep, 0, sizeof(*iep));
06240    iax_ie_append_int(iep,IAX_IE_RR_JITTER, pvt->jitter);
06241    iax_ie_append_int(iep,IAX_IE_RR_PKTS, pvt->frames_received);
06242    if(!ast_test_flag(pvt, IAX_USEJITTERBUF)) 
06243       iax_ie_append_short(iep,IAX_IE_RR_DELAY, 0);
06244    else
06245       iax_ie_append_short(iep,IAX_IE_RR_DELAY, pvt->jitterbuffer - pvt->min);
06246    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, pvt->frames_dropped);
06247    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_OOO, 0); */
06248    /* don't know, don't send! iax_ie_append_int(&ied,IAX_IE_RR_LOSS, 0); */
06249 #endif
06250 }

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

Definition at line 2739 of file chan_iax2.c.

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

02740 {
02741    struct ast_hostent ahp;
02742    struct hostent *hp;
02743    struct iax2_peer *peer;
02744 
02745    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02746    cai->sockfd = defaultsockfd;
02747    cai->maxtime = 0;
02748    sin->sin_family = AF_INET;
02749 
02750    if (!(peer = find_peer(peername, 1))) {
02751       cai->found = 0;
02752 
02753       hp = ast_gethostbyname(peername, &ahp);
02754       if (hp) {
02755          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02756          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02757          /* use global iax prefs for unknown peer/user */
02758          ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02759          return 0;
02760       } else {
02761          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02762          return -1;
02763       }
02764    }
02765 
02766    cai->found = 1;
02767    
02768    /* if the peer has no address (current or default), return failure */
02769    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
02770       if (ast_test_flag(peer, IAX_TEMPONLY))
02771          destroy_peer(peer);
02772       return -1;
02773    }
02774 
02775    /* if the peer is being monitored and is currently unreachable, return failure */
02776    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
02777       if (ast_test_flag(peer, IAX_TEMPONLY))
02778          destroy_peer(peer);
02779       return -1;
02780    }
02781 
02782    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02783    cai->maxtime = peer->maxms;
02784    cai->capability = peer->capability;
02785    cai->encmethods = peer->encmethods;
02786    cai->sockfd = peer->sockfd;
02787    ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02788    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02789    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02790    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02791    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02792    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02793    if (ast_strlen_zero(peer->dbsecret)) {
02794       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02795    } else {
02796       char *family;
02797       char *key = NULL;
02798 
02799       family = ast_strdupa(peer->dbsecret);
02800       if (family) {
02801          key = strchr(family, '/');
02802          if (key)
02803             *key++ = '\0';
02804       }
02805       if (!family || !key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02806          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02807          if (ast_test_flag(peer, IAX_TEMPONLY))
02808             destroy_peer(peer);
02809          return -1;
02810       }
02811    }
02812 
02813    if (peer->addr.sin_addr.s_addr) {
02814       sin->sin_addr = peer->addr.sin_addr;
02815       sin->sin_port = peer->addr.sin_port;
02816    } else {
02817       sin->sin_addr = peer->defaddr.sin_addr;
02818       sin->sin_port = peer->defaddr.sin_port;
02819    }
02820 
02821    if (ast_test_flag(peer, IAX_TEMPONLY))
02822       destroy_peer(peer);
02823 
02824    return 0;
02825 }

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

Definition at line 3834 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, ast_frame::frametype, LOG_DEBUG, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().

Referenced by decrypt_frame().

03835 {
03836    int padding;
03837    unsigned char *workspace;
03838    workspace = alloca(*datalen);
03839    if (!workspace)
03840       return -1;
03841    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03842       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03843       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03844          return -1;
03845       /* Decrypt */
03846       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03847 
03848       padding = 16 + (workspace[15] & 0xf);
03849       if (option_debug && iaxdebug)
03850          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03851       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03852          return -1;
03853 
03854       *datalen -= padding;
03855       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03856       f->frametype = fh->type;
03857       if (f->frametype == AST_FRAME_VIDEO) {
03858          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03859       } else {
03860          f->subclass = uncompress_subclass(fh->csub);
03861       }
03862    } else {
03863       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03864       if (option_debug && iaxdebug)
03865          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03866       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03867          return -1;
03868       /* Decrypt */
03869       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03870       padding = 16 + (workspace[15] & 0x0f);
03871       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03872          return -1;
03873       *datalen -= padding;
03874       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03875    }
03876    return 0;
03877 }

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

Definition at line 3920 of file chan_iax2.c.

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

Referenced by socket_read().

03921 {
03922    int res=-1;
03923    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03924       /* Search for possible keys, given secrets */
03925       struct MD5Context md5;
03926       unsigned char digest[16];
03927       char *tmppw, *stringp;
03928       
03929       tmppw = ast_strdupa(iaxs[callno]->secret);
03930       stringp = tmppw;
03931       while((tmppw = strsep(&stringp, ";"))) {
03932          MD5Init(&md5);
03933          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03934          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03935          MD5Final(digest, &md5);
03936          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03937          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03938          if (!res) {
03939             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03940             break;
03941          }
03942       }
03943    } else 
03944       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03945    return res;
03946 }

void delete_users void   )  [static]
 

Definition at line 8453 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, iaxs, iaxsl, ast_peer_list::lock, ast_user_list::lock, iax2_peer::next, iax2_registry::next, iax2_user::next, peerl, ast_peer_list::peers, chan_iax2_pvt::reg, registrations, sched, userl, and ast_user_list::users.

08454 {
08455    struct iax2_user *user;
08456    struct iax2_peer *peer;
08457    struct iax2_registry *reg, *regl;
08458 
08459    ast_mutex_lock(&userl.lock);
08460    for (user=userl.users;user;) {
08461       ast_set_flag(user, IAX_DELME);
08462       user = user->next;
08463    }
08464    ast_mutex_unlock(&userl.lock);
08465    for (reg = registrations;reg;) {
08466       regl = reg;
08467       reg = reg->next;
08468       if (regl->expire > -1) {
08469          ast_sched_del(sched, regl->expire);
08470       }
08471       if (regl->callno) {
08472          /* XXX Is this a potential lock?  I don't think so, but you never know */
08473          ast_mutex_lock(&iaxsl[regl->callno]);
08474          if (iaxs[regl->callno]) {
08475             iaxs[regl->callno]->reg = NULL;
08476             iax2_destroy_nolock(regl->callno);
08477          }
08478          ast_mutex_unlock(&iaxsl[regl->callno]);
08479       }
08480       free(regl);
08481    }
08482    registrations = NULL;
08483    ast_mutex_lock(&peerl.lock);
08484    for (peer=peerl.peers;peer;) {
08485       /* Assume all will be deleted, and we'll find out for sure later */
08486       ast_set_flag(peer, IAX_DELME);
08487       peer = peer->next;
08488    }
08489    ast_mutex_unlock(&peerl.lock);
08490 }

char* description void   ) 
 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 9646 of file chan_iax2.c.

09647 {
09648    return (char *) desc;
09649 }

void destroy_firmware struct iax_firmware cur  )  [static]
 

Definition at line 1141 of file chan_iax2.c.

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

Referenced by reload_firmware().

01142 {
01143    /* Close firmware */
01144    if (cur->fwh) {
01145       munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01146    }
01147    close(cur->fd);
01148    free(cur);
01149 }

void destroy_peer struct iax2_peer peer  )  [static]
 

Definition at line 8522 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(), iaxs, iaxsl, chan_iax2_pvt::peerpoke, iax2_peer::pokeexpire, register_peer_exten(), and sched.

08523 {
08524    int x;
08525    ast_free_ha(peer->ha);
08526    for (x=0;x<IAX_MAX_CALLS;x++) {
08527       ast_mutex_lock(&iaxsl[x]);
08528       if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
08529          iax2_destroy(x);
08530       }
08531       ast_mutex_unlock(&iaxsl[x]);
08532    }
08533    /* Delete it, it needs to disappear */
08534    if (peer->expire > -1)
08535       ast_sched_del(sched, peer->expire);
08536    if (peer->pokeexpire > -1)
08537       ast_sched_del(sched, peer->pokeexpire);
08538    if (peer->callno > 0)
08539       iax2_destroy(peer->callno);
08540    register_peer_exten(peer, 0);
08541    if (peer->dnsmgr)
08542       ast_dnsmgr_release(peer->dnsmgr);
08543    free(peer);
08544 }

void destroy_user struct iax2_user user  )  [static]
 

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

08493 {
08494    ast_free_ha(user->ha);
08495    free_context(user->contexts);
08496    if(user->vars) {
08497       ast_variables_destroy(user->vars);
08498       user->vars = NULL;
08499    }
08500    free(user);
08501 }

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

Definition at line 6066 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(), context, IAX_COMMAND_DPREP, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxdefaultdpcache, iaxs, iaxsl, and send_command().

Referenced by dp_lookup_thread(), and socket_read().

06067 {
06068    unsigned short dpstatus = 0;
06069    struct iax_ie_data ied1;
06070    int mm;
06071 
06072    memset(&ied1, 0, sizeof(ied1));
06073    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06074    /* Must be started */
06075    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06076       dpstatus = IAX_DPSTATUS_EXISTS;
06077    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06078       dpstatus = IAX_DPSTATUS_CANEXIST;
06079    } else {
06080       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06081    }
06082    if (ast_ignore_pattern(context, callednum))
06083       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06084    if (mm)
06085       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06086    if (!skiplock)
06087       ast_mutex_lock(&iaxsl[callno]);
06088    if (iaxs[callno]) {
06089       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06090       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06091       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06092       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06093    }
06094    if (!skiplock)
06095       ast_mutex_unlock(&iaxsl[callno]);
06096 }

void* dp_lookup_thread void *  data  )  [static]
 

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

06099 {
06100    /* Look up for dpreq */
06101    struct dpreq_data *dpr = data;
06102    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06103    if (dpr->callerid)
06104       free(dpr->callerid);
06105    free(dpr);
06106    return NULL;
06107 }

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

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

Referenced by iax2_send().

03880 {
03881    int padding;
03882    unsigned char *workspace;
03883    workspace = alloca(*datalen + 32);
03884    if (!workspace)
03885       return -1;
03886    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03887       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03888       if (option_debug && iaxdebug)
03889          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03890       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03891       padding = 16 + (padding & 0xf);
03892       memcpy(workspace, poo, padding);
03893       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03894       workspace[15] &= 0xf0;
03895       workspace[15] |= (padding & 0xf);
03896       if (option_debug && iaxdebug)
03897          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]);
03898       *datalen += padding;
03899       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03900       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03901          memcpy(poo, workspace + *datalen - 32, 32);
03902    } else {
03903       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03904       if (option_debug && iaxdebug)
03905          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03906       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03907       padding = 16 + (padding & 0xf);
03908       memcpy(workspace, poo, padding);
03909       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03910       workspace[15] &= 0xf0;
03911       workspace[15] |= (padding & 0x0f);
03912       *datalen += padding;
03913       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03914       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03915          memcpy(poo, workspace + *datalen - 32, 32);
03916    }
03917    return 0;
03918 }

int expire_registry void *  data  )  [static]
 

Definition at line 5566 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, LOG_DEBUG, iax2_peer::name, prune_peers(), and register_peer_exten().

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

05567 {
05568    struct iax2_peer *p = data;
05569 
05570    ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05571    /* Reset the address */
05572    memset(&p->addr, 0, sizeof(p->addr));
05573    /* Reset expire notice */
05574    p->expire = -1;
05575    /* Reset expiry value */
05576    p->expiry = min_reg_expire;
05577    if (!ast_test_flag(p, IAX_TEMPONLY))
05578       ast_db_del("IAX/Registry", p->name);
05579    register_peer_exten(p, 0);
05580    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05581    if (iax2_regfunk)
05582       iax2_regfunk(p->name, 0);
05583 
05584    if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05585       ast_set_flag(p, IAX_DELME);
05586       prune_peers();
05587    }
05588 
05589    return 0;
05590 }

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

Definition at line 8931 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_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, iaxdefaulttimeout, iaxs, iaxsl, LOG_WARNING, malloc, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, tv, and iax2_dpcache::waiters.

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

08932 {
08933    struct iax2_dpcache *dp, *prev = NULL, *next;
08934    struct timeval tv;
08935    int x;
08936    int com[2];
08937    int timeout;
08938    int old=0;
08939    int outfd;
08940    int abort;
08941    int callno;
08942    struct ast_channel *c;
08943    struct ast_frame *f;
08944    gettimeofday(&tv, NULL);
08945    dp = dpcache;
08946    while(dp) {
08947       next = dp->next;
08948       /* Expire old caches */
08949       if (ast_tvcmp(tv, dp->expiry) > 0) {
08950             /* It's expired, let it disappear */
08951             if (prev)
08952                prev->next = dp->next;
08953             else
08954                dpcache = dp->next;
08955             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
08956                /* Free memory and go again */
08957                free(dp);
08958             } else {
08959                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);
08960             }
08961             dp = next;
08962             continue;
08963       }
08964       /* We found an entry that matches us! */
08965       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
08966          break;
08967       prev = dp;
08968       dp = next;
08969    }
08970    if (!dp) {
08971       /* No matching entry.  Create a new one. */
08972       /* First, can we make a callno? */
08973       callno = cache_get_callno_locked(data);
08974       if (callno < 0) {
08975          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
08976          return NULL;
08977       }
08978       dp = malloc(sizeof(struct iax2_dpcache));
08979       if (!dp) {
08980          ast_mutex_unlock(&iaxsl[callno]);
08981          return NULL;
08982       }
08983       memset(dp, 0, sizeof(struct iax2_dpcache));
08984       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
08985       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
08986       gettimeofday(&dp->expiry, NULL);
08987       dp->orig = dp->expiry;
08988       /* Expires in 30 mins by default */
08989       dp->expiry.tv_sec += iaxdefaultdpcache;
08990       dp->next = dpcache;
08991       dp->flags = CACHE_FLAG_PENDING;
08992       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
08993          dp->waiters[x] = -1;
08994       dpcache = dp;
08995       dp->peer = iaxs[callno]->dpentries;
08996       iaxs[callno]->dpentries = dp;
08997       /* Send the request if we're already up */
08998       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
08999          iax2_dprequest(dp, callno);
09000       ast_mutex_unlock(&iaxsl[callno]);
09001    }
09002    /* By here we must have a dp */
09003    if (dp->flags & CACHE_FLAG_PENDING) {
09004       /* Okay, here it starts to get nasty.  We need a pipe now to wait
09005          for a reply to come back so long as it's pending */
09006       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09007          /* Find an empty slot */
09008          if (dp->waiters[x] < 0)
09009             break;
09010       }
09011       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09012          ast_log(LOG_WARNING, "No more waiter positions available\n");
09013          return NULL;
09014       }
09015       if (pipe(com)) {
09016          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09017          return NULL;
09018       }
09019       dp->waiters[x] = com[1];
09020       /* Okay, now we wait */
09021       timeout = iaxdefaulttimeout * 1000;
09022       /* Temporarily unlock */
09023       ast_mutex_unlock(&dpcache_lock);
09024       /* Defer any dtmf */
09025       if (chan)
09026          old = ast_channel_defer_dtmf(chan);
09027       abort = 0;
09028       while(timeout) {
09029          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09030          if (outfd > -1) {
09031             break;
09032          }
09033          if (c) {
09034             f = ast_read(c);
09035             if (f)
09036                ast_frfree(f);
09037             else {
09038                /* Got hung up on, abort! */
09039                break;
09040                abort = 1;
09041             }
09042          }
09043       }
09044       if (!timeout) {
09045          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09046       }
09047       ast_mutex_lock(&dpcache_lock);
09048       dp->waiters[x] = -1;
09049       close(com[1]);
09050       close(com[0]);
09051       if (abort) {
09052          /* Don't interpret anything, just abort.  Not sure what th epoint
09053            of undeferring dtmf on a hung up channel is but hey whatever */
09054          if (!old && chan)
09055             ast_channel_undefer_dtmf(chan);
09056          return NULL;
09057       }
09058       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09059          /* Now to do non-independent analysis the results of our wait */
09060          if (dp->flags & CACHE_FLAG_PENDING) {
09061             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
09062                pending.  Don't let it take as long to timeout. */
09063             dp->flags &= ~CACHE_FLAG_PENDING;
09064             dp->flags |= CACHE_FLAG_TIMEOUT;
09065             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
09066                systems without leaving it unavailable once the server comes back online */
09067             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09068             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09069                if (dp->waiters[x] > -1)
09070                   write(dp->waiters[x], "asdf", 4);
09071          }
09072       }
09073       /* Our caller will obtain the rest */
09074       if (!old && chan)
09075          ast_channel_undefer_dtmf(chan);
09076    }
09077    return dp;  
09078 }

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

Definition at line 1039 of file chan_iax2.c.

References accountcode, chan_iax2_pvt::addr, 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, chan_iax2_pvt::expiry, globalflags, iax2_getpeername(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, match(), new_iax(), option_debug, chan_iax2_pvt::peercallno, ping_time, chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, and update_max_nontrunk().

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

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

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

Definition at line 843 of file chan_iax2.c.

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

00844 {
00845    struct iax2_peer *peer;
00846    ast_mutex_lock(&peerl.lock);
00847    for(peer = peerl.peers; peer; peer = peer->next) {
00848       if (!strcasecmp(peer->name, name)) {
00849          break;
00850       }
00851    }
00852    ast_mutex_unlock(&peerl.lock);
00853    if(!peer && realtime)
00854       peer = realtime_peer(name, NULL);
00855    return peer;
00856 }

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

Definition at line 3683 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::lastsent, iax2_trunk_peer::lock, LOG_DEBUG, malloc, iax2_trunk_peer::next, iax2_trunk_peer::sockfd, tpeers, and iax2_trunk_peer::trunkact.

Referenced by iax2_trunk_queue(), and socket_read().

03684 {
03685    struct iax2_trunk_peer *tpeer;
03686    char iabuf[INET_ADDRSTRLEN];
03687    /* Finds and locks trunk peer */
03688    ast_mutex_lock(&tpeerlock);
03689    tpeer = tpeers;
03690    while(tpeer) {
03691       /* We don't lock here because tpeer->addr *never* changes */
03692       if (!inaddrcmp(&tpeer->addr, sin)) {
03693          ast_mutex_lock(&tpeer->lock);
03694          break;
03695       }
03696       tpeer = tpeer->next;
03697    }
03698    if (!tpeer) {
03699       tpeer = malloc(sizeof(struct iax2_trunk_peer));
03700       if (tpeer) {
03701          memset(tpeer, 0, sizeof(struct iax2_trunk_peer));
03702          ast_mutex_init(&tpeer->lock);
03703          tpeer->lastsent = 9999;
03704          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03705          tpeer->trunkact = ast_tvnow();
03706          ast_mutex_lock(&tpeer->lock);
03707          tpeer->next = tpeers;
03708          tpeer->sockfd = fd;
03709          tpeers = tpeer;
03710 #ifdef SO_NO_CHECK
03711          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03712 #endif
03713          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));
03714       }
03715    }
03716    ast_mutex_unlock(&tpeerlock);
03717    return tpeer;
03718 }

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

Definition at line 3481 of file chan_iax2.c.

References iaxs, chan_iax2_pvt::rxcore, and tv.

Referenced by socket_read().

03482 {
03483    long ms; /* NOT unsigned */
03484    if (ast_tvzero(iaxs[callno]->rxcore)) {
03485       /* Initialize rxcore time if appropriate */
03486       gettimeofday(&iaxs[callno]->rxcore, NULL);
03487       /* Round to nearest 20ms so traces look pretty */
03488       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03489    }
03490    /* Calculate difference between trunk and channel */
03491    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03492    /* Return as the sum of trunk time and the difference between trunk and real time */
03493    return ms + ts;
03494 }

void free_context struct iax2_context con  )  [static]
 

Definition at line 7838 of file chan_iax2.c.

References free, and iax2_context::next.

Referenced by build_user(), and destroy_user().

07839 {
07840    struct iax2_context *conl;
07841    while(con) {
07842       conl = con;
07843       con = con->next;
07844       free(conl);
07845    }
07846 }

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

Definition at line 9203 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::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), IAX_DYNAMIC, iaxs, LOG_ERROR, iax2_peer::mailbox, peer_status(), iax2_peer::prefs, PTR_TO_CALLNO, and ast_channel::tech_pvt.

09204 {
09205    char *ret = NULL;
09206    struct iax2_peer *peer;
09207    char *peername, *colname;
09208    char iabuf[INET_ADDRSTRLEN];
09209 
09210    if (!(peername = ast_strdupa(data))) {
09211       ast_log(LOG_ERROR, "Memory Error!\n");
09212       return ret;
09213    }
09214 
09215    /* if our channel, return the IP address of the endpoint of current channel */
09216    if (!strcmp(peername,"CURRENTCHANNEL")) {
09217            unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
09218       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iaxs[callno]->addr.sin_addr) : "", len);
09219       return buf;
09220    }
09221 
09222    if ((colname = strchr(peername, ':'))) {
09223       *colname = '\0';
09224       colname++;
09225    } else {
09226       colname = "ip";
09227    }
09228    if (!(peer = find_peer(peername, 1)))
09229       return ret;
09230 
09231    if (!strcasecmp(colname, "ip")) {
09232       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), peer->addr.sin_addr) : "", len);
09233    } else  if (!strcasecmp(colname, "status")) {
09234       peer_status(peer, buf, len); 
09235    } else  if (!strcasecmp(colname, "mailbox")) {
09236       ast_copy_string(buf, peer->mailbox, len);
09237    } else  if (!strcasecmp(colname, "context")) {
09238       ast_copy_string(buf, peer->context, len);
09239    } else  if (!strcasecmp(colname, "expire")) {
09240       snprintf(buf, len, "%d", peer->expire);
09241    } else  if (!strcasecmp(colname, "dynamic")) {
09242       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09243    } else  if (!strcasecmp(colname, "callerid_name")) {
09244       ast_copy_string(buf, peer->cid_name, len);
09245    } else  if (!strcasecmp(colname, "callerid_num")) {
09246       ast_copy_string(buf, peer->cid_num, len);
09247    } else  if (!strcasecmp(colname, "codecs")) {
09248       ast_getformatname_multiple(buf, len -1, peer->capability);
09249    } else  if (!strncasecmp(colname, "codec[", 6)) {
09250       char *codecnum, *ptr;
09251       int index = 0, codec = 0;
09252       
09253       codecnum = strchr(colname, '[');
09254       *codecnum = '\0';
09255       codecnum++;
09256       if ((ptr = strchr(codecnum, ']'))) {
09257          *ptr = '\0';
09258       }
09259       index = atoi(codecnum);
09260       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09261          ast_copy_string(buf, ast_getformatname(codec), len);
09262       }
09263    }
09264    ret = buf;
09265 
09266    return ret;
09267 }

int get_auth_methods char *  value  )  [static]
 

Definition at line 8008 of file chan_iax2.c.

Referenced by build_peer(), and build_user().

08009 {
08010    int methods = 0;
08011    if (strstr(value, "rsa"))
08012       methods |= IAX_AUTH_RSA;
08013    if (strstr(value, "md5"))
08014       methods |= IAX_AUTH_MD5;
08015    if (strstr(value, "plaintext"))
08016       methods |= IAX_AUTH_PLAINTEXT;
08017    return methods;
08018 }

int get_encrypt_methods const char *  s  )  [static]
 

Definition at line 783 of file chan_iax2.c.

References ast_true(), and s.

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

00784 {
00785    int e;
00786    if (!strcasecmp(s, "aes128"))
00787       e = IAX_ENCRYPT_AES128;
00788    else if (ast_true(s))
00789       e = IAX_ENCRYPT_AES128;
00790    else
00791       e = 0;
00792    return e;
00793 }

int get_from_jb void *  p  )  [static]
 

Definition at line 2167 of file chan_iax2.c.

References __do_deliver(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_tvadd(), chan_iax2_pvt::callno, ast_frame::data, jb_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, ast_frame::mallocd, jb_frame::ms, ast_frame::offset, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, tv, update_jbsched(), and chan_iax2_pvt::voiceformat.

Referenced by update_jbsched().

02168 {
02169    /* make sure pvt is valid! */ 
02170     struct chan_iax2_pvt *pvt = p;
02171     struct iax_frame *fr;
02172     jb_frame frame;
02173     int ret;
02174     long now;
02175     long next;
02176     struct timeval tv;
02177 
02178     ast_mutex_lock(&iaxsl[pvt->callno]);
02179     /*  fprintf(stderr, "get_from_jb called\n"); */
02180     pvt->jbid = -1;
02181 
02182     gettimeofday(&tv,NULL);
02183     /* round up a millisecond since ast_sched_runq does; */
02184     /* prevents us from spinning while waiting for our now */
02185     /* to catch up with runq's now */
02186     tv.tv_usec += 1000;
02187 
02188     now = ast_tvdiff_ms(tv, pvt->rxcore);
02189 
02190     if(now >= (next = jb_next(pvt->jb))) {
02191       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02192       switch(ret) {
02193       case JB_OK:
02194          /*if(frame.type == JB_TYPE_VOICE && next + 20 != jb_next(pvt->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(pvt->jb), next); */
02195          fr = frame.data;
02196          __do_deliver(fr);
02197           break;
02198       case JB_INTERP:
02199           {
02200          struct ast_frame af;
02201    
02202          /*if(next + 20 != jb_next(pvt->jb)) fprintf(stderr, "NEXT %ld is not %ld+20!\n", jb_next(pvt->jb), next); */
02203    
02204          /* create an interpolation frame */
02205          /*fprintf(stderr, "Making Interpolation frame\n"); */
02206          af.frametype = AST_FRAME_VOICE;
02207          af.subclass = pvt->voiceformat;
02208          af.datalen  = 0;
02209          af.samples  = frame.ms * 8;
02210          af.mallocd  = 0;
02211          af.src  = "IAX2 JB interpolation";
02212          af.data  = NULL;
02213          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02214          af.offset=AST_FRIENDLY_OFFSET;
02215    
02216          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02217           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02218          if (iaxs[pvt->callno] && !ast_test_flag(iaxs[pvt->callno], IAX_ALREADYGONE))
02219             iax2_queue_frame(pvt->callno, &af);
02220           }
02221           break;
02222       case JB_DROP:
02223          /*if(next != jb_next(pvt->jb)) fprintf(stderr, "NEXT %ld is not next %ld!\n", jb_next(pvt->jb), next); */
02224          iax2_frame_free(frame.data);
02225           break;
02226       case JB_NOFRAME:
02227       case JB_EMPTY:
02228          /* do nothing */
02229           break;
02230       default:
02231          /* shouldn't happen */
02232           break;
02233       }
02234     }
02235     update_jbsched(pvt);
02236     ast_mutex_unlock(&iaxsl[pvt->callno]);
02237     return 0;
02238 }

int handle_error void   )  [static]
 

Definition at line 1435 of file chan_iax2.c.

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

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

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

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

Acknowledgment received for OUR registration.

Definition at line 5432 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(), iaxs, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, iax_ies::msgcount, option_verbose, iax2_registry::refresh, iax_ies::refresh, chan_iax2_pvt::reg, sched, iax2_registry::us, iax_ies::username, and VERBOSE_PREFIX_3.

Referenced by socket_read().

05433 {
05434    struct iax2_registry *reg;
05435    /* Start pessimistic */
05436    char peer[256] = "";
05437    char msgstatus[40];
05438    int refresh = 0;
05439    char ourip[256] = "<Unspecified>";
05440    struct sockaddr_in oldus;
05441    struct sockaddr_in us;
05442    char iabuf[INET_ADDRSTRLEN];
05443    int oldmsgs;
05444 
05445    memset(&us, 0, sizeof(us));
05446    if (ies->apparent_addr)
05447       memcpy(&us, ies->apparent_addr, sizeof(us));
05448    if (ies->username)
05449       ast_copy_string(peer, ies->username, sizeof(peer));
05450    if (ies->refresh)
05451       refresh = ies->refresh;
05452    if (ies->calling_number) {
05453       /* We don't do anything with it really, but maybe we should */
05454    }
05455    reg = iaxs[callno]->reg;
05456    if (!reg) {
05457       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05458       return -1;
05459    }
05460    memcpy(&oldus, &reg->us, sizeof(oldus));
05461    oldmsgs = reg->messages;
05462    if (inaddrcmp(&reg->addr, sin)) {
05463       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05464       return -1;
05465    }
05466    memcpy(&reg->us, &us, sizeof(reg->us));
05467    reg->messages = ies->msgcount;
05468    /* always refresh the registration at the interval requested by the server
05469       we are registering to
05470    */
05471    reg->refresh = refresh;
05472    if (reg->expire > -1)
05473       ast_sched_del(sched, reg->expire);
05474    reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05475    if ((inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) && (option_verbose > 2)) {
05476       if (reg->messages > 65534)
05477          snprintf(msgstatus, sizeof(msgstatus), " with message(s) waiting\n");
05478       else if (reg->messages > 1)
05479          snprintf(msgstatus, sizeof(msgstatus), " with %d messages waiting\n", reg->messages);
05480       else if (reg->messages > 0)
05481          snprintf(msgstatus, sizeof(msgstatus), " with 1 message waiting\n");
05482       else
05483          snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05484       snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
05485       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);
05486       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));
05487    }
05488    reg->regstate = REG_STATE_REGISTERED;
05489    return 0;
05490 }

int iax2_answer struct ast_channel c  )  [static]
 

Definition at line 3332 of file chan_iax2.c.

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

03333 {
03334    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03335    if (option_debug)
03336       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03337    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03338 }

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

References ast_channel::_softhangup, AST_BRIDGE_DTMF_CHANNEL_0, ast_bridge_result, ast_check_hangup(), ast_frfree(), ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_verbose(), ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, ast_frame::frametype, iax2_start_transfer(), IAX_NOTRANSFER, iaxdebug, iaxs, iaxsl, lock_both(), LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_verbose, PTR_TO_CALLNO, ast_channel::tech_pvt, tv, ast_channel::type, unlock_both(), and VERBOSE_PREFIX_3.

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

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

Definition at line 2928 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_RINGING, ast_strdupa, ast_strlen_zero(), ast_test_flag, auto_congest(), autokill, CALLNO_TO_PTR, 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_info::context, create_addr(), chan_iax2_pvt::encmethods, create_addr_info::encmethods, iax2_datetime(), 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, iaxs, iaxsl, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, chan_iax2_pvt::outkey, create_addr_info::outkey, parse_dial_string(), create_addr_info::peercontext, chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, chan_iax2_pvt::secret, create_addr_info::secret, send_command(), ast_channel::tech_pvt, chan_iax2_pvt::username, and create_addr_info::username.

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

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

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

09105 {
09106    int res = 0;
09107    struct iax2_dpcache *dp;
09108 #if 0
09109    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09110 #endif
09111    if ((priority != 1) && (priority != 2))
09112       return 0;
09113    ast_mutex_lock(&dpcache_lock);
09114    dp = find_cache(chan, data, context, exten, priority);
09115    if (dp) {
09116       if (dp->flags & CACHE_FLAG_CANEXIST)
09117          res= 1;
09118    }
09119    ast_mutex_unlock(&dpcache_lock);
09120    if (!dp) {
09121       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09122    }
09123    return res;
09124 }

unsigned int iax2_datetime char *  tz  )  [static]
 

Definition at line 2841 of file chan_iax2.c.

References ast_localtime(), and ast_strlen_zero().

Referenced by iax2_call(), and update_registry().

02842 {
02843    time_t t;
02844    struct tm tm;
02845    unsigned int tmp;
02846    time(&t);
02847    localtime_r(&t, &tm);
02848    if (!ast_strlen_zero(tz))
02849       ast_localtime(&t, &tm, tz);
02850    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
02851    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
02852    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
02853    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
02854    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
02855    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
02856    return tmp;
02857 }

void iax2_destroy int  callno  )  [static]
 

Definition at line 1580 of file chan_iax2.c.

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

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

01581 {
01582    struct chan_iax2_pvt *pvt;
01583    struct iax_frame *cur;
01584    struct ast_channel *owner;
01585 
01586 retry:
01587    ast_mutex_lock(&iaxsl[callno]);
01588    pvt = iaxs[callno];
01589    gettimeofday(&lastused[callno], NULL);
01590 
01591    if (pvt)
01592       owner = pvt->owner;
01593    else
01594       owner = NULL;
01595    if (owner) {
01596       if (ast_mutex_trylock(&owner->lock)) {
01597          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01598          ast_mutex_unlock(&iaxsl[callno]);
01599          usleep(1);
01600          goto retry;
01601       }
01602    }
01603    if (!owner)
01604       iaxs[callno] = NULL;
01605    if (pvt) {
01606       if (!owner)
01607          pvt->owner = NULL;
01608       /* No more pings or lagrq's */
01609       if (pvt->pingid > -1)
01610          ast_sched_del(sched, pvt->pingid);
01611       if (pvt->lagid > -1)
01612          ast_sched_del(sched, pvt->lagid);
01613       if (pvt->autoid > -1)
01614          ast_sched_del(sched, pvt->autoid);
01615       if (pvt->authid > -1)
01616          ast_sched_del(sched, pvt->authid);
01617       if (pvt->initid > -1)
01618          ast_sched_del(sched, pvt->initid);
01619 #ifdef NEWJB
01620       if (pvt->jbid > -1)
01621          ast_sched_del(sched, pvt->jbid);
01622       pvt->jbid = -1;
01623 #endif
01624       pvt->pingid = -1;
01625       pvt->lagid = -1;
01626       pvt->autoid = -1;
01627       pvt->authid = -1;
01628       pvt->initid = -1;
01629       if (pvt->bridgetrans)
01630          ast_translator_free_path(pvt->bridgetrans);
01631       pvt->bridgetrans = NULL;
01632 
01633       /* Already gone */
01634       ast_set_flag(pvt, IAX_ALREADYGONE); 
01635 
01636       if (owner) {
01637          /* If there's an owner, prod it to give up */
01638          owner->_softhangup |= AST_SOFTHANGUP_DEV;
01639          ast_queue_hangup(owner);
01640       }
01641 
01642       for (cur = iaxq.head; cur ; cur = cur->next) {
01643          /* Cancel any pending transmissions */
01644          if (cur->callno == pvt->callno) 
01645             cur->retries = -1;
01646       }
01647       if (pvt->reg) {
01648          pvt->reg->callno = 0;
01649       }
01650       if (!owner) {
01651          if (pvt->vars) {
01652             ast_variables_destroy(pvt->vars);
01653             pvt->vars = NULL;
01654          }
01655 #ifdef NEWJB
01656          {
01657                             jb_frame frame;
01658                             while(jb_getall(pvt->jb,&frame) == JB_OK)
01659             iax2_frame_free(frame.data);
01660                             jb_destroy(pvt->jb);
01661                         }
01662 #endif
01663          free(pvt);
01664       }
01665    }
01666    if (owner) {
01667       ast_mutex_unlock(&owner->lock);
01668    }
01669    ast_mutex_unlock(&iaxsl[callno]);
01670    if (callno & 0x4000)
01671       update_max_trunk();
01672 }

void iax2_destroy_nolock int  callno  )  [static]
 

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

01674 {  
01675    /* Actually it's easier to unlock, kill it, and relock */
01676    ast_mutex_unlock(&iaxsl[callno]);
01677    iax2_destroy(callno);
01678    ast_mutex_lock(&iaxsl[callno]);
01679 }

int iax2_devicestate void *  data  )  [static]
 

Definition at line 9292 of file chan_iax2.c.

References iax2_peer::addr, ast_log(), ast_test_flag, iax2_peer::defaddr, destroy_peer(), find_peer(), iax2_peer::historicms, IAX_TEMPONLY, iax2_peer::lastms, LOG_DEBUG, iax2_peer::maxms, and option_debug.

09293 {
09294    char *dest = (char *) data;
09295    struct iax2_peer *p;
09296    int found = 0;
09297    char *ext, *host;
09298    char tmp[256];
09299    int res = AST_DEVICE_INVALID;
09300 
09301    ast_copy_string(tmp, dest, sizeof(tmp));
09302    host = strchr(tmp, '@');
09303    if (host) {
09304       *host = '\0';
09305       host++;
09306       ext = tmp;
09307    } else {
09308       host = tmp;
09309       ext = NULL;
09310    }
09311 
09312    if (option_debug > 2)
09313       ast_log(LOG_DEBUG, "Checking device state for device %s\n", dest);
09314 
09315    /* SLD: FIXME: second call to find_peer during registration */
09316    p = find_peer(host, 1);
09317    if (p) {
09318       found++;
09319       res = AST_DEVICE_UNAVAILABLE;
09320       if (option_debug > 2) 
09321          ast_log(LOG_DEBUG, "iax2_devicestate(%s): Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09322             host, dest, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09323 
09324       if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09325           (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09326          /* Peer is registered, or have default IP address
09327             and a valid registration */
09328          if (p->historicms == 0 || p->historicms <= p->maxms)
09329             /* let the core figure out whether it is in use or not */
09330             res = AST_DEVICE_UNKNOWN;  
09331       }
09332    } else {
09333       if (option_debug > 2) 
09334          ast_log(LOG_DEBUG, "Devicestate: Can't find peer %s.\n", host);
09335    }
09336    
09337    if (p && ast_test_flag(p, IAX_TEMPONLY))
09338       destroy_peer(p);
09339    return res;
09340 }

int iax2_digit struct ast_channel c,
char  digit
[static]
 

Definition at line 2530 of file chan_iax2.c.

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

02531 {
02532    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
02533 }

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

Definition at line 4557 of file chan_iax2.c.

References ast_cli(), and iaxdebug.

04558 {
04559    if (argc != 2)
04560       return RESULT_SHOWUSAGE;
04561    iaxdebug = 1;
04562    ast_cli(fd, "IAX2 Debugging Enabled\n");
04563    return RESULT_SUCCESS;
04564 }

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

Definition at line 4575 of file chan_iax2.c.

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

04576 {
04577    if (argc != 3)
04578       return RESULT_SHOWUSAGE;
04579 #ifdef NEWJB
04580    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04581 #endif
04582    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04583    return RESULT_SUCCESS;
04584 }

int iax2_do_register struct iax2_registry reg  )  [static]
 

Definition at line 7629 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, iaxs, LOG_DEBUG, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, sched, send_command(), and iax2_registry::username.

Referenced by iax2_do_register_s(), and load_module().

07630 {
07631    struct iax_ie_data ied;
07632    if (option_debug && iaxdebug)
07633       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07634    if (!reg->callno) {
07635       if (option_debug)
07636          ast_log(LOG_DEBUG, "Allocate call number\n");
07637       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
07638       if (reg->callno < 1) {
07639          ast_log(LOG_WARNING, "Unable to create call for registration\n");
07640          return -1;
07641       } else if (option_debug)
07642          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07643       iaxs[reg->callno]->reg = reg;
07644    }
07645    /* Schedule the next registration attempt */
07646    if (reg->expire > -1)
07647       ast_sched_del(sched, reg->expire);
07648    /* Setup the next registration a little early */
07649    reg->expire  = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07650    /* Send the request */
07651    memset(&ied, 0, sizeof(ied));
07652    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07653    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07654    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07655    reg->regstate = REG_STATE_REGSENT;
07656    return 0;
07657 }

int iax2_do_register_s void *  data  )  [static]
 

Definition at line 5278 of file chan_iax2.c.

References iax2_registry::expire, and iax2_do_register().

Referenced by iax2_ack_registry(), and iax2_do_register().

05279 {
05280    struct iax2_registry *reg = data;
05281    reg->expire = -1;
05282    iax2_do_register(reg);
05283    return 0;
05284 }

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

Definition at line 4566 of file chan_iax2.c.

References ast_cli(), and iaxtrunkdebug.

04567 {
04568    if (argc != 3)
04569       return RESULT_SHOWUSAGE;
04570    iaxtrunkdebug = 1;
04571    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04572    return RESULT_SUCCESS;
04573 }

void iax2_dprequest struct iax2_dpcache dp,
int  callno
[static]
 

Definition at line 5889 of file chan_iax2.c.

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

Referenced by find_cache(), and socket_read().

05890 {
05891    struct iax_ie_data ied;
05892    /* Auto-hangup with 30 seconds of inactivity */
05893    if (iaxs[callno]->autoid > -1)
05894       ast_sched_del(sched, iaxs[callno]->autoid);
05895    iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05896    memset(&ied, 0, sizeof(ied));
05897    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05898    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05899    dp->flags |= CACHE_FLAG_TRANSMITTED;
05900 }

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

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

09151 {
09152    char odata[256];
09153    char req[256];
09154    char *ncontext;
09155    char *dialstatus;
09156    struct iax2_dpcache *dp;
09157    struct ast_app *dial;
09158 #if 0
09159    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);
09160 #endif
09161    if (priority == 2) {
09162       /* Indicate status, can be overridden in dialplan */
09163       dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09164       if (dialstatus) {
09165          dial = pbx_findapp(dialstatus);
09166          if (dial) 
09167             pbx_exec(chan, dial, "", newstack);
09168       }
09169       return -1;
09170    } else if (priority != 1)
09171       return -1;
09172    ast_mutex_lock(&dpcache_lock);
09173    dp = find_cache(chan, data, context, exten, priority);
09174    if (dp) {
09175       if (dp->flags & CACHE_FLAG_EXISTS) {
09176          ast_copy_string(odata, data, sizeof(odata));
09177          ncontext = strchr(odata, '/');
09178          if (ncontext) {
09179             *ncontext = '\0';
09180             ncontext++;
09181             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09182          } else {
09183             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09184          }
09185          if (option_verbose > 2)
09186             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09187       } else {
09188          ast_mutex_unlock(&dpcache_lock);
09189          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09190          return -1;
09191       }
09192    }
09193    ast_mutex_unlock(&dpcache_lock);
09194    dial = pbx_findapp("Dial");
09195    if (dial) {
09196       return pbx_exec(chan, dial, req, newstack);
09197    } else {
09198       ast_log(LOG_WARNING, "No dial application registered\n");
09199    }
09200    return -1;
09201 }

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

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

09082 {
09083    struct iax2_dpcache *dp;
09084    int res = 0;
09085 #if 0
09086    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09087 #endif
09088    if ((priority != 1) && (priority != 2))
09089       return 0;
09090    ast_mutex_lock(&dpcache_lock);
09091    dp = find_cache(chan, data, context, exten, priority);
09092    if (dp) {
09093       if (dp->flags & CACHE_FLAG_EXISTS)
09094          res= 1;
09095    }
09096    ast_mutex_unlock(&dpcache_lock);
09097    if (!dp) {
09098       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09099    }
09100    return res;
09101 }

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

Definition at line 2552 of file chan_iax2.c.

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

02553 {
02554    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02555    ast_mutex_lock(&iaxsl[callno]);
02556    if (iaxs[callno])
02557       iaxs[callno]->owner = newchan;
02558    else
02559       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02560    ast_mutex_unlock(&iaxsl[callno]);
02561    return 0;
02562 }

void iax2_frame_free struct iax_frame fr  )  [static]
 

Definition at line 1113 of file chan_iax2.c.

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

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

01114 {
01115    if (fr->retrans > -1)
01116       ast_sched_del(sched, fr->retrans);
01117    iax_frame_free(fr);
01118 }

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

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

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

int iax2_getpeertrunk struct sockaddr_in  sin  )  [static]
 

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

03372 {
03373    struct iax2_peer *peer;
03374    int res = 0;
03375    ast_mutex_lock(&peerl.lock);
03376    peer = peerl.peers;
03377    while(peer) {
03378       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03379             (peer->addr.sin_port == sin.sin_port)) {
03380                res = ast_test_flag(peer, IAX_TRUNK);
03381                break;
03382       }
03383       peer = peer->next;
03384    }
03385    ast_mutex_unlock(&peerl.lock);
03386    return res;
03387 }

int iax2_hangup struct ast_channel c  )  [static]
 

Definition at line 3059 of file chan_iax2.c.

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

03060 {
03061    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03062    int alreadygone;
03063    struct iax_ie_data ied;
03064    memset(&ied, 0, sizeof(ied));
03065    ast_mutex_lock(&iaxsl[callno]);
03066    if (callno && iaxs[callno]) {
03067       ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03068       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03069       /* Send the hangup unless we have had a transmission error or are already gone */
03070       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03071       if (!iaxs[callno]->error && !alreadygone) 
03072          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03073       /* Explicitly predestroy it */
03074       iax2_predestroy_nolock(callno);
03075       /* If we were already gone to begin with, destroy us now */
03076       if (alreadygone) {
03077          ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03078          iax2_destroy_nolock(callno);
03079       }
03080    }
03081    ast_mutex_unlock(&iaxsl[callno]);
03082    if (option_verbose > 2) 
03083       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03084    return 0;
03085 }

int iax2_indicate struct ast_channel c,
int  condition
[static]
 

Definition at line 3340 of file chan_iax2.c.

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

03341 {
03342    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03343    if (option_debug && iaxdebug)
03344       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03345    return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, NULL, 0, -1);
03346 }

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

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

09128 {
09129    int res = 0;
09130    struct iax2_dpcache *dp;
09131 #if 0
09132    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09133 #endif
09134    if ((priority != 1) && (priority != 2))
09135       return 0;
09136    ast_mutex_lock(&dpcache_lock);
09137    dp = find_cache(chan, data, context, exten, priority);
09138    if (dp) {
09139       if (dp->flags & CACHE_FLAG_MATCHMORE)
09140          res= 1;
09141    }
09142    ast_mutex_unlock(&dpcache_lock);
09143    if (!dp) {
09144       ast_log(LOG_WARNING, "Unable to make DP cache\n");
09145    }
09146    return res;
09147 }

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

Definition at line 4586 of file chan_iax2.c.

References ast_cli(), and iaxdebug.

04587 {
04588    if (argc != 3)
04589       return RESULT_SHOWUSAGE;
04590    iaxdebug = 0;
04591    ast_cli(fd, "IAX2 Debugging Disabled\n");
04592    return RESULT_SUCCESS;
04593 }

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

Definition at line 4604 of file chan_iax2.c.

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

04605 {
04606    if (argc != 4)
04607       return RESULT_SHOWUSAGE;
04608 #ifdef NEWJB
04609    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04610    jb_debug_output("\n");
04611 #endif
04612    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04613    return RESULT_SUCCESS;
04614 }

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

Definition at line 4595 of file chan_iax2.c.

References ast_cli(), and iaxtrunkdebug.

04596 {
04597    if (argc != 4)
04598       return RESULT_SHOWUSAGE;
04599    iaxtrunkdebug = 0;
04600    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04601    return RESULT_SUCCESS;
04602 }

int iax2_poke_noanswer void *  data  )  [static]
 

Definition at line 7780 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, iax2_peer::pokefreqnotok, and sched.

Referenced by iax2_poke_peer().

07781 {
07782    struct iax2_peer *peer = data;
07783    peer->pokeexpire = -1;
07784    if (peer->lastms > -1) {
07785       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07786       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07787       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07788    }
07789    if (peer->callno > 0)
07790       iax2_destroy(peer->callno);
07791    peer->callno = 0;
07792    peer->lastms = -1;
07793    /* Try again quickly */
07794    peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07795    return 0;
07796 }

int iax2_poke_peer struct iax2_peer peer,
int  heldcall
[static]
 

Definition at line 7798 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, iaxs, 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, sched, send_command(), and iax2_peer::sockfd.

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

07799 {
07800    if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07801       /* IF we have no IP, or this isn't to be monitored, return
07802         imeediately after clearing things out */
07803       peer->lastms = 0;
07804       peer->historicms = 0;
07805       peer->pokeexpire = -1;
07806       peer->callno = 0;
07807       return 0;
07808    }
07809    if (peer->callno > 0) {
07810       ast_log(LOG_NOTICE, "Still have a callno...\n");
07811       iax2_destroy(peer->callno);
07812    }
07813    if (heldcall)
07814       ast_mutex_unlock(&iaxsl[heldcall]);
07815    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
07816    if (heldcall)
07817       ast_mutex_lock(&iaxsl[heldcall]);
07818    if (peer->callno < 1) {
07819       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
07820       return -1;
07821    }
07822    if (peer->pokeexpire > -1)
07823       ast_sched_del(sched, peer->pokeexpire);
07824    /* Speed up retransmission times */
07825    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
07826    iaxs[peer->callno]->peerpoke = peer;
07827    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
07828    
07829    /* If the host is already unreachable then use the unreachable interval instead */
07830    if (peer->lastms < 0) {
07831       peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
07832    } else
07833       peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
07834 
07835    return 0;
07836 }

int iax2_poke_peer_s void *  data  )  [static]
 

Definition at line 5923 of file chan_iax2.c.

References iax2_poke_peer(), and iax2_peer::pokeexpire.

Referenced by iax2_poke_noanswer(), and socket_read().

05924 {
05925    struct iax2_peer *peer = data;
05926    peer->pokeexpire = -1;
05927    iax2_poke_peer(peer, 0);
05928    return 0;
05929 }

int iax2_predestroy int  callno  )  [static]
 

Definition at line 1520 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_test_flag, ast_update_use_count(), chan_iax2_pvt::authid, chan_iax2_pvt::autoid, IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, LOG_WARNING, chan_iax2_pvt::owner, chan_iax2_pvt::pingid, sched, ast_channel::tech_pvt, and usecnt.

Referenced by iax2_predestroy_nolock().

01521 {
01522    struct ast_channel *c;
01523    struct chan_iax2_pvt *pvt;
01524    ast_mutex_lock(&iaxsl[callno]);
01525    pvt = iaxs[callno];
01526    if (!pvt) {
01527       ast_mutex_unlock(&iaxsl[callno]);
01528       return -1;
01529    }
01530    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01531       /* No more pings or lagrq's */
01532       if (pvt->pingid > -1)
01533          ast_sched_del(sched, pvt->pingid);
01534       if (pvt->lagid > -1)
01535          ast_sched_del(sched, pvt->lagid);
01536       if (pvt->autoid > -1)
01537          ast_sched_del(sched, pvt->autoid);
01538       if (pvt->authid > -1)
01539          ast_sched_del(sched, pvt->authid);
01540       if (pvt->initid > -1)
01541          ast_sched_del(sched, pvt->initid);
01542 #ifdef NEWJB
01543       if (pvt->jbid > -1)
01544          ast_sched_del(sched, pvt->jbid);
01545       pvt->jbid = -1;
01546 #endif
01547       pvt->pingid = -1;
01548       pvt->lagid = -1;
01549       pvt->autoid = -1;
01550       pvt->initid = -1;
01551       pvt->authid = -1;
01552       ast_set_flag(pvt, IAX_ALREADYGONE); 
01553    }
01554    c = pvt->owner;
01555    if (c) {
01556       c->_softhangup |= AST_SOFTHANGUP_DEV;
01557       c->tech_pvt = NULL;
01558       ast_queue_hangup(c);
01559       pvt->owner = NULL;
01560       ast_mutex_lock(&usecnt_lock);
01561       usecnt--;
01562       if (usecnt < 0) 
01563          ast_log(LOG_WARNING, "Usecnt < 0???\n");
01564       ast_mutex_unlock(&usecnt_lock);
01565    }
01566    ast_mutex_unlock(&iaxsl[callno]);
01567    ast_update_use_count();
01568    return 0;
01569 }

int iax2_predestroy_nolock int  callno  )  [static]
 

Definition at line 1571 of file chan_iax2.c.

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

Referenced by iax2_hangup(), and send_command_final().

01572 {
01573    int res;
01574    ast_mutex_unlock(&iaxsl[callno]);
01575    res = iax2_predestroy(callno);
01576    ast_mutex_lock(&iaxsl[callno]);
01577    return res;
01578 }

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

Definition at line 7758 of file chan_iax2.c.

References ast_cli(), and iax2_provision().

07759 {
07760    int force = 0;
07761    int res;
07762    if (argc < 4)
07763       return RESULT_SHOWUSAGE;
07764    if ((argc > 4)) {
07765       if (!strcasecmp(argv[4], "forced"))
07766          force = 1;
07767       else
07768          return RESULT_SHOWUSAGE;
07769    }
07770    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07771    if (res < 0)
07772       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07773    else if (res < 1)
07774       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07775    else
07776       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07777    return RESULT_SUCCESS;
07778 }

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

Definition at line 7659 of file chan_iax2.c.

References iax_prov_complete_template().

07660 {
07661    if (pos != 3)
07662       return NULL;
07663    return iax_prov_complete_template(line, word, pos, state);
07664 }

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

Definition at line 7666 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(), iaxs, iaxsl, LOG_DEBUG, NEW_FORCE, iax_ie_data::pos, sched, send_command(), and create_addr_info::sockfd.

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

07667 {
07668    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
07669       is found for template */
07670    struct iax_ie_data provdata;
07671    struct iax_ie_data ied;
07672    unsigned int sig;
07673    struct sockaddr_in sin;
07674    int callno;
07675    struct create_addr_info cai;
07676 
07677    memset(&cai, 0, sizeof(cai));
07678 
07679    if (option_debug)
07680       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07681 
07682    if (iax_provision_build(&provdata, &sig, template, force)) {
07683       ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07684       return 0;
07685    }
07686 
07687    if (end) {
07688       memcpy(&sin, end, sizeof(sin));
07689       cai.sockfd = sockfd;
07690    } else if (create_addr(dest, &sin, &cai))
07691       return -1;
07692 
07693    /* Build the rest of the message */
07694    memset(&ied, 0, sizeof(ied));
07695    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07696 
07697    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07698    if (!callno)
07699       return -1;
07700 
07701    ast_mutex_lock(&iaxsl[callno]);
07702    if (iaxs[callno]) {
07703       /* Schedule autodestruct in case they don't ever give us anything back */
07704       if (iaxs[callno]->autoid > -1)
07705          ast_sched_del(sched, iaxs[callno]->autoid);
07706       iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07707       ast_set_flag(iaxs[callno], IAX_PROVISION);
07708       /* Got a call number now, so go ahead and send the provisioning information */
07709       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07710    }
07711    ast_mutex_unlock(&iaxsl[callno]);
07712 
07713    return 1;
07714 }

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

Definition at line 1819 of file chan_iax2.c.

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

01820 {
01821    struct iax2_peer *peer;
01822 
01823    if (argc != 4)
01824         return RESULT_SHOWUSAGE;
01825    if (!strcmp(argv[3],"all")) {
01826       reload_config();
01827       ast_cli(fd, "OK cache is flushed.\n");
01828    } else if ((peer = find_peer(argv[3], 0))) {
01829       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
01830          ast_set_flag(peer, IAX_RTAUTOCLEAR);
01831          expire_registry(peer);
01832          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
01833       } else {
01834          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
01835       }
01836    } else {
01837       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
01838    }
01839    
01840    return RESULT_SUCCESS;
01841 }

int iax2_queue_frame int  callno,
struct ast_frame f
[static]
 

Definition at line 1120 of file chan_iax2.c.

References ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), iaxs, iaxsl, and chan_iax2_pvt::owner.

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

01121 {
01122    /* Assumes lock for callno is already held... */
01123    for (;;) {
01124       if (iaxs[callno] && iaxs[callno]->owner) {
01125          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01126             /* Avoid deadlock by pausing and trying again */
01127             ast_mutex_unlock(&iaxsl[callno]);
01128             usleep(1);
01129             ast_mutex_lock(&iaxsl[callno]);
01130          } else {
01131             ast_queue_frame(iaxs[callno]->owner, f);
01132             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01133             break;
01134          }
01135       } else
01136          break;
01137    }
01138    return 0;
01139 }

struct ast_frame * iax2_read struct ast_channel c  )  [static]
 

Definition at line 3116 of file chan_iax2.c.

References ast_log(), and LOG_NOTICE.

03117 {
03118    static struct ast_frame f = { AST_FRAME_NULL, };
03119    ast_log(LOG_NOTICE, "I should never be called!\n");
03120    return &f;
03121 }

int iax2_register char *  value,
int  lineno
[static]
 

Definition at line 5492 of file chan_iax2.c.

References iax2_registry::addr, ahp, ast_gethostbyname(), ast_log(), iax2_registry::callno, iax2_registry::expire, hp, IAX_DEFAULT_PORTNO, LOG_ERROR, LOG_WARNING, malloc, iax2_registry::next, iax2_registry::refresh, registrations, iax2_registry::secret, strsep(), and iax2_registry::username.

Referenced by set_config().

05493 {
05494    struct iax2_registry *reg;
05495    char copy[256];
05496    char *username, *hostname, *secret;
05497    char *porta;
05498    char *stringp=NULL;
05499    
05500    struct ast_hostent ahp; struct hostent *hp;
05501    if (!value)
05502       return -1;
05503    ast_copy_string(copy, value, sizeof(copy));
05504    stringp=copy;
05505    username = strsep(&stringp, "@");
05506    hostname = strsep(&stringp, "@");
05507    if (!hostname) {
05508       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
05509       return -1;
05510    }
05511    stringp=username;
05512    username = strsep(&stringp, ":");
05513    secret = strsep(&stringp, ":");
05514    stringp=hostname;
05515    hostname = strsep(&stringp, ":");
05516    porta = strsep(&stringp, ":");
05517    
05518    if (porta && !atoi(porta)) {
05519       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05520       return -1;
05521    }
05522    hp = ast_gethostbyname(hostname, &ahp);
05523    if (!hp) {
05524       ast_log(LOG_WARNING, "Host '%s' not found at line %d\n", hostname, lineno);
05525       return -1;
05526    }
05527    reg = malloc(sizeof(struct iax2_registry));
05528    if (reg) {
05529       memset(reg, 0, sizeof(struct iax2_registry));
05530       ast_copy_string(reg->username, username, sizeof(reg->username));
05531       if (secret)
05532          ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05533       reg->expire = -1;
05534       reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05535       reg->addr.sin_family = AF_INET;
05536       memcpy(&reg->addr.sin_addr, hp->h_addr, sizeof(&reg->addr.sin_addr));
05537       reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05538       reg->next = registrations;
05539       reg->callno = 0;
05540       registrations = reg;
05541    } else {
05542       ast_log(LOG_ERROR, "Out of memory\n");
05543       return -1;
05544    }
05545    return 0;
05546 }

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

Definition at line 8853 of file chan_iax2.c.

References reload_config().

08854 {
08855    return reload_config();
08856 }

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

Definition at line 7848 of file chan_iax2.c.

References ast_best_codec(), 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_info::capability, create_addr(), find_callno(), fmt, globalflags, chan_iax2_pvt::host, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.

07849 {
07850    int callno;
07851    int res;
07852    int fmt, native;
07853    struct sockaddr_in sin;
07854    struct ast_channel *c;
07855    struct parsed_dial_string pds;
07856    struct create_addr_info cai;
07857    char *tmpstr;
07858 
07859    memset(&pds, 0, sizeof(pds));
07860    tmpstr = ast_strdupa(data);
07861    parse_dial_string(tmpstr, &pds);
07862 
07863    memset(&cai, 0, sizeof(cai));
07864    cai.capability = iax2_capability;
07865 
07866    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
07867 
07868    if (!pds.peer) {
07869       ast_log(LOG_WARNING, "No peer given\n");
07870       return NULL;
07871    }
07872           
07873    
07874    /* Populate our address from the given */
07875    if (create_addr(pds.peer, &sin, &cai)) {
07876       *cause = AST_CAUSE_UNREGISTERED;
07877       return NULL;
07878    }
07879 
07880    if (pds.port)
07881       sin.sin_port = htons(atoi(pds.port));
07882 
07883    callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07884    if (callno < 1) {
07885       ast_log(LOG_WARNING, "Unable to create call\n");
07886       *cause = AST_CAUSE_CONGESTION;
07887       return NULL;
07888    }
07889 
07890    ast_mutex_lock(&iaxsl[callno]);
07891 
07892    /* If this is a trunk, update it now */
07893    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
07894    if (ast_test_flag(&cai, IAX_TRUNK))
07895       callno = make_trunk(callno, 1);
07896    iaxs[callno]->maxtime = cai.maxtime;
07897    if (cai.found)
07898       ast_copy_string(iaxs[callno]->host, pds.peer, sizeof(iaxs[callno]->host));
07899 
07900    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
07901 
07902    ast_mutex_unlock(&iaxsl[callno]);
07903 
07904    if (c) {
07905       /* Choose a format we can live with */
07906       if (c->nativeformats & format) 
07907          c->nativeformats &= format;
07908       else {
07909          native = c->nativeformats;
07910          fmt = format;
07911          res = ast_translator_best_choice(&fmt, &native);
07912          if (res < 0) {
07913             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
07914                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
07915             ast_hangup(c);
07916             return NULL;
07917          }
07918          c->nativeformats = native;
07919       }
07920       c->readformat = ast_best_codec(c->nativeformats);
07921       c->writeformat = c->readformat;
07922    }
07923 
07924    return c;
07925 }

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

References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, 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, chan_iax2_pvt::ecx, encrypt_frame(), iax_frame::final, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::lastsent, LOG_WARNING, 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, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, 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().

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

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

Definition at line 2547 of file chan_iax2.c.

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

02548 {
02549    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02550 }

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

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

02543 {
02544    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02545 }

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

Definition at line 2535 of file chan_iax2.c.

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

02536 {
02537    
02538    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02539       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02540 }

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

Definition at line 1783 of file chan_iax2.c.

References ast_cli(), iaxs, and max_jitter_buffer.

01784 {
01785 #ifdef NEWJB
01786    ast_cli(fd, "sorry, this command is deprecated\n");
01787    return RESULT_SUCCESS;
01788 #else
01789    if ((argc != 4) && (argc != 5))
01790       return RESULT_SHOWUSAGE;
01791    if (argc == 4) {
01792       max_jitter_buffer = atoi(argv[3]);
01793       if (max_jitter_buffer < 0)
01794          max_jitter_buffer = 0;
01795    } else {
01796       if (argc == 5) {
01797          if ((atoi(argv[3]) >= 0) && (atoi(argv[3]) < IAX_MAX_CALLS)) {
01798             if (iaxs[atoi(argv[3])]) {
01799                iaxs[atoi(argv[3])]->jitterbuffer = atoi(argv[4]);
01800                if (iaxs[atoi(argv[3])]->jitterbuffer < 0)
01801                   iaxs[atoi(argv[3])]->jitterbuffer = 0;
01802             } else
01803                ast_cli(fd, "No such call '%d'\n", atoi(argv[3]));
01804          } else
01805             ast_cli(fd, "%d is not a valid call number\n", atoi(argv[3]));
01806       }
01807    }
01808    return RESULT_SUCCESS;
01809 #endif
01810 }

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

Definition at line 3087 of file chan_iax2.c.

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

03088 {
03089    struct ast_option_header *h;
03090    int res;
03091 
03092    switch (option) {
03093    case AST_OPTION_TXGAIN:
03094    case AST_OPTION_RXGAIN:
03095       /* these two cannot be sent, because they require a result */
03096       errno = ENOSYS;
03097       return -1;
03098    default:
03099       h = malloc(datalen + sizeof(*h));
03100       if (h) {
03101          h->flag = AST_OPTION_FLAG_REQUEST;
03102          h->option = htons(option);
03103          memcpy(h->data, data, datalen);
03104          res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03105                     AST_CONTROL_OPTION, 0, (unsigned char *) h,
03106                     datalen + sizeof(*h), -1);
03107          free(h);
03108          return res;
03109       } else {
03110          ast_log(LOG_WARNING, "Out of memory\n");
03111          return -1;
03112       }
03113    }
03114 }

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

Definition at line 2016 of file chan_iax2.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, s, tv, and iax2_dpcache::waiters.

02017 {
02018    struct iax2_dpcache *dp;
02019    char tmp[1024], *pc;
02020    int s;
02021    int x,y;
02022    struct timeval tv;
02023    gettimeofday(&tv, NULL);
02024    ast_mutex_lock(&dpcache_lock);
02025    dp = dpcache;
02026    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02027    while(dp) {
02028       s = dp->expiry.tv_sec - tv.tv_sec;
02029       tmp[0] = '\0';
02030       if (dp->flags & CACHE_FLAG_EXISTS)
02031          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02032       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02033          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02034       if (dp->flags & CACHE_FLAG_CANEXIST)
02035          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02036       if (dp->flags & CACHE_FLAG_PENDING)
02037          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02038       if (dp->flags & CACHE_FLAG_TIMEOUT)
02039          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02040       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02041          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02042       if (dp->flags & CACHE_FLAG_MATCHMORE)
02043          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02044       if (dp->flags & CACHE_FLAG_UNKNOWN)
02045          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02046       /* Trim trailing pipe */
02047       if (!ast_strlen_zero(tmp))
02048          tmp[strlen(tmp) - 1] = '\0';
02049       else
02050          ast_copy_string(tmp, "(none)", sizeof(tmp));
02051       y=0;
02052       pc = strchr(dp->peercontext, '@');
02053       if (!pc)
02054          pc = dp->peercontext;
02055       else
02056          pc++;
02057       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02058          if (dp->waiters[x] > -1)
02059             y++;
02060       if (s > 0)
02061          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02062       else
02063          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02064       dp = dp->next;
02065    }
02066    ast_mutex_unlock(&dpcache_lock);
02067    return RESULT_SUCCESS;
02068 }

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

Definition at line 4399 of file chan_iax2.c.

References ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, chan_iax2_pvt::bridgecallno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, FORMATB, IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, jb_info::min, and chan_iax2_pvt::remote_rr.

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

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

Definition at line 4296 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, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.

04297 {
04298 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04299 #if !defined(__FreeBSD__)
04300 #define FORMAT "%-15.15s  %-15d %-15d\n"
04301 #else /* __FreeBSD__ */
04302 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04303 #endif /* __FreeBSD__ */
04304    struct iax_firmware *cur;
04305    if ((argc != 3) && (argc != 4))
04306       return RESULT_SHOWUSAGE;
04307    ast_mutex_lock(&waresl.lock);
04308    
04309    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04310    for (cur = waresl.wares;cur;cur = cur->next) {
04311       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04312          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04313             (int)ntohl(cur->fwh->datalen));
04314    }
04315    ast_mutex_unlock(&waresl.lock);
04316    return RESULT_SUCCESS;
04317 #undef FORMAT
04318 #undef FORMAT2
04319 }

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

Definition at line 4545 of file chan_iax2.c.

References ast_cli(), and ast_cli_netstats().

04546 {
04547    int numchans = 0;
04548    if (argc != 3)
04549       return RESULT_SHOWUSAGE;
04550    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04551    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04552    numchans = ast_cli_netstats(fd, 1);
04553    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04554    return RESULT_SUCCESS;
04555 }

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

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

01913 {
01914    char status[30];
01915    char cbuf[256];
01916    char iabuf[INET_ADDRSTRLEN];
01917    struct iax2_peer *peer;
01918    char codec_buf[512];
01919    int x = 0, codec = 0, load_realtime = 0;
01920 
01921    if (argc < 4)
01922       return RESULT_SHOWUSAGE;
01923 
01924    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
01925 
01926    peer = find_peer(argv[3], load_realtime);
01927    if (peer) {
01928       ast_cli(fd,"\n\n");
01929       ast_cli(fd, "  * Name       : %s\n", peer->name);
01930       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
01931       ast_cli(fd, "  Context      : %s\n", peer->context);
01932       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
01933       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
01934       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
01935       ast_cli(fd, "  Expire       : %d\n", peer->expire);
01936       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
01937       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));
01938       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
01939       ast_cli(fd, "  Username     : %s\n", peer->username);
01940       ast_cli(fd, "  Codecs       : ");
01941       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
01942       ast_cli(fd, "%s\n", codec_buf);
01943 
01944       ast_cli(fd, "  Codec Order  : (");
01945       for(x = 0; x < 32 ; x++) {
01946          codec = ast_codec_pref_index(&peer->prefs,x);
01947          if(!codec)
01948             break;
01949          ast_cli(fd, "%s", ast_getformatname(codec));
01950          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
01951             ast_cli(fd, "|");
01952       }
01953 
01954       if (!x)
01955          ast_cli(fd, "none");
01956       ast_cli(fd, ")\n");
01957 
01958       ast_cli(fd, "  Status       : ");
01959       peer_status(peer, status, sizeof(status));   
01960       ast_cli(fd, "%s\n",status);
01961       ast_cli(fd, " Qualify        : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
01962       ast_cli(fd,"\n");
01963       if (ast_test_flag(peer, IAX_TEMPONLY))
01964          destroy_peer(peer);
01965    } else {
01966       ast_cli(fd,"Peer %s not found.\n", argv[3]);
01967       ast_cli(fd,"\n");
01968    }
01969 
01970    return RESULT_SUCCESS;
01971 }

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

Definition at line 4285 of file chan_iax2.c.

References __iax2_show_peers().

04286 {
04287    return __iax2_show_peers(0, fd, argc, argv);
04288 }

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

Definition at line 4357 of file chan_iax2.c.

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

04358 {
04359 #define FORMAT2 "%-20.20s  %-10.10s  %-20.20s %8.8s  %s\n"
04360 #define FORMAT "%-20.20s  %-10.10s  %-20.20s %8d  %s\n"
04361    struct iax2_registry *reg;
04362    char host[80];
04363    char perceived[80];
04364    char iabuf[INET_ADDRSTRLEN];
04365    if (argc != 3)
04366       return RESULT_SHOWUSAGE;
04367    ast_mutex_lock(&peerl.lock);
04368    ast_cli(fd, FORMAT2, "Host", "Username", "Perceived", "Refresh", "State");
04369    for (reg = registrations;reg;reg = reg->next) {
04370       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04371       if (reg->us.sin_addr.s_addr) 
04372          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), reg->us.sin_addr), ntohs(reg->us.sin_port));
04373       else
04374          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04375       ast_cli(fd, FORMAT, host, 
04376                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04377    }
04378    ast_mutex_unlock(&peerl.lock);
04379    return RESULT_SUCCESS;
04380 #undef FORMAT
04381 #undef FORMAT2
04382 }

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

Definition at line 1996 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, and iax_frame::retries.

01997 {
01998    struct iax_frame *cur;
01999    int cnt = 0, dead=0, final=0;
02000    if (argc != 3)
02001       return RESULT_SHOWUSAGE;
02002    for (cur = iaxq.head; cur ; cur = cur->next) {
02003       if (cur->retries < 0)
02004          dead++;
02005       if (cur->final)
02006          final++;
02007       cnt++;
02008    }
02009    ast_cli(fd, "    IAX Statistics\n");
02010    ast_cli(fd, "---------------------\n");
02011    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02012    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
02013    return RESULT_SUCCESS;
02014 }

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

Definition at line 4118 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, iax2_user::secret, userl, and ast_user_list::users.

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

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

Definition at line 3123 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, iaxs, and send_command().

Referenced by iax2_bridge().

03124 {
03125    int res;
03126    struct iax_ie_data ied0;
03127    struct iax_ie_data ied1;
03128    unsigned int transferid = rand();
03129    memset(&ied0, 0, sizeof(ied0));
03130    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03131    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03132    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03133 
03134    memset(&ied1, 0, sizeof(ied1));
03135    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03136    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03137    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03138    
03139    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03140    if (res)
03141       return -1;
03142    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03143    if (res)
03144       return -1;
03145    iaxs[callno0]->transferring = TRANSFER_BEGIN;
03146    iaxs[callno1]->transferring = TRANSFER_BEGIN;
03147    return 0;
03148 }

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

Definition at line 1843 of file chan_iax2.c.

References test_losspct.

01844 {
01845        if (argc != 4)
01846                return RESULT_SHOWUSAGE;
01847 
01848        test_losspct = atoi(argv[3]);
01849 
01850        return RESULT_SUCCESS;
01851 }

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

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

03349 {
03350    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03351    struct iax_ie_data ied;
03352    char tmp[256], *context;
03353    ast_copy_string(tmp, dest, sizeof(tmp));
03354    context = strchr(tmp, '@');
03355    if (context) {
03356       *context = '\0';
03357       context++;
03358    }
03359    memset(&ied, 0, sizeof(ied));
03360    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03361    if (context)
03362       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03363    if (option_debug)
03364       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03365    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03366 }

int iax2_transmit struct iax_frame fr  )  [static]
 

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

02503 {
02504    /* Lock the queue and place this packet at the end */
02505    fr->next = NULL;
02506    fr->prev = NULL;
02507    /* By setting this to 0, the network thread will send it for us, and
02508       queue retransmission if necessary */
02509    fr->sentyet = 0;
02510    ast_mutex_lock(&iaxq.lock);
02511    if (!iaxq.head) {
02512       /* Empty queue */
02513       iaxq.head = fr;
02514       iaxq.tail = fr;
02515    } else {
02516       /* Double link */
02517       iaxq.tail->next = fr;
02518       fr->prev = iaxq.tail;
02519       iaxq.tail = fr;
02520    }
02521    iaxq.count++;
02522    ast_mutex_unlock(&iaxq.lock);
02523    /* Wake up the network thread */
02524    pthread_kill(netthreadid, SIGURG);
02525    return 0;
02526 }

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

Definition at line 5974 of file chan_iax2.c.

References iax2_trunk_peer::trunkact.

Referenced by timing_read().

05975 {
05976    /* Drop when trunk is about 5 seconds idle */
05977    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
05978       return 1;
05979    return 0;
05980 }

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

Definition at line 3720 of file chan_iax2.c.

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

03721 {
03722    struct ast_frame *f;
03723    struct iax2_trunk_peer *tpeer;
03724    void *tmp, *ptr;
03725    struct ast_iax2_meta_trunk_entry *met;
03726    struct ast_iax2_meta_trunk_mini *mtm;
03727    char iabuf[INET_ADDRSTRLEN];
03728 
03729    f = &fr->af;
03730    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03731    if (tpeer) {
03732       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03733          /* Need to reallocate space */
03734          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03735             tmp = realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE);
03736             if (tmp) {
03737                tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03738                tpeer->trunkdata = tmp;
03739                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);
03740             } else {
03741                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));
03742                ast_mutex_unlock(&tpeer->lock);
03743                return -1;
03744             }
03745          } else {
03746             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));
03747             ast_mutex_unlock(&tpeer->lock);
03748             return -1;
03749          }
03750       }
03751 
03752       /* Append to meta frame */
03753       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03754       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03755          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03756          mtm->len = htons(f->datalen);
03757          mtm->mini.callno = htons(pvt->callno);
03758          mtm->mini.ts = htons(0xffff & fr->ts);
03759          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03760          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03761       } else {
03762          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03763          /* Store call number and length in meta header */
03764          met->callno = htons(pvt->callno);
03765          met->len = htons(f->datalen);
03766          /* Advance pointers/decrease length past trunk entry header */
03767          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03768          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03769       }
03770       /* Copy actual trunk data */
03771       memcpy(ptr, f->data, f->datalen);
03772       tpeer->trunkdatalen += f->datalen;
03773 
03774       tpeer->calls++;
03775       ast_mutex_unlock(&tpeer->lock);
03776    }
03777    return 0;
03778 }

int iax2_vnak int  callno  )  [static]
 

Definition at line 5902 of file chan_iax2.c.

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

Referenced by socket_read().

05903 {
05904    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
05905 }

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

Definition at line 4616 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, chan_iax2_pvt::error, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, LOG_DEBUG, PTR_TO_CALLNO, and ast_channel::tech_pvt.

04617 {
04618    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04619    int res = -1;
04620    ast_mutex_lock(&iaxsl[callno]);
04621    if (iaxs[callno]) {
04622    /* If there's an outstanding error, return failure now */
04623       if (!iaxs[callno]->error) {
04624          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04625             res = 0;
04626             /* Don't waste bandwidth sending null frames */
04627          else if (f->frametype == AST_FRAME_NULL)
04628             res = 0;
04629          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04630             res = 0;
04631          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04632             res = 0;
04633          else
04634          /* Simple, just queue for transmission */
04635             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04636       } else {
04637          ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04638       }
04639    }
04640    /* If it's already gone, just return */
04641    ast_mutex_unlock(&iaxsl[callno]);
04642    return res;
04643 }

int iax_check_version char *  dev  )  [static]
 

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

01299 {
01300    int res = 0;
01301    struct iax_firmware *cur;
01302    if (!ast_strlen_zero(dev)) {
01303       ast_mutex_lock(&waresl.lock);
01304       cur = waresl.wares;
01305       while(cur) {
01306          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01307             res = ntohs(cur->fwh->version);
01308             break;
01309          }
01310          cur = cur->next;
01311       }
01312       ast_mutex_unlock(&waresl.lock);
01313    }
01314    return res;
01315 }

void iax_debug_output const char *  data  )  [static]
 

Definition at line 658 of file chan_iax2.c.

References ast_verbose().

Referenced by load_module().

00659 {
00660    if (iaxdebug)
00661       ast_verbose("%s", data);
00662 }

void iax_error_output const char *  data  )  [static]
 

Definition at line 664 of file chan_iax2.c.

References ast_log(), and LOG_WARNING.

Referenced by load_module().

00665 {
00666    ast_log(LOG_WARNING, "%s", data);
00667 }

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

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

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

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

Definition at line 6153 of file chan_iax2.c.

References ast_channel_alloc(), ast_channel_masquerade(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create, iax_dual::chan1, 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().

06154 {
06155    struct iax_dual *d;
06156    struct ast_channel *chan1m, *chan2m;
06157    pthread_t th;
06158    chan1m = ast_channel_alloc(0);
06159    chan2m = ast_channel_alloc(0);
06160    if (chan2m && chan1m) {
06161       snprintf(chan1m->name, sizeof(chan1m->name), "Parking/%s", chan1->name);
06162       /* Make formats okay */
06163       chan1m->readformat = chan1->readformat;
06164       chan1m->writeformat = chan1->writeformat;
06165       ast_channel_masquerade(chan1m, chan1);
06166       /* Setup the extensions and such */
06167       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06168       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06169       chan1m->priority = chan1->priority;
06170       
06171       /* We make a clone of the peer channel too, so we can play
06172          back the announcement */
06173       snprintf(chan2m->name, sizeof (chan2m->name), "IAXPeer/%s",chan2->name);
06174       /* Make formats okay */
06175       chan2m->readformat = chan2->readformat;
06176       chan2m->writeformat = chan2->writeformat;
06177       ast_channel_masquerade(chan2m, chan2);
06178       /* Setup the extensions and such */
06179       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06180       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06181       chan2m->priority = chan2->priority;
06182       if (ast_do_masquerade(chan2m)) {
06183          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06184          ast_hangup(chan2m);
06185          return -1;
06186       }
06187    } else {
06188       if (chan1m)
06189          ast_hangup(chan1m);
06190       if (chan2m)
06191          ast_hangup(chan2m);
06192       return -1;
06193    }
06194    d = malloc(sizeof(struct iax_dual));
06195    if (d) {
06196       memset(d, 0, sizeof(*d));
06197       d->chan1 = chan1m;
06198       d->chan2 = chan2m;
06199       if (!ast_pthread_create(&th, NULL, iax_park_thread, d))
06200          return 0;
06201       free(d);
06202    }
06203    return -1;
06204 }

void* iax_park_thread void *  stuff  )  [static]
 

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

06134 {
06135    struct ast_channel *chan1, *chan2;
06136    struct iax_dual *d;
06137    struct ast_frame *f;
06138    int ext;
06139    int res;
06140    d = stuff;
06141    chan1 = d->chan1;
06142    chan2 = d->chan2;
06143    free(d);
06144    f = ast_read(chan1);
06145    if (f)
06146       ast_frfree(f);
06147    res = ast_park_call(chan1, chan2, 0, &ext);
06148    ast_hangup(chan2);
06149    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06150    return NULL;
06151 }

struct iax_frame* iaxfrdup2 struct iax_frame fr  )  [static]
 

Definition at line 925 of file chan_iax2.c.

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

Referenced by socket_read().

00926 {
00927    /* Malloc() a copy of a frame */
00928    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
00929    if (new) {
00930       memcpy(new, fr, sizeof(struct iax_frame));   
00931       iax_frame_wrap(new, &fr->af);
00932       new->data = NULL;
00933       new->datalen = 0;
00934       new->direction = DIRECTION_INGRESS;
00935       new->retrans = -1;
00936    }
00937    return new;
00938 }

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

Definition at line 694 of file chan_iax2.c.

References ast_verbose(), and fmt.

Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().

00695 {
00696    va_list args;
00697    char buf[1024];
00698 
00699    va_start(args, fmt);
00700    vsnprintf(buf, 1024, fmt, args);
00701    va_end(args);
00702 
00703    ast_verbose(buf);
00704 }

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

Definition at line 670 of file chan_iax2.c.

References ast_log(), fmt, and LOG_ERROR.

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

00671 {
00672    va_list args;
00673    char buf[1024];
00674 
00675    va_start(args, fmt);
00676    vsnprintf(buf, 1024, fmt, args);
00677    va_end(args);
00678 
00679    ast_log(LOG_ERROR, buf);
00680 }

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

Definition at line 682 of file chan_iax2.c.

References ast_log(), fmt, and LOG_WARNING.

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

00683 {
00684    va_list args;
00685    char buf[1024];
00686 
00687    va_start(args, fmt);
00688    vsnprintf(buf, 1024, fmt, args);
00689    va_end(args);
00690 
00691    ast_log(LOG_WARNING, buf);
00692 }

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

09657 {
09658    return ASTERISK_GPL_KEY;
09659 }

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 9535 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_bindaddr(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_register_application(), ast_register_switch(), ast_verbose(), channeltype, defaultsockfd, iax2_cli, iax2_do_register(), iax2_poke_peer(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), IAX_DEFAULT_PORTNO, iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, ast_peer_list::lock, ast_user_list::lock, ast_iax2_queue::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), netsock, iax2_peer::next, iax2_registry::next, option_verbose, papp, pdescrip, peerl, ast_peer_list::peers, psyn, reload_firmware(), sched, sched_context_create(), set_config(), socket_read(), iax2_peer::sockfd, start_network_thread(), timingfd, tos, userl, VERBOSE_PREFIX_2, and waresl.

09536 {
09537    char *config = "iax.conf";
09538    int res = 0;
09539    int x;
09540    struct iax2_registry *reg;
09541    struct iax2_peer *peer;
09542    
09543    struct ast_netsock *ns;
09544    struct sockaddr_in sin;
09545    
09546    ast_custom_function_register(&iaxpeer_function);
09547 
09548    iax_set_output(iax_debug_output);
09549    iax_set_error(iax_error_output);
09550 #ifdef NEWJB
09551    jb_setoutput(jb_error_output, jb_warning_output, NULL);
09552 #endif
09553    
09554    sin.sin_family = AF_INET;
09555    sin.sin_port = htons(IAX_DEFAULT_PORTNO);
09556    sin.sin_addr.s_addr = INADDR_ANY;
09557 
09558 #ifdef IAX_TRUNKING
09559 #ifdef ZT_TIMERACK
09560    timingfd = open("/dev/zap/timer", O_RDWR);
09561    if (timingfd < 0)
09562 #endif
09563       timingfd = open("/dev/zap/pseudo", O_RDWR);
09564    if (timingfd < 0) 
09565       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
09566 #endif      
09567 
09568    memset(iaxs, 0, sizeof(iaxs));
09569 
09570    for (x=0;x<IAX_MAX_CALLS;x++)
09571       ast_mutex_init(&iaxsl[x]);
09572    
09573    io = io_context_create();
09574    sched = sched_context_create();
09575    
09576    if (!io || !sched) {
09577       ast_log(LOG_ERROR, "Out of memory\n");
09578       return -1;
09579    }
09580 
09581    netsock = ast_netsock_list_alloc();
09582    if (!netsock) {
09583       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
09584       return -1;
09585    }
09586    ast_netsock_init(netsock);
09587 
09588    ast_mutex_init(&iaxq.lock);
09589    ast_mutex_init(&userl.lock);
09590    ast_mutex_init(&peerl.lock);
09591    ast_mutex_init(&waresl.lock);
09592    
09593    ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
09594 
09595    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
09596    
09597    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
09598    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
09599 
09600    set_config(config, 0);
09601 
09602    if (ast_channel_register(&iax2_tech)) {
09603       ast_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
09604       __unload_module();
09605       return -1;
09606    }
09607 
09608    if (ast_register_switch(&iax2_switch)) 
09609       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
09610    
09611    if (defaultsockfd < 0) {
09612       if (!(ns = ast_netsock_bindaddr(netsock, io, &sin, tos, socket_read, NULL))) {
09613          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09614          return -1;
09615       } else {
09616          if (option_verbose > 1)
09617             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", IAX_DEFAULT_PORTNO);
09618          defaultsockfd = ast_netsock_sockfd(ns);
09619          ast_netsock_unref(ns);
09620       }
09621    }
09622    
09623    res = start_network_thread();
09624    if (!res) {
09625       if (option_verbose > 1) 
09626          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
09627    } else {
09628       ast_log(LOG_ERROR, "Unable to start network thread\n");
09629       ast_netsock_release(netsock);
09630    }
09631 
09632    for (reg = registrations; reg; reg = reg->next)
09633       iax2_do_register(reg);
09634    ast_mutex_lock(&peerl.lock);
09635    for (peer = peerl.peers; peer; peer = peer->next) {
09636       if (peer->sockfd < 0)
09637          peer->sockfd = defaultsockfd;
09638       iax2_poke_peer(peer, 0);
09639    }
09640    ast_mutex_unlock(&peerl.lock);
09641    reload_firmware();
09642    iax_provision_reload();
09643    return res;
09644 }

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

Definition at line 3150 of file chan_iax2.c.

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

Referenced by iax2_bridge().

03151 {
03152    ast_mutex_lock(&iaxsl[callno0]);
03153    while (ast_mutex_trylock(&iaxsl[callno1])) {
03154       ast_mutex_unlock(&iaxsl[callno0]);
03155       usleep(10);
03156       ast_mutex_lock(&iaxsl[callno0]);
03157    }
03158 }

int make_trunk unsigned short  callno,
int  locked
[static]
 

Definition at line 992 of file chan_iax2.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_sched_del(), chan_iax2_pvt::callno, IAX_MAX_CALLS, iaxs, iaxsl, chan_iax2_pvt::lagid, lagrq_time, lastused, LOG_DEBUG, LOG_WARNING, chan_iax2_pvt::oseqno, ping_time, chan_iax2_pvt::pingid, sched, send_lagrq(), send_ping(), update_max_nontrunk(), and update_max_trunk().

Referenced by iax2_request(), and socket_read().

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

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

Definition at line 4289 of file chan_iax2.c.

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

Referenced by load_module().

04290 {
04291    ast_cli_netstats(s->fd, 0);
04292    ast_cli(s->fd, "\r\n");
04293    return RESULT_SUCCESS;
04294 }

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

Definition at line 4322 of file chan_iax2.c.

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

Referenced by load_module().

04323 {
04324    char *a[] = { "iax2", "show", "users" };
04325    int ret;
04326    char *id;
04327    id = astman_get_header(m,"ActionID");
04328    if (!ast_strlen_zero(id))
04329       ast_cli(s->fd, "ActionID: %s\r\n",id);
04330    ret = __iax2_show_peers(1, s->fd, 3, a );
04331    ast_cli(s->fd, "\r\n\r\n" );
04332    return ret;
04333 } /* /JDG */

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

Definition at line 944 of file chan_iax2.c.

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

Referenced by find_callno(), and schedule_delivery().

00945 {
00946    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
00947       (cur->addr.sin_port == sin->sin_port)) {
00948       /* This is the main host */
00949       if ((cur->peercallno == callno) ||
00950          ((dcallno == cur->callno) && !cur->peercallno)) {
00951          /* That's us.  Be sure we keep track of the peer call number */
00952          return 1;
00953       }
00954    }
00955    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
00956        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
00957       /* We're transferring */
00958       if (dcallno == cur->callno)
00959          return 1;
00960    }
00961    return 0;
00962 }

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

Definition at line 3786 of file chan_iax2.c.

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

Referenced by decode_frame().

03787 {
03788 #if 0
03789    /* Debug with "fake encryption" */
03790    int x;
03791    if (len % 16)
03792       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03793    for (x=0;x<len;x++)
03794       dst[x] = src[x] ^ 0xff;
03795 #else 
03796    unsigned char lastblock[16] = { 0 };
03797    int x;
03798    while(len > 0) {
03799       aes_decrypt(src, dst, dcx);
03800       for (x=0;x<16;x++)
03801          dst[x] ^= lastblock[x];
03802       memcpy(lastblock, src, sizeof(lastblock));
03803       dst += 16;
03804       src += 16;
03805       len -= 16;
03806    }
03807 #endif
03808 }

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

Definition at line 3810 of file chan_iax2.c.

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

Referenced by encrypt_frame().

03811 {
03812 #if 0
03813    /* Debug with "fake encryption" */
03814    int x;
03815    if (len % 16)
03816       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03817    for (x=0;x<len;x++)
03818       dst[x] = src[x] ^ 0xff;
03819 #else
03820    unsigned char curblock[16] = { 0 };
03821    int x;
03822    while(len > 0) {
03823       for (x=0;x<16;x++)
03824          curblock[x] ^= src[x];
03825       aes_encrypt(curblock, dst, ecx);
03826       memcpy(curblock, dst, sizeof(curblock)); 
03827       dst += 16;
03828       src += 16;
03829       len -= 16;
03830    }
03831 #endif
03832 }

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

Definition at line 4921 of file chan_iax2.c.

References chan_iax2_pvt::encmethods.

Referenced by authenticate_reply(), and socket_read().

04922 {
04923    /* Select exactly one common encryption if there are any */
04924    p->encmethods &= enc;
04925    if (p->encmethods) {
04926       if (p->encmethods & IAX_ENCRYPT_AES128)
04927          p->encmethods = IAX_ENCRYPT_AES128;
04928       else
04929          p->encmethods = 0;
04930    }
04931 }

void* network_thread void *  ignore  )  [static]
 

Definition at line 7927 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, iaxs, io, ast_iax2_queue::lock, LOG_DEBUG, iax_frame::next, iax_frame::prev, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_packet(), iax_frame::sentyet, ast_iax2_queue::tail, timing_read(), and timingfd.

Referenced by start_network_thread().

07928 {
07929    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
07930       from the network, and queue them for delivery to the channels */
07931    int res, count;
07932    struct iax_frame *f, *freeme;
07933    if (timingfd > -1)
07934       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
07935    for(;;) {
07936       /* Go through the queue, sending messages which have not yet been
07937          sent, and scheduling retransmissions if appropriate */
07938       ast_mutex_lock(&iaxq.lock);
07939       f = iaxq.head;
07940       count = 0;
07941       while(f) {
07942          freeme = NULL;
07943          if (!f->sentyet) {
07944             f->sentyet++;
07945             /* Send a copy immediately -- errors here are ok, so don't bother locking */
07946             if (iaxs[f->callno]) {
07947                send_packet(f);
07948                count++;
07949             } 
07950             if (f->retries < 0) {
07951                /* This is not supposed to be retransmitted */
07952                if (f->prev) 
07953                   f->prev->next = f->next;
07954                else
07955                   iaxq.head = f->next;
07956                if (f->next)
07957                   f->next->prev = f->prev;
07958                else
07959                   iaxq.tail = f->prev;
07960                iaxq.count--;
07961                /* Free the iax frame */
07962                freeme = f;
07963             } else {
07964                /* We need reliable delivery.  Schedule a retransmission */
07965                f->retries++;
07966                f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
07967             }
07968          }
07969          f = f->next;
07970          if (freeme)
07971             iax_frame_free(freeme);
07972       }
07973       ast_mutex_unlock(&iaxq.lock);
07974       if (count >= 20)
07975          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
07976 
07977       /* Now do the IO, and run scheduled tasks */
07978       res = ast_sched_wait(sched);
07979       if ((res > 1000) || (res < 0))
07980          res = 1000;
07981       res = ast_io_wait(io, res);
07982       if (res >= 0) {
07983          if (res >= 20)
07984             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
07985          count = ast_sched_runq(sched);
07986          if (count >= 20)
07987             ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
07988       }
07989    }
07990    return NULL;
07991 }

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

Definition at line 890 of file chan_iax2.c.

References chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::bridgecallno, chan_iax2_pvt::callno, chan_iax2_pvt::exten, chan_iax2_pvt::host, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, malloc, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingid, chan_iax2_pvt::prefs, jb_conf::resync_threshold, and chan_iax2_pvt::transfercallno.

Referenced by find_callno().

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

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 2888 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(), and iax2_request().

02889 {
02890    if (ast_strlen_zero(data))
02891       return;
02892 
02893    pds->peer = strsep(&data, "/");
02894    pds->exten = strsep(&data, "/");
02895    pds->options = data;
02896 
02897    if (pds->exten) {
02898       data = pds->exten;
02899       pds->exten = strsep(&data, "@");
02900       pds->context = data;
02901    }
02902 
02903    if (strchr(pds->peer, '@')) {
02904       data = pds->peer;
02905       pds->username = strsep(&data, "@");
02906       pds->peer = data;
02907    }
02908 
02909    if (pds->username) {
02910       data = pds->username;
02911       pds->username = strsep(&data, ":");
02912       pds->password = data;
02913    }
02914 
02915    data = pds->peer;
02916    pds->peer = strsep(&data, ":");
02917    pds->port = data;
02918 
02919    /* check for a key name wrapped in [] in the secret position, if found,
02920       move it to the key field instead
02921    */
02922    if (pds->password && (pds->password[0] == '[')) {
02923       pds->key = ast_strip_quoted(pds->password, "[", "]");
02924       pds->password = NULL;
02925    }
02926 }

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

Definition at line 8052 of file chan_iax2.c.

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

Referenced by build_peer().

08053 {
08054    struct sockaddr_in sin;
08055    int nonlocal = 1;
08056    int port = IAX_DEFAULT_PORTNO;
08057    int sockfd = defaultsockfd;
08058    char *tmp;
08059    char *addr;
08060    char *portstr;
08061 
08062    tmp = ast_strdupa(srcaddr);
08063    if (!tmp) {
08064       ast_log(LOG_WARNING, "Out of memory!\n");
08065       return -1;
08066    }
08067 
08068    addr = strsep(&tmp, ":");
08069    portstr = tmp;
08070 
08071    if (portstr) {
08072       port = atoi(portstr);
08073       if (port < 1)
08074          port = IAX_DEFAULT_PORTNO;
08075    }
08076    
08077    if (!ast_get_ip(&sin, addr)) {
08078       struct ast_netsock *sock;
08079       int res;
08080 
08081       sin.sin_port = 0;
08082       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08083       if (res == 0) {
08084          /* ip address valid. */
08085          sin.sin_port = htons(port);
08086          sock = ast_netsock_find(netsock, &sin);
08087          if (sock) {
08088             sockfd = ast_netsock_sockfd(sock);
08089             nonlocal = 0;
08090          }
08091       }
08092    }
08093       
08094    peer->sockfd = sockfd;
08095 
08096    if (nonlocal) {
08097       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08098          srcaddr, peer->name);
08099       return -1;
08100    } else {
08101       ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08102       return 0;
08103    }
08104 }

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

peer_status: Report Peer status in character string

Definition at line 1889 of file chan_iax2.c.

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

01890 {
01891    int res = 0;
01892    if (peer->maxms) {
01893       if (peer->lastms < 0) {
01894          ast_copy_string(status, "UNREACHABLE", statuslen);
01895       } else if (peer->lastms > peer->maxms) {
01896          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
01897          res = 1;
01898       } else if (peer->lastms) {
01899          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
01900          res = 1;
01901       } else {
01902          ast_copy_string(status, "UNKNOWN", statuslen);
01903       }
01904    } else { 
01905       ast_copy_string(status, "Unmonitored", statuslen);
01906       res = -1;
01907    }
01908    return res;
01909 }

void prune_peers void   )  [static]
 

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

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

void prune_users void   )  [static]
 

Definition at line 8503 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, userl, and ast_user_list::users.

08504 {
08505    struct iax2_user *user, *usernext, *userlast = NULL;
08506    ast_mutex_lock(&userl.lock);
08507    for (user=userl.users;user;) {
08508       usernext = user->next;
08509       if (ast_test_flag(user, IAX_DELME)) {
08510          destroy_user(user);
08511          if (userlast)
08512             userlast->next = usernext;
08513          else
08514             userl.users = usernext;
08515       } else
08516          userlast = user;
08517       user = usernext;
08518    }
08519    ast_mutex_unlock(&userl.lock);
08520 }

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

Definition at line 4900 of file chan_iax2.c.

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

Referenced by socket_read().

04901 {
04902    struct ast_iax2_full_hdr fh;
04903    char iabuf[INET_ADDRSTRLEN];
04904    fh.scallno = htons(src | IAX_FLAG_FULL);
04905    fh.dcallno = htons(dst);
04906    fh.ts = 0;
04907    fh.oseqno = 0;
04908    fh.iseqno = 0;
04909    fh.type = AST_FRAME_IAX;
04910    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04911    if (iaxdebug)
04912        iax_showframe(NULL, &fh, 0, sin, 0);
04913 #if 0
04914    if (option_debug)
04915 #endif   
04916       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04917          ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), src, dst);
04918    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04919 }

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

Definition at line 2570 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(), iax2_peer::expire, expire_registry(), global_rtautoclear, globalflags, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, ast_peer_list::lock, LOG_DEBUG, ast_variable::name, iax2_peer::next, ast_variable::next, peerl, ast_peer_list::peers, reg_source_db(), sched, ast_variable::value, and var.

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

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

Definition at line 2709 of file chan_iax2.c.

References ast_inet_ntoa(), and ast_update_realtime().

02710 {
02711    char port[10];
02712    char ipaddr[20];
02713    char regseconds[20];
02714    time_t nowtime;
02715    
02716    time(&nowtime);
02717    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);
02718    ast_inet_ntoa(ipaddr, sizeof(ipaddr), sin->sin_addr);
02719    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02720    ast_update_realtime("iaxpeers", "name", peername, "ipaddr", ipaddr, "port", port, "regseconds", regseconds, NULL);
02721 }

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

Definition at line 2668 of file chan_iax2.c.

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

02669 {
02670    struct ast_variable *var;
02671    struct ast_variable *tmp;
02672    struct iax2_user *user=NULL;
02673 
02674    var = ast_load_realtime("iaxusers", "name", username, NULL);
02675    if (!var)
02676       return NULL;
02677 
02678    tmp = var;
02679    while(tmp) {
02680       /* Make sure it's not a peer only... */
02681       if (!strcasecmp(tmp->name, "type")) {
02682          if (strcasecmp(tmp->value, "friend") &&
02683              strcasecmp(tmp->value, "user")) {
02684             return NULL;
02685          } 
02686       }
02687       tmp = tmp->next;
02688    }
02689 
02690    user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02691    if (!user)
02692       return NULL;
02693 
02694    ast_variables_destroy(var);
02695 
02696    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02697       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02698       ast_mutex_lock(&userl.lock);
02699       user->next = userl.users;
02700       userl.users = user;
02701       ast_mutex_unlock(&userl.lock);
02702    } else {
02703       ast_set_flag(user, IAX_TEMPONLY);   
02704    }
02705 
02706    return user;
02707 }

void reg_source_db struct iax2_peer p  )  [static]
 

Definition at line 5595 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(), sched, and VERBOSE_PREFIX_3.

05596 {
05597    char data[80];
05598    struct in_addr in;
05599    char iabuf[INET_ADDRSTRLEN];
05600    char *c, *d;
05601    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05602       c = strchr(data, ':');
05603       if (c) {
05604          *c = '\0';
05605          c++;
05606          if (inet_aton(data, &in)) {
05607             d = strchr(c, ':');
05608             if (d) {
05609                *d = '\0';
05610                d++;
05611                if (option_verbose > 2)
05612                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05613                   ast_inet_ntoa(iabuf, sizeof(iabuf), in), atoi(c), atoi(d));
05614                iax2_poke_peer(p, 0);
05615                p->expiry = atoi(d);
05616                memset(&p->addr, 0, sizeof(p->addr));
05617                p->addr.sin_family = AF_INET;
05618                p->addr.sin_addr = in;
05619                p->addr.sin_port = htons(atoi(c));
05620                if (p->expire > -1)
05621                   ast_sched_del(sched, p->expire);
05622                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05623                p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05624                if (iax2_regfunk)
05625                   iax2_regfunk(p->name, 1);
05626                register_peer_exten(p, 1);
05627             }              
05628                
05629          }
05630       }
05631    }
05632 }

void register_peer_exten struct iax2_peer peer,
int  onoff
[static]
 

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

05549 {
05550    char multi[256];
05551    char *stringp, *ext;
05552    if (!ast_strlen_zero(regcontext)) {
05553       ast_copy_string(multi, ast_strlen_zero(peer->regexten) ? peer->name : peer->regexten, sizeof(multi));
05554       stringp = multi;
05555       while((ext = strsep(&stringp, "&"))) {
05556          if (onoff) {
05557             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05558                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, "Noop", strdup(peer->name), free, channeltype);
05559          } else
05560             ast_context_remove_extension(regcontext, ext, 1, NULL);
05561       }
05562    }
05563 }

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

Verify inbound registration.

Definition at line 5014 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, iax2_peer::authmethods, destroy_peer(), chan_iax2_pvt::expiry, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, 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, strsep(), and iax_ies::username.

05015 {
05016    char requeststr[256] = "";
05017    char peer[256] = "";
05018    char md5secret[256] = "";
05019    char rsasecret[256] = "";
05020    char secret[256] = "";
05021    char iabuf[INET_ADDRSTRLEN];
05022    struct iax2_peer *p;
05023    struct ast_key *key;
05024    char *keyn;
05025    int x;
05026    int expire = 0;
05027 
05028    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05029    iaxs[callno]->peer[0] = '\0';
05030    if (ies->username)
05031       ast_copy_string(peer, ies->username, sizeof(peer));
05032    if (ies->password)
05033       ast_copy_string(secret, ies->password, sizeof(secret));
05034    if (ies->md5_result)
05035       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05036    if (ies->rsa_result)
05037       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05038    if (ies->refresh)
05039       expire = ies->refresh;
05040 
05041    if (ast_strlen_zero(peer)) {
05042       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05043       return -1;
05044    }
05045    /* We release the lock for the call to prevent a deadlock, but it's okay because
05046       only the current thread could possibly make it go away or make changes */
05047    ast_mutex_unlock(&iaxsl[callno]);
05048    /* SLD: first call to lookup peer during registration */
05049    p = find_peer(peer, 1);
05050    ast_mutex_lock(&iaxsl[callno]);
05051 
05052    if (!p) {
05053       if (authdebug)
05054          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05055       return -1;
05056    }
05057 
05058    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05059       if (authdebug)
05060          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05061       if (ast_test_flag(p, IAX_TEMPONLY))
05062          destroy_peer(p);
05063       return -1;
05064    }
05065 
05066    if (!ast_apply_ha(p->ha, sin)) {
05067       if (authdebug)
05068          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), p->name);
05069       if (ast_test_flag(p, IAX_TEMPONLY))
05070          destroy_peer(p);
05071       return -1;
05072    }
05073    ast_copy_string(iaxs[callno]->secret, p->secret, sizeof(iaxs[callno]->secret));
05074    ast_copy_string(iaxs[callno]->inkeys, p->inkeys, sizeof(iaxs[callno]->inkeys));
05075    /* Check secret against what we have on file */
05076    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05077       if (!ast_strlen_zero(p->inkeys)) {
05078          char tmpkeys[256];
05079          char *stringp=NULL;
05080          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05081          stringp=tmpkeys;
05082          keyn = strsep(&stringp, ":");
05083          while(keyn) {
05084             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05085             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05086                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05087                break;
05088             } else if (!key) 
05089                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05090             keyn = strsep(&stringp, ":");
05091          }
05092          if (!keyn) {
05093             if (authdebug)
05094                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05095             if (ast_test_flag(p, IAX_TEMPONLY))
05096                destroy_peer(p);
05097             return -1;
05098          }
05099       } else {
05100          if (authdebug)
05101             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05102          if (ast_test_flag(p, IAX_TEMPONLY))
05103             destroy_peer(p);
05104          return -1;
05105       }
05106    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05107       /* They've provided a plain text password and we support that */
05108       if (strcmp(secret, p->secret)) {
05109          if (authdebug)
05110             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);
05111          if (ast_test_flag(p, IAX_TEMPONLY))
05112             destroy_peer(p);
05113          return -1;
05114       } else
05115          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05116    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05117       struct MD5Context md5;
05118       unsigned char digest[16];
05119       char *tmppw, *stringp;
05120       
05121       tmppw = ast_strdupa(p->secret);
05122       stringp = tmppw;
05123       while((tmppw = strsep(&stringp, ";"))) {
05124          MD5Init(&md5);
05125          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05126          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05127          MD5Final(digest, &md5);
05128          for (x=0;x<16;x++)
05129             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05130          if (!strcasecmp(requeststr, md5secret)) 
05131             break;
05132       }
05133       if (tmppw) {
05134          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05135       } else {
05136          if (authdebug)
05137             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);
05138          if (ast_test_flag(p, IAX_TEMPONLY))
05139             destroy_peer(p);
05140          return -1;
05141       }
05142    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05143       if (authdebug)
05144          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05145       if (ast_test_flag(p, IAX_TEMPONLY))
05146          destroy_peer(p);
05147       return -1;
05148    }
05149    ast_copy_string(iaxs[callno]->peer, peer, sizeof(iaxs[callno]->peer));
05150    /* Choose lowest expiry number */
05151    if (expire && (expire < iaxs[callno]->expiry)) 
05152       iaxs[callno]->expiry = expire;
05153 
05154    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05155 
05156    if (ast_test_flag(p, IAX_TEMPONLY))
05157       destroy_peer(p);
05158    return 0;
05159    
05160 }

int registry_authrequest char *  name,
int  callno
[static]
 

Definition at line 5736 of file chan_iax2.c.

References AST_FRAME_IAX, ast_log(), ast_test_flag, iax2_peer::authmethods, destroy_peer(), find_peer(), 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, iaxs, LOG_WARNING, name, and send_command().

Referenced by socket_read().

05737 {
05738    struct iax_ie_data ied;
05739    struct iax2_peer *p;
05740    /* SLD: third call to find_peer in registration */
05741    p = find_peer(name, 1);
05742    if (p) {
05743       memset(&ied, 0, sizeof(ied));
05744       iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05745       if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05746          /* Build the challenge */
05747          snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", rand());
05748          iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05749       }
05750       iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05751       if (ast_test_flag(p, IAX_TEMPONLY))
05752          destroy_peer(p);
05753       return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05754    } 
05755    ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05756    return 0;
05757 }

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

Definition at line 5759 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, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.

Referenced by socket_read().

05760 {
05761    struct iax2_registry *reg;
05762    /* Start pessimistic */
05763    struct iax_ie_data ied;
05764    char peer[256] = "";
05765    char iabuf[INET_ADDRSTRLEN];
05766    char challenge[256] = "";
05767    int res;
05768    int authmethods = 0;
05769    if (ies->authmethods)
05770       authmethods = ies->authmethods;
05771    if (ies->username)
05772       ast_copy_string(peer, ies->username, sizeof(peer));
05773    if (ies->challenge)
05774       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05775    memset(&ied, 0, sizeof(ied));
05776    reg = iaxs[callno]->reg;
05777    if (reg) {
05778          if (inaddrcmp(&reg->addr, sin)) {
05779             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr));
05780             return -1;
05781          }
05782          if (ast_strlen_zero(reg->secret)) {
05783             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05784             reg->regstate = REG_STATE_NOAUTH;
05785             return -1;
05786          }
05787          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05788          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05789          if (reg->secret[0] == '[') {
05790             char tmpkey[256];
05791             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05792             tmpkey[strlen(tmpkey) - 1] = '\0';
05793             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05794          } else
05795             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05796          if (!res) {
05797             reg->regstate = REG_STATE_AUTHSENT;
05798             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05799          } else
05800             return -1;
05801          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05802    } else   
05803       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05804    return -1;
05805 }

char* regstate2str int  regstate  )  [static]
 

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

04336 {
04337    switch(regstate) {
04338    case REG_STATE_UNREGISTERED:
04339       return "Unregistered";
04340    case REG_STATE_REGSENT:
04341       return "Request Sent";
04342    case REG_STATE_AUTHSENT:
04343       return "Auth. Sent";
04344    case REG_STATE_REGISTERED:
04345       return "Registered";
04346    case REG_STATE_REJECTED:
04347       return "Rejected";
04348    case REG_STATE_TIMEOUT:
04349       return "Timeout";
04350    case REG_STATE_NOAUTH:
04351       return "No Authentication";
04352    default:
04353       return "Unknown";
04354    }
04355 }

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

References reload_config().

08859 {
08860    return reload_config();
08861 }

int reload_config void   )  [static]
 

Definition at line 1999 of file chan_h323.c.

References ahp, ast_alias_list::aliases, aliasl, ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_gethostbyname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), bindaddr, build_alias(), build_peer(), build_user(), cfg, config, default_context, gatekeeper, gatekeeper_disable, gatekeeper_discover, gkroute, global_options, h323_signalling_port, h323debug, hp, 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(), 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().

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

void reload_firmware void   )  [static]
 

Definition at line 1354 of file chan_iax2.c.

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

Referenced by load_module().

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

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

Definition at line 6252 of file chan_iax2.c.

References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, 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().

06253 {
06254    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06255    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06256    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06257    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06258    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06259    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06260    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06261 }

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

Definition at line 2243 of file chan_iax2.c.

References __do_deliver(), iax_frame::af, ast_bridged_channel(), ast_codec_get_samples(), 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, chan_iax2_pvt::frames_dropped, ast_frame::frametype, GAMMA, iax2_dropcount, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, jb_getall(), jb_put(), jb_reset(), chan_iax2_pvt::jbid, chan_iax2_pvt::last, LOG_DEBUG, match(), MEMORY_SIZE, chan_iax2_pvt::min, option_debug, chan_iax2_pvt::owner, ast_channel_tech::properties, iax_frame::retrans, chan_iax2_pvt::rxcore, sched, ast_channel::tech, iax_frame::ts, TS_GAP_FOR_JB_RESYNC, type, unwrap_timestamp(), and update_jbsched().

Referenced by socket_read().

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

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

Definition at line 4660 of file chan_iax2.c.

References __send_command(), and type.

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

04661 {
04662    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04663 }

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

Definition at line 4681 of file chan_iax2.c.

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

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

04682 {
04683    /* It is assumed that the callno has already been locked */
04684    iax2_predestroy_nolock(i->callno);
04685    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04686 }

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

Definition at line 4688 of file chan_iax2.c.

References __send_command(), and type.

Referenced by iax2_vnak(), and socket_read().

04689 {
04690    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04691 }

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

Definition at line 4665 of file chan_iax2.c.

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

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

04666 {
04667    int res;
04668    ast_mutex_lock(&iaxsl[callno]);
04669    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04670    ast_mutex_unlock(&iaxsl[callno]);
04671    return res;
04672 }

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

Definition at line 4693 of file chan_iax2.c.

References __send_command(), and type.

Referenced by socket_read(), and try_transfer().

04694 {
04695    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04696 }

int send_lagrq void *  data  )  [static]
 

Definition at line 795 of file chan_iax2.c.

References AST_FRAME_IAX, chan_iax2_pvt::bridgecallno, IAX_COMMAND_LAGRQ, iaxs, and send_command().

Referenced by find_callno(), and make_trunk().

00796 {
00797    int callno = (long)data;
00798    /* Ping only if it's real not if it's bridged */
00799    if (iaxs[callno]) {
00800 #ifdef BRIDGE_OPTIMIZATION
00801       if (!iaxs[callno]->bridgecallno)
00802 #endif      
00803          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
00804       return 1;
00805    } else
00806       return 0;
00807 }

int send_packet struct iax_frame f  )  [static]
 

Definition at line 1483 of file chan_iax2.c.

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

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

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

int send_ping void *  data  )  [static]
 

Definition at line 769 of file chan_iax2.c.

References AST_FRAME_IAX, chan_iax2_pvt::bridgecallno, IAX_COMMAND_PING, iaxs, and send_command().

Referenced by find_callno(), and make_trunk().

00770 {
00771    int callno = (long)data;
00772    /* Ping only if it's real, not if it's bridged */
00773    if (iaxs[callno]) {
00774 #ifdef BRIDGE_OPTIMIZATION
00775       if (!iaxs[callno]->bridgecallno)
00776 #endif
00777          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00778       return 1;
00779    } else
00780       return 0;
00781 }

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

Definition at line 5931 of file chan_iax2.c.

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

Referenced by timing_read().

05932 {
05933    int res = 0;
05934    struct iax_frame *fr;
05935    struct ast_iax2_meta_hdr *meta;
05936    struct ast_iax2_meta_trunk_hdr *mth;
05937    int calls = 0;
05938    
05939    /* Point to frame */
05940    fr = (struct iax_frame *)tpeer->trunkdata;
05941    /* Point to meta data */
05942    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
05943    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
05944    if (tpeer->trunkdatalen) {
05945       /* We're actually sending a frame, so fill the meta trunk header and meta header */
05946       meta->zeros = 0;
05947       meta->metacmd = IAX_META_TRUNK;
05948       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
05949          meta->cmddata = IAX_META_TRUNK_MINI;
05950       else
05951          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
05952       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
05953       /* And the rest of the ast_iax2 header */
05954       fr->direction = DIRECTION_OUTGRESS;
05955       fr->retrans = -1;
05956       fr->transfer = 0;
05957       /* Any appropriate call will do */
05958       fr->data = fr->afdata;
05959       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
05960       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
05961       calls = tpeer->calls;
05962 #if 0
05963       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));
05964 #endif      
05965       /* Reset transmit trunk side data */
05966       tpeer->trunkdatalen = 0;
05967       tpeer->calls = 0;
05968    }
05969    if (res < 0)
05970       return res;
05971    return calls;
05972 }

int set_config char *  config_file,
int  reload
[static]
 

Definition at line 8583 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(), cfg, channeltype, defaultsockfd, delayreject, get_encrypt_methods(), global_rtautoclear, globalflags, iax2_capability, iax2_dropcount, iax2_encryption, iax2_register(), IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_MESSAGEDETAIL, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxcompat, io, jittershrinkrate, lagrq_time, language, ast_variable::lineno, ast_peer_list::lock, ast_user_list::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, max_jitter_buffer, max_reg_expire, maxjitterbuffer, maxjitterinterps, min_jitter_buffer, min_reg_expire, ast_variable::name, netsock, iax2_peer::next, iax2_user::next, ast_variable::next, option_verbose, peerl, ast_peer_list::peers, ping_time, prefs, reg_source_db(), regcontext, resyncthreshold, set_timing(), socket_read(), tos, trunkfreq, userl, ast_user_list::users, ast_variable::value, and VERBOSE_PREFIX_2.

08584 {
08585    struct ast_config *cfg;
08586    int capability=iax2_capability;
08587    struct ast_variable *v;
08588    char *cat;
08589    char *utype;
08590    char *tosval;
08591    int format;
08592    int portno = IAX_DEFAULT_PORTNO;
08593    int  x;
08594    struct iax2_user *user;
08595    struct iax2_peer *peer;
08596    struct ast_netsock *ns;
08597 #if 0
08598    static unsigned short int last_port=0;
08599 #endif
08600 
08601    cfg = ast_config_load(config_file);
08602    
08603    if (!cfg) {
08604       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
08605       return -1;
08606    }
08607 
08608    /* Reset global codec prefs */   
08609    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
08610    
08611    /* Reset Global Flags */
08612    memset(&globalflags, 0, sizeof(globalflags));
08613    ast_set_flag(&globalflags, IAX_RTUPDATE);
08614 
08615 #ifdef SO_NO_CHECK
08616    nochecksums = 0;
08617 #endif
08618 
08619    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08620    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08621 
08622    v = ast_variable_browse(cfg, "general");
08623 
08624    /* Seed initial tos value */
08625    tosval = ast_variable_retrieve(cfg, "general", "tos");
08626    if (tosval) {
08627       if (ast_str2tos(tosval, &tos))
08628          ast_log(LOG_WARNING, "Invalid tos value, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n");
08629    }
08630    while(v) {
08631       if (!strcasecmp(v->name, "bindport")){ 
08632          if (reload)
08633             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
08634          else
08635             portno = atoi(v->value);
08636       } else if (!strcasecmp(v->name, "pingtime")) 
08637          ping_time = atoi(v->value);
08638       else if (!strcasecmp(v->name, "nochecksums")) {
08639 #ifdef SO_NO_CHECK
08640          if (ast_true(v->value))
08641             nochecksums = 1;
08642          else
08643             nochecksums = 0;
08644 #else
08645          if (ast_true(v->value))
08646             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
08647 #endif
08648       }
08649       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
08650          maxjitterbuffer = atoi(v->value);
08651 #ifdef NEWJB
08652       else if (!strcasecmp(v->name, "resyncthreshold")) 
08653          resyncthreshold = atoi(v->value);
08654       else if (!strcasecmp(v->name, "maxjitterinterps")) 
08655          maxjitterinterps = atoi(v->value);
08656 #endif
08657       else if (!strcasecmp(v->name, "jittershrinkrate")) 
08658          jittershrinkrate = atoi(v->value);
08659       else if (!strcasecmp(v->name, "maxexcessbuffer")) 
08660          max_jitter_buffer = atoi(v->value);
08661       else if (!strcasecmp(v->name, "minexcessbuffer")) 
08662          min_jitter_buffer = atoi(v->value);
08663       else if (!strcasecmp(v->name, "lagrqtime")) 
08664          lagrq_time = atoi(v->value);
08665       else if (!strcasecmp(v->name, "dropcount")) 
08666          iax2_dropcount = atoi(v->value);
08667       else if (!strcasecmp(v->name, "maxregexpire")) 
08668          max_reg_expire = atoi(v->value);
08669       else if (!strcasecmp(v->name, "minregexpire")) 
08670          min_reg_expire = atoi(v->value);
08671       else if (!strcasecmp(v->name, "bindaddr")) {
08672          if (reload) {
08673             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
08674          } else {
08675             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
08676                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
08677             } else {
08678                if (option_verbose > 1) {
08679                   if (strchr(v->value, ':'))
08680                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
08681                   else
08682                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
08683                }
08684                if (defaultsockfd < 0) 
08685                   defaultsockfd = ast_netsock_sockfd(ns);
08686                ast_netsock_unref(ns);
08687             }
08688          }
08689       } else if (!strcasecmp(v->name, "authdebug"))
08690          authdebug = ast_true(v->value);
08691       else if (!strcasecmp(v->name, "encryption"))
08692          iax2_encryption = get_encrypt_methods(v->value);
08693       else if (!strcasecmp(v->name, "notransfer"))
08694          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
08695       else if (!strcasecmp(v->name, "codecpriority")) {
08696          if(!strcasecmp(v->value, "caller"))
08697             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
08698          else if(!strcasecmp(v->value, "disabled"))
08699             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08700          else if(!strcasecmp(v->value, "reqonly")) {
08701             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
08702             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
08703          }
08704       } else if (!strcasecmp(v->name, "jitterbuffer"))
08705          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
08706       else if (!strcasecmp(v->name, "forcejitterbuffer"))
08707          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
08708       else if (!strcasecmp(v->name, "delayreject"))
08709          delayreject = ast_true(v->value);
08710       else if (!strcasecmp(v->name, "mailboxdetail"))
08711          ast_set2_flag((&globalflags), ast_true(v->value), IAX_MESSAGEDETAIL);   
08712       else if (!strcasecmp(v->name, "rtcachefriends"))
08713          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
08714       else if (!strcasecmp(v->name, "rtignoreregexpire"))
08715          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
08716       else if (!strcasecmp(v->name, "rtupdate"))
08717          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
08718       else if (!strcasecmp(v->name, "trunktimestamps"))
08719          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
08720       else if (!strcasecmp(v->name, "rtautoclear")) {
08721          int i = atoi(v->value);
08722          if(i > 0)
08723             global_rtautoclear = i;
08724          else
08725             i = 0;
08726          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
08727       } else if (!strcasecmp(v->name, "trunkfreq")) {
08728          trunkfreq = atoi(v->value);
08729          if (trunkfreq < 10)
08730             trunkfreq = 10;
08731       } else if (!strcasecmp(v->name, "autokill")) {
08732          if (sscanf(v->value, "%d", &x) == 1) {
08733             if (x >= 0)
08734                autokill = x;
08735             else
08736                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
08737          } else if (ast_true(v->value)) {
08738             autokill = DEFAULT_MAXMS;
08739          } else {
08740             autokill = 0;
08741          }
08742       } else if (!strcasecmp(v->name, "bandwidth")) {
08743          if (!strcasecmp(v->value, "low")) {
08744             capability = IAX_CAPABILITY_LOWBANDWIDTH;
08745          } else if (!strcasecmp(v->value, "medium")) {
08746             capability = IAX_CAPABILITY_MEDBANDWIDTH;
08747          } else if (!strcasecmp(v->value, "high")) {
08748             capability = IAX_CAPABILITY_FULLBANDWIDTH;
08749          } else
08750             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
08751       } else if (!strcasecmp(v->name, "allow")) {
08752          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
08753       } else if (!strcasecmp(v->name, "disallow")) {
08754          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
08755       } else if (!strcasecmp(v->name, "register")) {
08756          iax2_register(v->value, v->lineno);
08757       } else if (!strcasecmp(v->name, "iaxcompat")) {
08758          iaxcompat = ast_true(v->value);
08759       } else if (!strcasecmp(v->name, "regcontext")) {
08760          ast_copy_string(regcontext, v->value, sizeof(regcontext));
08761          /* Create context if it doesn't exist already */
08762          if (!ast_context_find(regcontext))
08763             ast_context_create(NULL, regcontext, channeltype);
08764       } else if (!strcasecmp(v->name, "tos")) {
08765          if (ast_str2tos(v->value, &tos))
08766             ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
08767       } else if (!strcasecmp(v->name, "accountcode")) {
08768          ast_copy_string(accountcode, v->value, sizeof(accountcode));
08769       } else if (!strcasecmp(v->name, "amaflags")) {
08770          format = ast_cdr_amaflags2int(v->value);
08771          if (format < 0) {
08772             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08773          } else {
08774             amaflags = format;
08775          }
08776       } else if (!strcasecmp(v->name, "language")) {
08777                         ast_copy_string(language, v->value, sizeof(language));
08778       } /*else if (strcasecmp(v->name,"type")) */
08779       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
08780       v = v->next;
08781    }
08782    if (min_reg_expire > max_reg_expire) {
08783       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
08784          min_reg_expire, max_reg_expire, max_reg_expire);
08785       min_reg_expire = max_reg_expire;
08786    }
08787    iax2_capability = capability;
08788    cat = ast_category_browse(cfg, NULL);
08789    while(cat) {
08790       if (strcasecmp(cat, "general")) {
08791          utype = ast_variable_retrieve(cfg, cat, "type");
08792          if (utype) {
08793             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
08794                user = build_user(cat, ast_variable_browse(cfg, cat), 0);
08795                if (user) {
08796                   ast_mutex_lock(&userl.lock);
08797                   user->next = userl.users;
08798                   userl.users = user;
08799                   ast_mutex_unlock(&userl.lock);
08800                }
08801             }
08802             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
08803                peer = build_peer(cat, ast_variable_browse(cfg, cat), 0);
08804                if (peer) {
08805                   ast_mutex_lock(&peerl.lock);
08806                   peer->next = peerl.peers;
08807                   peerl.peers = peer;
08808                   ast_mutex_unlock(&peerl.lock);
08809                   if (ast_test_flag(peer, IAX_DYNAMIC))
08810                      reg_source_db(peer);
08811                }
08812             } else if (strcasecmp(utype, "user")) {
08813                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
08814             }
08815          } else
08816             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
08817       }
08818       cat = ast_category_browse(cfg, cat);
08819    }
08820    ast_config_destroy(cfg);
08821    set_timing();
08822    return capability;
08823 }

void set_timing void   )  [static]
 

Definition at line 8566 of file chan_iax2.c.

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

Referenced by set_config().

08567 {
08568 #ifdef IAX_TRUNKING
08569    int bs = trunkfreq * 8;
08570    if (timingfd > -1) {
08571       if (
08572 #ifdef ZT_TIMERACK
08573          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08574 #endif         
08575          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08576          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08577    }
08578 #endif
08579 }

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

Definition at line 6263 of file chan_iax2.c.

References iax_frame::af, chan_iax2_pvt::aseqno, 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_string(), AST_CONTROL_PROGRESS, ast_device_state_changed(), ast_exists_extension(), ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_add(), ast_sched_del(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strlen_zero(), ast_test_flag, ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, chan_iax2_pvt::bridgecallno, iax_ie_data::buf, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, iax_frame::callno, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, check_access(), check_provisioning(), ast_iax2_meta_hdr::cmddata, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), ast_iax2_full_hdr::csub, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, ast_iax2_full_hdr::dcallno, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::dpentries, chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, iax_frame::final, find_callno(), find_tpeer(), fix_peerts(), iax2_dpcache::flags, iax_ies::format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_error(), ast_channel::hangupcause, 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_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_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, iaxdebug, iaxfrdup2(), iaxq, iaxs, iaxsl, inaddrcmp(), chan_iax2_pvt::initid, chan_iax2_pvt::iseqno, ast_iax2_full_hdr::iseqno, iax_frame::iseqno, chan_iax2_pvt::lag, 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_DEBUG, 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, ast_channel::name, ast_channel::nativeformats, NEW_PREVENT, iax_frame::next, ast_frame::offset, option_debug, option_verbose, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, iax2_dpcache::peer, chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, raw_hangup(), ast_channel::readformat, iax_ies::refresh, chan_iax2_pvt::reg, register_verify(), registry_authrequest(), registry_rerequest(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, ast_frame::samples, save_rr(), sched, 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, iax_frame::transfer, iax2_trunk_peer::trunkact, try_transfer(), ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, ast_channel::writeformat, ast_iax2_meta_hdr::zeros, and ast_iax2_video_hdr::zeros.

Referenced by load_module(), and set_config().

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

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

Definition at line 6109 of file chan_iax2.c.

References ast_log(), ast_pthread_create, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, context, dpreq_data::context, dp_lookup_thread(), LOG_WARNING, malloc, and strdup.

Referenced by socket_read().

06110 {
06111    pthread_t newthread;
06112    struct dpreq_data *dpr;
06113    dpr = malloc(sizeof(struct dpreq_data));
06114    if (dpr) {
06115       memset(dpr, 0, sizeof(struct dpreq_data));
06116       dpr->callno = callno;
06117       ast_copy_string(dpr->context, context, sizeof(dpr->context));
06118       ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06119       if (callerid)
06120          dpr->callerid = strdup(callerid);
06121       if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) {
06122          ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06123       }
06124    } else
06125       ast_log(LOG_WARNING, "Out of memory!\n");
06126 }

int start_network_thread void   )  [static]
 

Definition at line 7993 of file chan_iax2.c.

References ast_pthread_create, netthreadid, and network_thread().

Referenced by load_module().

07994 {
07995    return ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
07996 }

int stop_stuff int  callno  )  [static]
 

Definition at line 5807 of file chan_iax2.c.

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

Referenced by socket_read().

05808 {
05809       if (iaxs[callno]->lagid > -1)
05810          ast_sched_del(sched, iaxs[callno]->lagid);
05811       iaxs[callno]->lagid = -1;
05812       if (iaxs[callno]->pingid > -1)
05813          ast_sched_del(sched, iaxs[callno]->pingid);
05814       iaxs[callno]->pingid = -1;
05815       if (iaxs[callno]->autoid > -1)
05816          ast_sched_del(sched, iaxs[callno]->autoid);
05817       iaxs[callno]->autoid = -1;
05818       if (iaxs[callno]->initid > -1)
05819          ast_sched_del(sched, iaxs[callno]->initid);
05820       iaxs[callno]->initid = -1;
05821       if (iaxs[callno]->authid > -1)
05822          ast_sched_del(sched, iaxs[callno]->authid);
05823       iaxs[callno]->authid = -1;
05824 #ifdef NEWJB
05825       if (iaxs[callno]->jbid > -1)
05826          ast_sched_del(sched, iaxs[callno]->jbid);
05827       iaxs[callno]->jbid = -1;
05828 #endif
05829       return 0;
05830 }

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

Definition at line 5982 of file chan_iax2.c.

References iax2_trunk_peer::addr, ast_inet_ntoa(), 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_DEBUG, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, peerl, send_trunk(), tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.

Referenced by network_thread().

05983 {
05984    char buf[1024];
05985    int res;
05986    char iabuf[INET_ADDRSTRLEN];
05987    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
05988    int processed = 0;
05989    int totalcalls = 0;
05990 #ifdef ZT_TIMERACK
05991    int x = 1;
05992 #endif
05993    struct timeval now;
05994    if (iaxtrunkdebug)
05995       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
05996    gettimeofday(&now, NULL);
05997    if (events & AST_IO_PRI) {
05998 #ifdef ZT_TIMERACK
05999       /* Great, this is a timing interface, just call the ioctl */
06000       if (ioctl(fd, ZT_TIMERACK, &x)) 
06001          ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
06002       res = 0;
06003 #endif      
06004    } else {
06005       /* Read and ignore from the pseudo channel for timing */
06006       res = read(fd, buf, sizeof(buf));
06007       if (res < 1) {
06008          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06009          ast_mutex_unlock(&peerl.lock);
06010          return 1;
06011       }
06012    }
06013    /* For each peer that supports trunking... */
06014    ast_mutex_lock(&tpeerlock);
06015    tpeer = tpeers;
06016    while(tpeer) {
06017       processed++;
06018       res = 0;
06019       ast_mutex_lock(&tpeer->lock);
06020       /* We can drop a single tpeer per pass.  That makes all this logic
06021          substantially easier */
06022       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06023          /* Take it out of the list, but don't free it yet, because it
06024             could be in use */
06025          if (prev)
06026             prev->next = tpeer->next;
06027          else
06028             tpeers = tpeer->next;
06029          drop = tpeer;
06030       } else {
06031          res = send_trunk(tpeer, &now);
06032          if (iaxtrunkdebug)
06033             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);
06034       }     
06035       totalcalls += res;   
06036       res = 0;
06037       ast_mutex_unlock(&tpeer->lock);
06038       prev = tpeer;
06039       tpeer = tpeer->next;
06040    }
06041    ast_mutex_unlock(&tpeerlock);
06042    if (drop) {
06043       ast_mutex_lock(&drop->lock);
06044       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06045          because by the time they could get tpeerlock, we've already grabbed it */
06046       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));
06047       free(drop->trunkdata);
06048       ast_mutex_unlock(&drop->lock);
06049       ast_mutex_destroy(&drop->lock);
06050       free(drop);
06051       
06052    }
06053    if (iaxtrunkdebug)
06054       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06055    iaxtrunkdebug =0;
06056    return 1;
06057 }

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

Definition at line 1469 of file chan_iax2.c.

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

Referenced by send_trunk().

01470 {
01471    int res;
01472    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01473                sizeof(*sin));
01474    if (res < 0) {
01475       if (option_debug)
01476          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01477       handle_error();
01478    } else
01479       res = 0;
01480    return res;
01481 }

int try_firmware char *  s  )  [static]
 

Definition at line 1151 of file chan_iax2.c.

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

Referenced by reload_firmware().

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

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

Definition at line 5286 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, chan_iax2_pvt::transfercallno, iax_ies::transferid, and chan_iax2_pvt::transferid.

Referenced by socket_read().

05287 {
05288    int newcall = 0;
05289    char newip[256];
05290    struct iax_ie_data ied;
05291    struct sockaddr_in new;
05292    
05293    
05294    memset(&ied, 0, sizeof(ied));
05295    if (ies->apparent_addr)
05296       memcpy(&new, ies->apparent_addr, sizeof(new));
05297    if (ies->callno)
05298       newcall = ies->callno;
05299    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05300       ast_log(LOG_WARNING, "Invalid transfer request\n");
05301       return -1;
05302    }
05303    pvt->transfercallno = newcall;
05304    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05305    inet_aton(newip, &pvt->transfer.sin_addr);
05306    pvt->transfer.sin_family = AF_INET;
05307    pvt->transferring = TRANSFER_BEGIN;
05308    pvt->transferid = ies->transferid;
05309    if (ies->transferid)
05310       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05311    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05312    return 0; 
05313 }

int uncompress_subclass unsigned char  csub  )  [static]
 

Definition at line 829 of file chan_iax2.c.

References IAX_FLAG_SC_LOG.

Referenced by decode_frame(), and socket_read().

00830 {
00831    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
00832    if (csub & IAX_FLAG_SC_LOG) {
00833       /* special case for 'compressed' -1 */
00834       if (csub == 0xff)
00835          return -1;
00836       else
00837          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
00838    }
00839    else
00840       return csub;
00841 }

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

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

09524 {
09525    ast_mutex_destroy(&iaxq.lock);
09526    ast_mutex_destroy(&userl.lock);
09527    ast_mutex_destroy(&peerl.lock);
09528    ast_mutex_destroy(&waresl.lock);
09529    ast_custom_function_unregister(&iaxpeer_function);
09530    return __unload_module();
09531 }

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

Definition at line 3160 of file chan_iax2.c.

References ast_mutex_unlock(), and iaxsl.

Referenced by iax2_bridge().

03161 {
03162    ast_mutex_unlock(&iaxsl[callno1]);
03163    ast_mutex_unlock(&iaxsl[callno0]);
03164 }

void unwrap_timestamp struct iax_frame fr  )  [static]
 

Definition at line 2117 of file chan_iax2.c.

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

Referenced by schedule_delivery().

02118 {
02119    int x;
02120 
02121    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02122       x = fr->ts - iaxs[fr->callno]->last;
02123       if (x < -50000) {
02124          /* Sudden big jump backwards in timestamp:
02125             What likely happened here is that miniframe timestamp has circled but we haven't
02126             gotten the update from the main packet.  We'll just pretend that we did, and
02127             update the timestamp appropriately. */
02128          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02129          if (option_debug && iaxdebug)
02130             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02131       }
02132       if (x > 50000) {
02133          /* Sudden apparent big jump forwards in timestamp:
02134             What's likely happened is this is an old miniframe belonging to the previous
02135             top-16-bit timestamp that has turned up out of order.
02136             Adjust the timestamp appropriately. */
02137          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02138          if (option_debug && iaxdebug)
02139             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02140       }
02141    }
02142 }

void update_jbsched struct chan_iax2_pvt pvt  )  [static]
 

Definition at line 2147 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, chan_iax2_pvt::rxcore, and sched.

Referenced by get_from_jb(), and schedule_delivery().

02147                                                       {
02148     int when;
02149 
02150     when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02151 
02152     /*    fprintf(stderr, "now = %d, next=%d\n", when, jb_next(pvt->jb)); */
02153 
02154     when = jb_next(pvt->jb) - when;
02155     /*   fprintf(stderr, "when = %d\n", when); */
02156 
02157     if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
02158 
02159     if(when <= 0) {
02160       /* XXX should really just empty until when > 0.. */
02161       when = 1;
02162     }
02163 
02164     pvt->jbid = ast_sched_add(sched, when, get_from_jb, (void *)pvt);
02165 }

void update_max_nontrunk void   )  [static]
 

Definition at line 978 of file chan_iax2.c.

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

Referenced by find_callno(), and make_trunk().

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

void update_max_trunk void   )  [static]
 

Definition at line 964 of file chan_iax2.c.

References ast_log(), IAX_MAX_CALLS, iaxs, LOG_DEBUG, maxtrunkcall, and option_debug.

Referenced by iax2_destroy(), and make_trunk().

00965 {
00966    int max = TRUNK_CALL_START;
00967    int x;
00968    /* XXX Prolly don't need locks here XXX */
00969    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
00970       if (iaxs[x])
00971          max = x + 1;
00972    }
00973    maxtrunkcall = max;
00974    if (option_debug && iaxdebug)
00975       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
00976 }

int update_packet struct iax_frame f  )  [static]
 

Definition at line 1681 of file chan_iax2.c.

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

Referenced by attempt_transmit().

01682 {
01683    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
01684    struct ast_iax2_full_hdr *fh = f->data;
01685    /* Mark this as a retransmission */
01686    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
01687    /* Update iseqno */
01688    f->iseqno = iaxs[f->callno]->iseqno;
01689    fh->iseqno = f->iseqno;
01690    return 0;
01691 }

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

Definition at line 5634 of file chan_iax2.c.

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

Referenced by socket_read().

05635 {
05636    /* Called from IAX thread only, with proper iaxsl lock */
05637    struct iax_ie_data ied;
05638    struct iax2_peer *p;
05639    int msgcount;
05640    char data[80];
05641    char iabuf[INET_ADDRSTRLEN];
05642    int version;
05643 
05644    memset(&ied, 0, sizeof(ied));
05645 
05646    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05647    if (!(p = find_peer(name, 1))) {
05648       ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05649       return -1;
05650    }
05651 
05652    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05653       realtime_update_peer(name, sin);
05654    if (inaddrcmp(&p->addr, sin)) {
05655       if (iax2_regfunk)
05656          iax2_regfunk(p->name, 1);
05657       /* Stash the IP address from which they registered */
05658       memcpy(&p->addr, sin, sizeof(p->addr));
05659       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05660       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05661          ast_db_put("IAX/Registry", p->name, data);
05662          if  (option_verbose > 2)
05663             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
05664                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(iabuf, sizeof(iabuf), sin->sin_addr), ntohs(sin->sin_port));
05665          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05666          register_peer_exten(p, 1);
05667          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05668       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05669          if  (option_verbose > 2)
05670             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
05671                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05672          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05673          register_peer_exten(p, 0);
05674          ast_db_del("IAX/Registry", p->name);
05675          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05676       }
05677       /* Update the host */
05678       /* Verify that the host is really there */
05679       iax2_poke_peer(p, callno);
05680    }     
05681    /* Store socket fd */
05682    p->sockfd = fd;
05683    /* Setup the expiry */
05684    if (p->expire > -1)
05685       ast_sched_del(sched, p->expire);
05686    /* treat an unspecified refresh interval as the minimum */
05687    if (!refresh)
05688       refresh = min_reg_expire;
05689    if (refresh > max_reg_expire) {
05690       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05691          p->name, max_reg_expire, refresh);
05692       p->expiry = max_reg_expire;
05693    } else if (refresh < min_reg_expire) {
05694       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05695          p->name, min_reg_expire, refresh);
05696       p->expiry = min_reg_expire;
05697    } else {
05698       p->expiry = refresh;
05699    }
05700    if (p->expiry && sin->sin_addr.s_addr)
05701       p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p);
05702    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05703    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05704    if (sin->sin_addr.s_addr) {
05705       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05706       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05707       if (!ast_strlen_zero(p->mailbox)) {
05708          if (ast_test_flag(p, IAX_MESSAGEDETAIL)) {
05709             int new, old;
05710             ast_app_messagecount(p->mailbox, &new, &old);
05711             if (new > 255)
05712                new = 255;
05713             if (old > 255)
05714                old = 255;
05715             msgcount = (old << 8) | new;
05716          } else {
05717             msgcount = ast_app_has_voicemail(p->mailbox, NULL);
05718             if (msgcount)
05719                msgcount = 65535;
05720          }
05721          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05722       }
05723       if (ast_test_flag(p, IAX_HASCALLERID)) {
05724          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05725          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05726       }
05727    }
05728    version = iax_check_version(devtype);
05729    if (version) 
05730       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05731    if (ast_test_flag(p, IAX_TEMPONLY))
05732       destroy_peer(p);
05733    return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05734 }

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

09652 {
09653    return usecnt;
09654 }

void vnak_retransmit int  callno,
int  last
[static]
 

Definition at line 5907 of file chan_iax2.c.

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

Referenced by socket_read().

05908 {
05909    struct iax_frame *f;
05910    ast_mutex_lock(&iaxq.lock);
05911    f = iaxq.head;
05912    while(f) {
05913       /* Send a copy immediately */
05914       if ((f->callno == callno) && iaxs[f->callno] &&
05915          (f->oseqno >= last)) {
05916          send_packet(f);
05917       }
05918       f = f->next;
05919    }
05920    ast_mutex_unlock(&iaxq.lock);
05921 }


Variable Documentation

char accountcode[AST_MAX_ACCOUNT_CODE] [static]
 

Definition at line 223 of file chan_iax2.c.

Referenced by check_access(), find_callno(), and set_config().

int amaflags = 0 [static]
 

Definition at line 224 of file chan_iax2.c.

Referenced by set_config().

int authdebug = 1 [static]
 

Definition at line 161 of file chan_iax2.c.

Referenced by set_config().

int autokill = 0 [static]
 

Definition at line 162 of file chan_iax2.c.

Referenced by iax2_call(), and set_config().

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

Definition at line 142 of file chan_iax2.c.

Referenced by load_module(), register_peer_exten(), and set_config().

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

Definition at line 144 of file chan_iax2.c.

Referenced by apply_context(), build_context(), check_access(), dp_lookup(), iax2_call(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), iax2_show_users(), iax2_transfer(), and spawn_dp_lookup().

char debug_jb_usage[] [static]
 

Initial value:

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

Definition at line 9422 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 9414 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 9406 of file chan_iax2.c.

int defaultsockfd = -1 [static]
 

Definition at line 177 of file chan_iax2.c.

Referenced by iax2_do_register(), load_module(), and set_config().

int delayreject = 0 [static]
 

Definition at line 225 of file chan_iax2.c.

Referenced by set_config().

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

Definition at line 140 of file chan_iax2.c.

Referenced by iax_firmware_append().

struct iax2_dpcache * dpcache [static]
 

Referenced by find_cache().

int global_rtautoclear = 120 [static]
 

Definition at line 269 of file chan_iax2.c.

Referenced by realtime_peer(), and set_config().

struct ast_flags globalflags = { 0 } [static]
 

Definition at line 228 of file chan_iax2.c.

Referenced by build_peer(), build_user(), find_callno(), iax2_request(), iax2_trunk_queue(), realtime_peer(), realtime_user(), send_trunk(), set_config(), and update_registry().

int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static]
 

Definition at line 207 of file chan_iax2.c.

Referenced by set_config().

struct ast_cli_entry iax2_cli[] [static]
 

Definition at line 9448 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

int iax2_dropcount = DEFAULT_DROP [static]
 

Definition at line 209 of file chan_iax2.c.

Referenced by schedule_delivery(), and set_config().

int iax2_encryption = 0 [static]
 

Definition at line 226 of file chan_iax2.c.

Referenced by set_config().

enum { ... } iax2_flags
 

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

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

enum { ... } iax2_state
 

struct ast_switch iax2_switch [static]
 

Definition at line 9342 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

const struct ast_channel_tech iax2_tech [static]
 

Definition at line 745 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

char iax2_test_losspct_usage[] [static]
 

Initial value:

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

Definition at line 9430 of file chan_iax2.c.

int iaxcompat = 0 [static]
 

Definition at line 163 of file chan_iax2.c.

Referenced by set_config().

int iaxdebug = 0 [static]
 

Definition at line 211 of file chan_iax2.c.

Referenced by calc_timestamp(), iax2_bridge(), iax2_do_debug(), iax2_no_debug(), and socket_read().

int iaxdefaultdpcache = 10 * 60 [static]
 

Definition at line 165 of file chan_iax2.c.

Referenced by dp_lookup().

int iaxdefaulttimeout = 5 [static]
 

Definition at line 167 of file chan_iax2.c.

Referenced by find_cache().

struct ast_custom_function iaxpeer_function
 

Definition at line 9269 of file chan_iax2.c.

Referenced by load_module(), and unload_module().

struct ast_iax2_queue iaxq [static]
 

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

struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static]
 

Definition at line 709 of file chan_iax2.c.

Referenced by __do_deliver(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), attempt_transmit(), auth_fail(), auth_reject(), auto_congest(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), destroy_peer(), dp_lookup(), find_cache(), find_callno(), fix_peerts(), function_iaxpeer(), get_from_jb(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queue_frame(), iax2_request(), iax2_set_jitter(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), make_trunk(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_locked(), send_lagrq(), send_packet(), send_ping(), socket_read(), stop_stuff(), unwrap_timestamp(), update_max_nontrunk(), update_max_trunk(), update_packet(), update_registry(), and vnak_retransmit().

ast_mutex_t iaxsl[IAX_MAX_CALLS] [static]
 

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

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

char jitter_usage[] [static]
 

Definition at line 1812 of file chan_iax2.c.

int jittershrinkrate = 2 [static]
 

Definition at line 159 of file chan_iax2.c.

Referenced by set_config().

int lagrq_time = 10 [static]
 

Definition at line 151 of file chan_iax2.c.

Referenced by find_callno(), make_trunk(), and set_config().

char language[MAX_LANGUAGE] = "" [static]
 

Definition at line 146 of file chan_iax2.c.

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

struct timeval lastused[IAX_MAX_CALLS] [static]
 

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

Referenced by iax2_set_jitter(), and set_config().

int max_reg_expire [static]
 

Definition at line 172 of file chan_iax2.c.

Referenced by set_config(), and update_registry().

int max_retries = 4 [static]
 

Definition at line 149 of file chan_iax2.c.

int maxjitterbuffer = 1000 [static]
 

Definition at line 154 of file chan_iax2.c.

Referenced by set_config().

int maxjitterinterps = 10 [static]
 

Definition at line 157 of file chan_iax2.c.

Referenced by set_config().

int maxnontrunkcall = 1 [static]
 

Definition at line 153 of file chan_iax2.c.

Referenced by update_max_nontrunk().

int maxtrunkcall = TRUNK_CALL_START [static]
 

Definition at line 152 of file chan_iax2.c.

Referenced by update_max_trunk().

int min_jitter_buffer = MIN_JITTER_BUFFER [static]
 

Definition at line 427 of file chan_iax2.c.

Referenced by set_config().

int min_reg_expire [static]
 

Definition at line 171 of file chan_iax2.c.

Referenced by set_config(), and update_registry().

struct ast_netsock_list* netsock [static]
 

Definition at line 176 of file chan_iax2.c.

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

pthread_t netthreadid = AST_PTHREADT_NULL [static]
 

Definition at line 230 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 9426 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 9418 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 9410 of file chan_iax2.c.

char* papp = "IAX2Provision" [static]
 

Definition at line 7716 of file chan_iax2.c.

Referenced by __unload_module(), and load_module().

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

Referenced by load_module().

struct ast_peer_list peerl [static]
 

Referenced by __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), delete_users(), find_peer(), iax2_getpeername(), iax2_getpeertrunk(), iax2_show_registry(), load_module(), realtime_peer(), set_config(), timing_read(), and unload_module().

int ping_time = 20 [static]
 

Definition at line 150 of file chan_iax2.c.

Referenced by find_callno(), make_trunk(), and set_config().

struct ast_codec_pref prefs [static]
 

Definition at line 138 of file chan_iax2.c.

Referenced by check_access(), create_addr(), and set_config().

char prune_realtime_usage[] [static]
 

Initial value:

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

Definition at line 9364 of file chan_iax2.c.

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

Definition at line 7717 of file chan_iax2.c.

Referenced by load_module().

char regcontext[AST_MAX_CONTEXT] = "" [static]
 

Definition at line 147 of file chan_iax2.c.

Referenced by register_peer_exten(), and set_config().

struct iax2_registry* registrations [static]
 

Definition at line 407 of file chan_iax2.c.

Referenced by delete_users(), and iax2_register().

int resyncthreshold = 1000 [static]
 

Definition at line 156 of file chan_iax2.c.

Referenced by set_config().

struct sched_context* sched [static]
 

Definition at line 205 of file chan_iax2.c.

Referenced by __unload_module(), attempt_transmit(), auth_fail(), build_peer(), delete_users(), destroy_peer(), find_callno(), iax2_ack_registry(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_frame_free(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_predestroy(), iax2_provision(), load_module(), make_trunk(), network_thread(), realtime_peer(), reg_source_db(), schedule_delivery(), socket_read(), stop_stuff(), update_jbsched(), and update_registry().

char show_cache_usage[] [static]
 

Initial value:

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

Definition at line 9356 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 9384 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 9398 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 9388 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 9360 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 9392 of file chan_iax2.c.

char show_prov_usage[] [static]
 

Definition at line 9372 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 9402 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 9352 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 9379 of file chan_iax2.c.

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

Definition at line 141 of file chan_iax2.c.

int test_losspct = 0 [static]
 

Definition at line 215 of file chan_iax2.c.

Referenced by iax2_test_losspct().

int timingfd = -1 [static]
 

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

Referenced by load_module(), and set_config().

struct iax2_trunk_peer * tpeers [static]
 

Referenced by find_tpeer(), and timing_read().

int trunkfreq = 20 [static]
 

Definition at line 160 of file chan_iax2.c.

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

int usecnt [static]
 

Definition at line 179 of file chan_iax2.c.

Referenced by ast_iax2_new(), and iax2_predestroy().

struct ast_user_list userl [static]
 

Referenced by build_user(), check_access(), delete_users(), iax2_show_users(), load_module(), prune_users(), realtime_user(), set_config(), and unload_module().

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 Mon Mar 20 08:20:20 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1