#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include <sys/ioctl.h>
#include "asterisk/dahdi_compat.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/aes.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/astobj2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | active_list |
struct | ast_firmware_list |
struct | ast_iax2_queue |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | dynamic_list |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | idle_list |
struct | parsed_dial_string |
struct | registrations |
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_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15d %-15d\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_IOSTATE_IDLE 0 |
#define | IAX_IOSTATE_PROCESSING 2 |
#define | IAX_IOSTATE_READY 1 |
#define | IAX_IOSTATE_SCHEDREADY 3 |
#define | IAX_TYPE_DYNAMIC 2 |
#define | IAX_TYPE_POOL 1 |
#define | IPTOS_MINCOST 0x02 |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 1 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | NEW_ALLOW 1 |
#define | NEW_FORCE 2 |
#define | NEW_PREVENT 0 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
enum | { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26) } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int manager, int fd, struct mansession *s, int argc, char *argv[]) |
static void | __reg_module (void) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static void | __unreg_module (void) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
Create new call, interface with the PBX core. | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static struct iax2_context * | build_context (char *context) |
static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static void | build_rand_pad (unsigned char *buf, ssize_t len) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_show_peer (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (int subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | decode_frame (aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static int | encrypt_frame (aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static struct iax2_user * | find_user (const char *name) |
static unsigned int | fix_peerts (struct timeval *tv, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static int | function_iaxpeer (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int | iax2_answer (struct ast_channel *c) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static int | iax2_do_trunk_debug (int fd, int argc, char *argv[]) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_no_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_jb_debug (int fd, int argc, char *argv[]) |
static int | iax2_no_trunk_debug (int fd, int argc, char *argv[]) |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, void *data) |
static int | iax2_prov_cmd (int fd, int argc, char *argv[]) |
static char * | iax2_prov_complete_template_3rd (const char *line, const char *word, int pos, int state) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
static int | iax2_prune_realtime (int fd, int argc, char *argv[]) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (char *value, int lineno) |
static int | iax2_reload (int fd, int argc, char *argv[]) |
static struct ast_channel * | iax2_request (const char *type, int format, void *data, int *cause) |
static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_show_cache (int fd, int argc, char *argv[]) |
static int | iax2_show_channels (int fd, int argc, char *argv[]) |
static int | iax2_show_firmware (int fd, int argc, char *argv[]) |
static int | iax2_show_netstats (int fd, int argc, char *argv[]) |
static int | iax2_show_peer (int fd, int argc, char *argv[]) |
Show one peer in detail. | |
static int | iax2_show_peers (int fd, int argc, char *argv[]) |
static int | iax2_show_registry (int fd, int argc, char *argv[]) |
static int | iax2_show_stats (int fd, int argc, char *argv[]) |
static int | iax2_show_threads (int fd, int argc, char *argv[]) |
static int | iax2_show_users (int fd, int argc, char *argv[]) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_test_losspct (int fd, int argc, char *argv[]) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static void | poke_all_peers (void) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct sockaddr_in *sin, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void * | sched_thread (void *ignore) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | scheduled_destroy (const void *vid) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_timing (void) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static int | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static void | vnak_retransmit (int callno, int last) |
static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ast_cli_entry | cli_iax2 [] |
static struct ast_cli_entry | cli_iax2_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_jb_debug_deprecated |
static struct ast_cli_entry | cli_iax2_no_trunk_debug_deprecated |
static struct ast_cli_entry | cli_iax2_trunk_debug_deprecated |
static char | context [80] = "default" |
static char | debug_jb_usage [] |
static char | debug_trunk_usage [] |
static char | debug_usage [] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static struct iax2_dpcache * | dpcache |
static ast_mutex_t | dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static int | global_rtautoclear = 120 |
static struct ast_flags | globalflags = { 0 } |
static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static int | iax2_encryption = 0 |
enum { ... } | iax2_flags |
int(*) | iax2_regfunk (const char *username, int onoff) = NULL |
static char | iax2_reload_usage [] |
enum { ... } | iax2_state |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static char | iax2_test_losspct_usage [] |
static struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
static struct ao2_container * | iax_transfercallno_pvts |
Another container of iax2_pvt structures. | |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxdynamicthreadnum = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
ast_custom_function | iaxpeer_function |
static struct ast_iax2_queue | iaxq |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct io_context * | io |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static struct timeval | lastused [ARRAY_LEN(iaxs)] |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static char | no_debug_jb_usage [] |
static char | no_debug_trunk_usage [] |
static char | no_debug_usage [] |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static char * | pdescrip |
static struct ao2_container * | peers |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
static char | prune_realtime_usage [] |
static char * | psyn = "Provision a calling IAXy with a given template" |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct sched_context * | sched |
static ast_cond_t | sched_cond |
static ast_mutex_t | sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static pthread_t | schedthreadid = AST_PTHREADT_NULL |
static char | show_cache_usage [] |
static char | show_channels_usage [] |
static char | show_firmware_usage [] |
static char | show_netstats_usage [] |
static char | show_peer_usage [] |
static char | show_peers_usage [] |
static char | show_prov_usage [] |
static char | show_reg_usage [] |
static char | show_stats_usage [] |
static char | show_threads_usage [] |
static char | show_users_usage [] |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static int | timingfd = -1 |
static unsigned int | tos = 0 |
static ast_mutex_t | tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static struct iax2_trunk_peer * | tpeers |
static int | trunkfreq = 20 |
static struct ao2_container * | users |
static struct ast_firmware_list | waresl |
Definition in file chan_iax2.c.
#define CACHE_FLAG_CANEXIST (1 << 2) |
Extension can exist
Definition at line 673 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_canmatch(), and iax2_show_cache().
#define CACHE_FLAG_EXISTS (1 << 0) |
Extension exists
Definition at line 669 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_exec(), iax2_exists(), and iax2_show_cache().
#define CACHE_FLAG_MATCHMORE (1 << 7) |
Matchmore
Definition at line 683 of file chan_iax2.c.
Referenced by complete_dpreply(), iax2_matchmore(), and iax2_show_cache().
#define CACHE_FLAG_NONEXISTENT (1 << 1) |
Extension is nonexistent
Definition at line 671 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CACHE_FLAG_PENDING (1 << 3) |
Waiting to hear back response
Definition at line 675 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TIMEOUT (1 << 4) |
Timed out
Definition at line 677 of file chan_iax2.c.
Referenced by find_cache(), and iax2_show_cache().
#define CACHE_FLAG_TRANSMITTED (1 << 5) |
Request transmitted
Definition at line 679 of file chan_iax2.c.
Referenced by iax2_dprequest(), iax2_show_cache(), and socket_process().
#define CACHE_FLAG_UNKNOWN (1 << 6) |
Timeout
Definition at line 681 of file chan_iax2.c.
Referenced by complete_dpreply(), and iax2_show_cache().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 123 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 111 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 131 of file chan_iax2.c.
#define DEFAULT_DROP 3 |
Definition at line 129 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 197 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 196 of file chan_iax2.c.
Referenced by build_peer(), and handle_response_peerpoke().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 126 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 195 of file chan_iax2.c.
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 125 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 439 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15d %-15d\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 136 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
Definition at line 178 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 186 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 191 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Value:
(IAX_CAPABILITY_FULLBANDWIDTH & \ ~AST_FORMAT_SLINEAR & \ ~AST_FORMAT_ULAW & \ ~AST_FORMAT_ALAW & \ ~AST_FORMAT_G722)
Definition at line 180 of file chan_iax2.c.
Referenced by set_config().
#define IAX_IOSTATE_IDLE 0 |
#define IAX_IOSTATE_PROCESSING 2 |
Definition at line 706 of file chan_iax2.c.
#define IAX_IOSTATE_READY 1 |
#define IAX_IOSTATE_SCHEDREADY 3 |
#define IAX_TYPE_DYNAMIC 2 |
Definition at line 710 of file chan_iax2.c.
Referenced by find_idle_thread(), iax2_process_thread(), iax2_show_threads(), and insert_idle_thread().
#define IAX_TYPE_POOL 1 |
#define IPTOS_MINCOST 0x02 |
Definition at line 114 of file chan_iax2.c.
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 448 of file chan_iax2.c.
Referenced by ast_cli_netstats(), iax2_send(), and iax2_show_channels().
#define MAX_JITTER_BUFFER 50 |
Definition at line 436 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 1 |
This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.
Definition at line 655 of file chan_iax2.c.
Referenced by load_module(), and set_config().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 442 of file chan_iax2.c.
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 440 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), and timing_read().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 128 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 437 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define NEW_ALLOW 1 |
#define NEW_FORCE 2 |
Definition at line 1520 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 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 122 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
#define SCHED_MULTITHREADED |
Definition at line 107 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1003 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2 |
Definition at line 844 of file chan_iax2.c.
Referenced by __find_callno(), make_trunk(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 445 of file chan_iax2.c.
anonymous enum |
Definition at line 231 of file chan_iax2.c.
00231 { 00232 IAX_STATE_STARTED = (1 << 0), 00233 IAX_STATE_AUTHENTICATED = (1 << 1), 00234 IAX_STATE_TBD = (1 << 2), 00235 } iax2_state;
anonymous enum |
Definition at line 242 of file chan_iax2.c.
00242 { 00243 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00244 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00245 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00246 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00247 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00248 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00249 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00250 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00251 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00252 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00253 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00254 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00255 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00256 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00257 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00258 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00259 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00260 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00261 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00262 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00263 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00264 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00265 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00266 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00267 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00268 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00269 response, so that we've achieved a three-way handshake with 00270 them before sending voice or anything else*/ 00271 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00272 } iax2_flags;
enum iax_reg_state |
REG_STATE_UNREGISTERED | |
REG_STATE_REGSENT | |
REG_STATE_AUTHSENT | |
REG_STATE_REGISTERED | |
REG_STATE_REJECTED | |
REG_STATE_TIMEOUT | |
REG_STATE_NOAUTH |
Definition at line 391 of file chan_iax2.c.
00391 { 00392 REG_STATE_UNREGISTERED = 0, 00393 REG_STATE_REGSENT, 00394 REG_STATE_AUTHSENT, 00395 REG_STATE_REGISTERED, 00396 REG_STATE_REJECTED, 00397 REG_STATE_TIMEOUT, 00398 REG_STATE_NOAUTH 00399 };
enum iax_transfer_state |
TRANSFER_NONE | |
TRANSFER_BEGIN | |
TRANSFER_READY | |
TRANSFER_RELEASED | |
TRANSFER_PASSTHROUGH | |
TRANSFER_MBEGIN | |
TRANSFER_MREADY | |
TRANSFER_MRELEASED | |
TRANSFER_MPASSTHROUGH | |
TRANSFER_MEDIA | |
TRANSFER_MEDIAPASS |
Definition at line 401 of file chan_iax2.c.
00401 { 00402 TRANSFER_NONE = 0, 00403 TRANSFER_BEGIN, 00404 TRANSFER_READY, 00405 TRANSFER_RELEASED, 00406 TRANSFER_PASSTHROUGH, 00407 TRANSFER_MBEGIN, 00408 TRANSFER_MREADY, 00409 TRANSFER_MRELEASED, 00410 TRANSFER_MPASSTHROUGH, 00411 TRANSFER_MEDIA, 00412 TRANSFER_MEDIAPASS 00413 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2303 of file chan_iax2.c.
References AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax2_registry::callno, ast_iax2_queue::count, chan_iax2_pvt::error, f, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxq, iaxs, iaxsl, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, ast_iax2_queue::queue, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), ast_frame::subclass, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
02304 { 02305 /* Attempt to transmit the frame to the remote peer... 02306 Called without iaxsl held. */ 02307 struct iax_frame *f = (struct iax_frame *)data; 02308 int freeme=0; 02309 int callno = f->callno; 02310 /* Make sure this call is still active */ 02311 if (callno) 02312 ast_mutex_lock(&iaxsl[callno]); 02313 if (callno && iaxs[callno]) { 02314 if ((f->retries < 0) /* Already ACK'd */ || 02315 (f->retries >= max_retries) /* Too many attempts */) { 02316 /* Record an error if we've transmitted too many times */ 02317 if (f->retries >= max_retries) { 02318 if (f->transfer) { 02319 /* Transfer timeout */ 02320 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 02321 } else if (f->final) { 02322 if (f->final) 02323 iax2_destroy(callno); 02324 } else { 02325 if (iaxs[callno]->owner) 02326 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno); 02327 iaxs[callno]->error = ETIMEDOUT; 02328 if (iaxs[callno]->owner) { 02329 struct ast_frame fr = { 0, }; 02330 /* Hangup the fd */ 02331 fr.frametype = AST_FRAME_CONTROL; 02332 fr.subclass = AST_CONTROL_HANGUP; 02333 iax2_queue_frame(callno, &fr); // XXX 02334 /* Remember, owner could disappear */ 02335 if (iaxs[callno] && iaxs[callno]->owner) 02336 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 02337 } else { 02338 if (iaxs[callno]->reg) { 02339 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 02340 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 02341 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 02342 } 02343 iax2_destroy(callno); 02344 } 02345 } 02346 02347 } 02348 freeme++; 02349 } else { 02350 /* Update it if it needs it */ 02351 update_packet(f); 02352 /* Attempt transmission */ 02353 send_packet(f); 02354 f->retries++; 02355 /* Try again later after 10 times as long */ 02356 f->retrytime *= 10; 02357 if (f->retrytime > MAX_RETRY_TIME) 02358 f->retrytime = MAX_RETRY_TIME; 02359 /* Transfer messages max out at one second */ 02360 if (f->transfer && (f->retrytime > 1000)) 02361 f->retrytime = 1000; 02362 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 02363 } 02364 } else { 02365 /* Make sure it gets freed */ 02366 f->retries = -1; 02367 freeme++; 02368 } 02369 if (callno) 02370 ast_mutex_unlock(&iaxsl[callno]); 02371 /* Do not try again */ 02372 if (freeme) { 02373 /* Don't attempt delivery, just remove it from the queue */ 02374 AST_LIST_LOCK(&iaxq.queue); 02375 AST_LIST_REMOVE(&iaxq.queue, f, list); 02376 iaxq.count--; 02377 AST_LIST_UNLOCK(&iaxq.queue); 02378 f->retrans = -1; 02379 /* Free the IAX frame */ 02380 iax2_frame_free(f); 02381 } 02382 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 6686 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
06687 { 06688 /* Called from IAX thread only, without iaxs lock */ 06689 int callno = (int)(long)(nothing); 06690 struct iax_ie_data ied; 06691 ast_mutex_lock(&iaxsl[callno]); 06692 if (iaxs[callno]) { 06693 memset(&ied, 0, sizeof(ied)); 06694 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 06695 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 06696 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 06697 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 06698 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 06699 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 06700 } 06701 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 06702 } 06703 ast_mutex_unlock(&iaxsl[callno]); 06704 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 3283 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
03284 { 03285 int callno = PTR_TO_CALLNO(nothing); 03286 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 03287 ast_mutex_lock(&iaxsl[callno]); 03288 if (iaxs[callno]) { 03289 iaxs[callno]->initid = -1; 03290 iax2_queue_frame(callno, &f); 03291 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 03292 } 03293 ast_mutex_unlock(&iaxsl[callno]); 03294 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 6735 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
06736 { 06737 /* Called from IAX thread only, without iaxs lock */ 06738 int callno = (int)(long)(nothing); 06739 struct iax_ie_data ied; 06740 ast_mutex_lock(&iaxsl[callno]); 06741 if (iaxs[callno]) { 06742 memset(&ied, 0, sizeof(ied)); 06743 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 06744 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 06745 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 06746 } 06747 ast_mutex_unlock(&iaxsl[callno]); 06748 }
static int __do_deliver | ( | void * | data | ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.
Definition at line 2156 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
02157 { 02158 /* Just deliver the packet by using queueing. This is called by 02159 the IAX thread with the iaxsl lock held. */ 02160 struct iax_frame *fr = data; 02161 fr->retrans = -1; 02162 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 02163 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 02164 iax2_queue_frame(fr->callno, &fr->af); 02165 /* Free our iax frame */ 02166 iax2_frame_free(fr); 02167 /* And don't run again */ 02168 return 0; 02169 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6365 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_device_state_changed(), ast_log(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event(), iax2_peer::name, option_debug, peer_unref(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
06366 { 06367 struct iax2_peer *peer = (struct iax2_peer *) data; 06368 06369 if (!peer) 06370 return; 06371 06372 peer->expire = -1; 06373 06374 if (option_debug) 06375 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name); 06376 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 06377 realtime_update_peer(peer->name, &peer->addr, 0); 06378 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 06379 /* Reset the address */ 06380 memset(&peer->addr, 0, sizeof(peer->addr)); 06381 /* Reset expiry value */ 06382 peer->expiry = min_reg_expire; 06383 if (!ast_test_flag(peer, IAX_TEMPONLY)) 06384 ast_db_del("IAX/Registry", peer->name); 06385 register_peer_exten(peer, 0); 06386 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 06387 if (iax2_regfunk) 06388 iax2_regfunk(peer->name, 0); 06389 06390 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 06391 unlink_peer(peer); 06392 06393 peer_unref(peer); 06394 }
static int __find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | return_locked, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1609 of file chan_iax2.c.
References chan_iax2_pvt::addr, ao2_find(), ao2_ref(), ast_copy_flags, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_string_field_set, ast_tvnow(), chan_iax2_pvt::callno, DEFAULT_RETRY_TIME, globalflags, iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, LOG_DEBUG, LOG_WARNING, match(), MIN_REUSE_TIME, NEW_ALLOW, new_iax(), option_debug, chan_iax2_pvt::peercallno, sched, send_lagrq(), send_ping(), store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
01610 { 01611 int res = 0; 01612 int x; 01613 struct timeval now; 01614 char host[80]; 01615 01616 if (new <= NEW_ALLOW) { 01617 if (callno) { 01618 struct chan_iax2_pvt *pvt; 01619 struct chan_iax2_pvt tmp_pvt = { 01620 .callno = dcallno, 01621 .peercallno = callno, 01622 .transfercallno = callno, 01623 /* hack!! */ 01624 .frames_received = check_dcallno, 01625 }; 01626 01627 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 01628 /* this works for finding normal call numbers not involving transfering */ 01629 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01630 if (return_locked) { 01631 ast_mutex_lock(&iaxsl[pvt->callno]); 01632 } 01633 res = pvt->callno; 01634 ao2_ref(pvt, -1); 01635 pvt = NULL; 01636 return res; 01637 } 01638 /* this searches for transfer call numbers that might not get caught otherwise */ 01639 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 01640 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr)); 01641 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 01642 if (return_locked) { 01643 ast_mutex_lock(&iaxsl[pvt->callno]); 01644 } 01645 res = pvt->callno; 01646 ao2_ref(pvt, -1); 01647 pvt = NULL; 01648 return res; 01649 } 01650 } 01651 /* This will occur on the first response to a message that we initiated, 01652 * such as a PING. */ 01653 if (dcallno) { 01654 ast_mutex_lock(&iaxsl[dcallno]); 01655 } 01656 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 01657 iaxs[dcallno]->peercallno = callno; 01658 res = dcallno; 01659 store_by_peercallno(iaxs[dcallno]); 01660 if (!res || !return_locked) { 01661 ast_mutex_unlock(&iaxsl[dcallno]); 01662 } 01663 return res; 01664 } 01665 if (dcallno) { 01666 ast_mutex_unlock(&iaxsl[dcallno]); 01667 } 01668 #ifdef IAX_OLD_FIND 01669 /* If we get here, we SHOULD NOT find a call structure for this 01670 callno; if we do, it means that there is a call structure that 01671 has a peer callno but did NOT get entered into the hash table, 01672 which is bad. 01673 01674 If we find a call structure using this old, slow method, output a log 01675 message so we'll know about it. After a few months of leaving this in 01676 place, if we don't hear about people seeing these messages, we can 01677 remove this code for good. 01678 */ 01679 01680 for (x = 1; !res && x < maxnontrunkcall; x++) { 01681 ast_mutex_lock(&iaxsl[x]); 01682 if (iaxs[x]) { 01683 /* Look for an exact match */ 01684 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01685 res = x; 01686 } 01687 } 01688 if (!res || !return_locked) 01689 ast_mutex_unlock(&iaxsl[x]); 01690 } 01691 01692 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 01693 ast_mutex_lock(&iaxsl[x]); 01694 if (iaxs[x]) { 01695 /* Look for an exact match */ 01696 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 01697 res = x; 01698 } 01699 } 01700 if (!res || !return_locked) 01701 ast_mutex_unlock(&iaxsl[x]); 01702 } 01703 01704 if (res) { 01705 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res); 01706 } 01707 #endif 01708 } 01709 if (!res && (new >= NEW_ALLOW)) { 01710 int start, found = 0; 01711 01712 /* It may seem odd that we look through the peer list for a name for 01713 * this *incoming* call. Well, it is weird. However, users don't 01714 * have an IP address/port number that we can match against. So, 01715 * this is just checking for a peer that has that IP/port and 01716 * assuming that we have a user of the same name. This isn't always 01717 * correct, but it will be changed if needed after authentication. */ 01718 if (!iax2_getpeername(*sin, host, sizeof(host))) 01719 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 01720 01721 now = ast_tvnow(); 01722 start = 2 + (ast_random() % (TRUNK_CALL_START - 1)); 01723 for (x = start; 1; x++) { 01724 if (x == TRUNK_CALL_START) { 01725 x = 1; 01726 continue; 01727 } 01728 01729 /* Find first unused call number that hasn't been used in a while */ 01730 ast_mutex_lock(&iaxsl[x]); 01731 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01732 found = 1; 01733 break; 01734 } 01735 ast_mutex_unlock(&iaxsl[x]); 01736 01737 if (x == start - 1) { 01738 break; 01739 } 01740 } 01741 /* We've still got lock held if we found a spot */ 01742 if (x == start - 1 && !found) { 01743 ast_log(LOG_WARNING, "No more space\n"); 01744 return 0; 01745 } 01746 iaxs[x] = new_iax(sin, host); 01747 update_max_nontrunk(); 01748 if (iaxs[x]) { 01749 if (option_debug && iaxdebug) 01750 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x); 01751 iaxs[x]->sockfd = sockfd; 01752 iaxs[x]->addr.sin_port = sin->sin_port; 01753 iaxs[x]->addr.sin_family = sin->sin_family; 01754 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 01755 iaxs[x]->peercallno = callno; 01756 iaxs[x]->callno = x; 01757 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 01758 iaxs[x]->expiry = min_reg_expire; 01759 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01760 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01761 iaxs[x]->amaflags = amaflags; 01762 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 01763 01764 ast_string_field_set(iaxs[x], accountcode, accountcode); 01765 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 01766 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 01767 01768 if (iaxs[x]->peercallno) { 01769 store_by_peercallno(iaxs[x]); 01770 } 01771 } else { 01772 ast_log(LOG_WARNING, "Out of resources\n"); 01773 ast_mutex_unlock(&iaxsl[x]); 01774 return 0; 01775 } 01776 if (!return_locked) 01777 ast_mutex_unlock(&iaxsl[x]); 01778 res = x; 01779 } 01780 return res; 01781 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2725 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), iax2_registry::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, iax2_registry::next, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
02726 { 02727 int callno = PTR_TO_CALLNO(p); 02728 struct chan_iax2_pvt *pvt = NULL; 02729 struct iax_frame *fr; 02730 jb_frame frame; 02731 int ret; 02732 long now; 02733 long next; 02734 struct timeval tv; 02735 02736 /* Make sure we have a valid private structure before going on */ 02737 ast_mutex_lock(&iaxsl[callno]); 02738 pvt = iaxs[callno]; 02739 if (!pvt) { 02740 /* No go! */ 02741 ast_mutex_unlock(&iaxsl[callno]); 02742 return; 02743 } 02744 02745 pvt->jbid = -1; 02746 02747 gettimeofday(&tv,NULL); 02748 /* round up a millisecond since ast_sched_runq does; */ 02749 /* prevents us from spinning while waiting for our now */ 02750 /* to catch up with runq's now */ 02751 tv.tv_usec += 1000; 02752 02753 now = ast_tvdiff_ms(tv, pvt->rxcore); 02754 02755 if(now >= (next = jb_next(pvt->jb))) { 02756 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat)); 02757 switch(ret) { 02758 case JB_OK: 02759 fr = frame.data; 02760 __do_deliver(fr); 02761 /* __do_deliver() can cause the call to disappear */ 02762 pvt = iaxs[callno]; 02763 break; 02764 case JB_INTERP: 02765 { 02766 struct ast_frame af = { 0, }; 02767 02768 /* create an interpolation frame */ 02769 af.frametype = AST_FRAME_VOICE; 02770 af.subclass = pvt->voiceformat; 02771 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 02772 af.src = "IAX2 JB interpolation"; 02773 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 02774 af.offset = AST_FRIENDLY_OFFSET; 02775 02776 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 02777 * which we'd need to malloc, and then it would free it. That seems like a drag */ 02778 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 02779 iax2_queue_frame(callno, &af); 02780 /* iax2_queue_frame() could cause the call to disappear */ 02781 pvt = iaxs[callno]; 02782 } 02783 } 02784 break; 02785 case JB_DROP: 02786 iax2_frame_free(frame.data); 02787 break; 02788 case JB_NOFRAME: 02789 case JB_EMPTY: 02790 /* do nothing */ 02791 break; 02792 default: 02793 /* shouldn't happen */ 02794 break; 02795 } 02796 } 02797 if (pvt) 02798 update_jbsched(pvt); 02799 ast_mutex_unlock(&iaxsl[callno]); 02800 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 6052 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
06053 { 06054 struct iax2_registry *reg = (struct iax2_registry *)data; 06055 reg->expire = -1; 06056 iax2_do_register(reg); 06057 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 9185 of file chan_iax2.c.
References ast_device_state_changed(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event(), iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
09186 { 09187 struct iax2_peer *peer = (struct iax2_peer *)data; 09188 int callno; 09189 09190 if (peer->lastms > -1) { 09191 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 09192 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 09193 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 09194 } 09195 if ((callno = peer->callno) > 0) { 09196 ast_mutex_lock(&iaxsl[callno]); 09197 iax2_destroy(callno); 09198 ast_mutex_unlock(&iaxsl[callno]); 09199 } 09200 peer->callno = 0; 09201 peer->lastms = -1; 09202 /* Try again quickly */ 09203 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 09204 if (peer->pokeexpire == -1) 09205 peer_unref(peer); 09206 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6798 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
06799 { 06800 struct iax2_peer *peer = (struct iax2_peer *)data; 06801 iax2_poke_peer(peer, 0); 06802 peer_unref(peer); 06803 }
static int __iax2_show_peers | ( | int | manager, | |
int | fd, | |||
struct mansession * | s, | |||
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4782 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, s, and iax2_peer::username.
Referenced by iax2_show_peers(), and manager_iax2_show_peers().
04783 { 04784 regex_t regexbuf; 04785 int havepattern = 0; 04786 int total_peers = 0; 04787 int online_peers = 0; 04788 int offline_peers = 0; 04789 int unmonitored_peers = 0; 04790 struct ao2_iterator i; 04791 04792 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 04793 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 04794 04795 struct iax2_peer *peer = NULL; 04796 char name[256]; 04797 int registeredonly=0; 04798 char *term = manager ? "\r\n" : "\n"; 04799 04800 switch (argc) { 04801 case 6: 04802 if (!strcasecmp(argv[3], "registered")) 04803 registeredonly = 1; 04804 else 04805 return RESULT_SHOWUSAGE; 04806 if (!strcasecmp(argv[4], "like")) { 04807 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 04808 return RESULT_SHOWUSAGE; 04809 havepattern = 1; 04810 } else 04811 return RESULT_SHOWUSAGE; 04812 break; 04813 case 5: 04814 if (!strcasecmp(argv[3], "like")) { 04815 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04816 return RESULT_SHOWUSAGE; 04817 havepattern = 1; 04818 } else 04819 return RESULT_SHOWUSAGE; 04820 break; 04821 case 4: 04822 if (!strcasecmp(argv[3], "registered")) 04823 registeredonly = 1; 04824 else 04825 return RESULT_SHOWUSAGE; 04826 break; 04827 case 3: 04828 break; 04829 default: 04830 return RESULT_SHOWUSAGE; 04831 } 04832 04833 04834 if (s) 04835 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04836 else 04837 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 04838 04839 i = ao2_iterator_init(peers, 0); 04840 for (peer = ao2_iterator_next(&i); peer; 04841 peer_unref(peer), peer = ao2_iterator_next(&i)) { 04842 char nm[20]; 04843 char status[20]; 04844 char srch[2000]; 04845 int retstatus; 04846 04847 if (registeredonly && !peer->addr.sin_addr.s_addr) 04848 continue; 04849 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 04850 continue; 04851 04852 if (!ast_strlen_zero(peer->username)) 04853 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 04854 else 04855 ast_copy_string(name, peer->name, sizeof(name)); 04856 04857 retstatus = peer_status(peer, status, sizeof(status)); 04858 if (retstatus > 0) 04859 online_peers++; 04860 else if (!retstatus) 04861 offline_peers++; 04862 else 04863 unmonitored_peers++; 04864 04865 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 04866 04867 snprintf(srch, sizeof(srch), FORMAT, name, 04868 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04869 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04870 nm, 04871 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04872 peer->encmethods ? "(E)" : " ", status, term); 04873 04874 if (s) 04875 astman_append(s, FORMAT, name, 04876 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)", 04877 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04878 nm, 04879 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04880 peer->encmethods ? "(E)" : " ", status, term); 04881 else 04882 ast_cli(fd, FORMAT, name, 04883 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 04884 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 04885 nm, 04886 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 04887 peer->encmethods ? "(E)" : " ", status, term); 04888 total_peers++; 04889 } 04890 04891 if (s) 04892 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04893 else 04894 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 04895 04896 if (havepattern) 04897 regfree(®exbuf); 04898 04899 return RESULT_SUCCESS; 04900 #undef FORMAT 04901 #undef FORMAT2 04902 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 11592 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 978 of file chan_iax2.c.
References ast_copy_string(), ast_log(), find_idle_thread(), IAX_IOSTATE_SCHEDREADY, LOG_DEBUG, option_debug, signal_condition(), t, and thread.
00979 { 00980 struct iax2_thread *thread = NULL; 00981 static time_t lasterror; 00982 static time_t t; 00983 00984 thread = find_idle_thread(); 00985 00986 if (thread != NULL) { 00987 thread->schedfunc = func; 00988 thread->scheddata = data; 00989 thread->iostate = IAX_IOSTATE_SCHEDREADY; 00990 #ifdef DEBUG_SCHED_MULTITHREAD 00991 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 00992 #endif 00993 signal_condition(&thread->lock, &thread->cond); 00994 return 0; 00995 } 00996 time(&t); 00997 if (t != lasterror && option_debug) 00998 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n"); 00999 lasterror = t; 01000 01001 return -1; 01002 }
static int __send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 5307 of file chan_iax2.c.
References f, and iax2_send().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
05309 { 05310 struct ast_frame f = { 0, }; 05311 05312 f.frametype = type; 05313 f.subclass = command; 05314 f.datalen = datalen; 05315 f.src = __FUNCTION__; 05316 f.data = (void *) data; 05317 05318 return iax2_send(i, &f, ts, seqno, now, transfer, final); 05319 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1065 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, LOG_WARNING, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01066 { 01067 int callno = (long) data; 01068 01069 ast_mutex_lock(&iaxsl[callno]); 01070 01071 if (iaxs[callno]) { 01072 if (iaxs[callno]->peercallno) { 01073 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01074 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01075 } else { 01076 /* I am the schedule, so I'm allowed to do this */ 01077 iaxs[callno]->lagid = -1; 01078 } 01079 } else { 01080 ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno); 01081 } 01082 01083 ast_mutex_unlock(&iaxsl[callno]); 01084 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1020 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_sched_add(), IAX_COMMAND_PING, LOG_DEBUG, option_debug, sched, send_command(), and send_ping().
Referenced by send_ping().
01021 { 01022 int callno = (long) data; 01023 01024 ast_mutex_lock(&iaxsl[callno]); 01025 01026 if (iaxs[callno]) { 01027 if (iaxs[callno]->peercallno) { 01028 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01029 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01030 } else { 01031 /* I am the schedule, so I'm allowed to do this */ 01032 iaxs[callno]->pingid = -1; 01033 } 01034 } else if (option_debug > 0) { 01035 ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno); 01036 } 01037 01038 ast_mutex_unlock(&iaxsl[callno]); 01039 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 11327 of file chan_iax2.c.
References ao2_ref(), ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_unregister_application(), ast_unregister_switch(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxactivethreadcount, iaxq, iaxs, iaxsl, iax2_thread::list, ast_firmware_list::lock, netsock, outsock, ast_iax2_queue::queue, reload_firmware(), sched, sched_context_destroy(), sched_lock, thread, and waresl.
11328 { 11329 struct iax2_thread *thread = NULL; 11330 int x; 11331 11332 /* Make sure threads do not hold shared resources when they are canceled */ 11333 11334 /* Grab the sched lock resource to keep it away from threads about to die */ 11335 /* Cancel the network thread, close the net socket */ 11336 if (netthreadid != AST_PTHREADT_NULL) { 11337 AST_LIST_LOCK(&iaxq.queue); 11338 ast_mutex_lock(&sched_lock); 11339 pthread_cancel(netthreadid); 11340 ast_cond_signal(&sched_cond); 11341 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 11342 AST_LIST_UNLOCK(&iaxq.queue); 11343 pthread_join(netthreadid, NULL); 11344 } 11345 if (schedthreadid != AST_PTHREADT_NULL) { 11346 ast_mutex_lock(&sched_lock); 11347 pthread_cancel(schedthreadid); 11348 ast_cond_signal(&sched_cond); 11349 ast_mutex_unlock(&sched_lock); 11350 pthread_join(schedthreadid, NULL); 11351 } 11352 11353 /* Call for all threads to halt */ 11354 AST_LIST_LOCK(&idle_list); 11355 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) { 11356 AST_LIST_REMOVE_CURRENT(&idle_list, list); 11357 pthread_cancel(thread->threadid); 11358 } 11359 AST_LIST_TRAVERSE_SAFE_END 11360 AST_LIST_UNLOCK(&idle_list); 11361 11362 AST_LIST_LOCK(&active_list); 11363 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) { 11364 AST_LIST_REMOVE_CURRENT(&active_list, list); 11365 pthread_cancel(thread->threadid); 11366 } 11367 AST_LIST_TRAVERSE_SAFE_END 11368 AST_LIST_UNLOCK(&active_list); 11369 11370 AST_LIST_LOCK(&dynamic_list); 11371 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) { 11372 AST_LIST_REMOVE_CURRENT(&dynamic_list, list); 11373 pthread_cancel(thread->threadid); 11374 } 11375 AST_LIST_TRAVERSE_SAFE_END 11376 AST_LIST_UNLOCK(&dynamic_list); 11377 11378 AST_LIST_HEAD_DESTROY(&iaxq.queue); 11379 11380 /* Wait for threads to exit */ 11381 while(0 < iaxactivethreadcount) 11382 usleep(10000); 11383 11384 ast_netsock_release(netsock); 11385 ast_netsock_release(outsock); 11386 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 11387 if (iaxs[x]) { 11388 iax2_destroy(x); 11389 } 11390 } 11391 ast_manager_unregister( "IAXpeers" ); 11392 ast_manager_unregister( "IAXnetstats" ); 11393 ast_unregister_application(papp); 11394 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11395 ast_unregister_switch(&iax2_switch); 11396 ast_channel_unregister(&iax2_tech); 11397 delete_users(); 11398 iax_provision_unload(); 11399 sched_context_destroy(sched); 11400 reload_firmware(1); 11401 11402 ast_mutex_destroy(&waresl.lock); 11403 11404 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11405 ast_mutex_destroy(&iaxsl[x]); 11406 } 11407 11408 ao2_ref(peers, -1); 11409 ao2_ref(users, -1); 11410 ao2_ref(iax_peercallno_pvts, -1); 11411 ao2_ref(iax_transfercallno_pvts, -1); 11412 11413 return 0; 11414 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 11592 of file chan_iax2.c.
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 5360 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
05361 { 05362 while(con) { 05363 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 05364 return -1; 05365 con = con->next; 05366 } 05367 return 0; 05368 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 5123 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, astman_append(), jb_info::current, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, chan_iax2_pvt::remote_rr, and s.
Referenced by iax2_show_netstats(), and manager_iax2_show_netstats().
05124 { 05125 int x; 05126 int numchans = 0; 05127 char first_message[10] = { 0, }; 05128 char last_message[10] = { 0, }; 05129 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 05130 ast_mutex_lock(&iaxsl[x]); 05131 if (iaxs[x]) { 05132 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 05133 char *fmt; 05134 jb_info jbinfo; 05135 05136 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 05137 jb_getinfo(iaxs[x]->jb, &jbinfo); 05138 localjitter = jbinfo.jitter; 05139 localdelay = jbinfo.current - jbinfo.min; 05140 locallost = jbinfo.frames_lost; 05141 locallosspct = jbinfo.losspct/1000; 05142 localdropped = jbinfo.frames_dropped; 05143 localooo = jbinfo.frames_ooo; 05144 } else { 05145 localjitter = -1; 05146 localdelay = 0; 05147 locallost = -1; 05148 locallosspct = -1; 05149 localdropped = 0; 05150 localooo = -1; 05151 } 05152 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 05153 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 05154 if (limit_fmt) 05155 fmt = "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"; 05156 else 05157 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"; 05158 if (s) 05159 05160 astman_append(s, fmt, 05161 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05162 iaxs[x]->pingtime, 05163 localjitter, 05164 localdelay, 05165 locallost, 05166 locallosspct, 05167 localdropped, 05168 localooo, 05169 iaxs[x]->frames_received/1000, 05170 iaxs[x]->remote_rr.jitter, 05171 iaxs[x]->remote_rr.delay, 05172 iaxs[x]->remote_rr.losscnt, 05173 iaxs[x]->remote_rr.losspct, 05174 iaxs[x]->remote_rr.dropped, 05175 iaxs[x]->remote_rr.ooo, 05176 iaxs[x]->remote_rr.packets/1000, 05177 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 05178 first_message, 05179 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 05180 last_message); 05181 else 05182 ast_cli(fd, fmt, 05183 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05184 iaxs[x]->pingtime, 05185 localjitter, 05186 localdelay, 05187 locallost, 05188 locallosspct, 05189 localdropped, 05190 localooo, 05191 iaxs[x]->frames_received/1000, 05192 iaxs[x]->remote_rr.jitter, 05193 iaxs[x]->remote_rr.delay, 05194 iaxs[x]->remote_rr.losscnt, 05195 iaxs[x]->remote_rr.losspct, 05196 iaxs[x]->remote_rr.dropped, 05197 iaxs[x]->remote_rr.ooo, 05198 iaxs[x]->remote_rr.packets/1000, 05199 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 05200 first_message, 05201 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 05202 last_message); 05203 numchans++; 05204 } 05205 ast_mutex_unlock(&iaxsl[x]); 05206 } 05207 return numchans; 05208 }
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
int | capability | |||
) | [static] |
Create new call, interface with the PBX core.
Definition at line 3948 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_channel_alloc(), ast_channel_free(), ast_copy_string(), ast_hangup(), ast_log(), ast_module_ref(), ast_mutex_lock(), ast_mutex_unlock(), ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, chan_iax2_pvt::dnid, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_tech, iaxs, iaxsl, chan_iax2_pvt::language, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
03949 { 03950 struct ast_channel *tmp; 03951 struct chan_iax2_pvt *i; 03952 struct ast_variable *v = NULL; 03953 03954 if (!(i = iaxs[callno])) { 03955 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 03956 return NULL; 03957 } 03958 03959 /* Don't hold call lock */ 03960 ast_mutex_unlock(&iaxsl[callno]); 03961 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno); 03962 ast_mutex_lock(&iaxsl[callno]); 03963 if (i != iaxs[callno]) { 03964 if (tmp) { 03965 /* unlock and relock iaxsl[callno] to preserve locking order */ 03966 ast_mutex_unlock(&iaxsl[callno]); 03967 ast_channel_free(tmp); 03968 ast_mutex_lock(&iaxsl[callno]); 03969 } 03970 return NULL; 03971 } 03972 03973 if (!tmp) 03974 return NULL; 03975 tmp->tech = &iax2_tech; 03976 /* We can support any format by default, until we get restricted */ 03977 tmp->nativeformats = capability; 03978 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 03979 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 03980 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 03981 03982 /* Don't use ast_set_callerid() here because it will 03983 * generate a NewCallerID event before the NewChannel event */ 03984 if (!ast_strlen_zero(i->ani)) 03985 tmp->cid.cid_ani = ast_strdup(i->ani); 03986 else 03987 tmp->cid.cid_ani = ast_strdup(i->cid_num); 03988 tmp->cid.cid_dnid = ast_strdup(i->dnid); 03989 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 03990 tmp->cid.cid_pres = i->calling_pres; 03991 tmp->cid.cid_ton = i->calling_ton; 03992 tmp->cid.cid_tns = i->calling_tns; 03993 if (!ast_strlen_zero(i->language)) 03994 ast_string_field_set(tmp, language, i->language); 03995 if (!ast_strlen_zero(i->accountcode)) 03996 ast_string_field_set(tmp, accountcode, i->accountcode); 03997 if (i->amaflags) 03998 tmp->amaflags = i->amaflags; 03999 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 04000 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 04001 if (i->adsi) 04002 tmp->adsicpe = i->peeradsicpe; 04003 else 04004 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 04005 i->owner = tmp; 04006 i->capability = capability; 04007 04008 for (v = i->vars ; v ; v = v->next) 04009 pbx_builtin_setvar_helper(tmp, v->name, v->value); 04010 04011 if (state != AST_STATE_DOWN) { 04012 if (ast_pbx_start(tmp)) { 04013 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 04014 ast_hangup(tmp); 04015 i->owner = NULL; 04016 return NULL; 04017 } 04018 } 04019 04020 ast_module_ref(ast_module_info->self); 04021 04022 return tmp; 04023 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 2384 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
02385 { 02386 #ifdef SCHED_MULTITHREADED 02387 if (schedule_action(__attempt_transmit, data)) 02388 #endif 02389 __attempt_transmit(data); 02390 return 0; 02391 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 6720 of file chan_iax2.c.
References AST_SCHED_DEL, auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_add(), iaxs, and sched.
Referenced by socket_process().
06721 { 06722 /* Schedule sending the authentication failure in one second, to prevent 06723 guessing */ 06724 if (iaxs[callno]) { 06725 iaxs[callno]->authfail = failcode; 06726 if (delayreject) { 06727 AST_SCHED_DEL(sched, iaxs[callno]->authid); 06728 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno); 06729 } else 06730 auth_reject((void *)(long)callno); 06731 } 06732 return 0; 06733 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 6706 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
06707 { 06708 int callno = (int)(long)(data); 06709 ast_mutex_lock(&iaxsl[callno]); 06710 if (iaxs[callno]) 06711 iaxs[callno]->authid = -1; 06712 ast_mutex_unlock(&iaxsl[callno]); 06713 #ifdef SCHED_MULTITHREADED 06714 if (schedule_action(__auth_reject, data)) 06715 #endif 06716 __auth_reject(data); 06717 return 0; 06718 }
static int authenticate | ( | const char * | challenge, | |
const char * | secret, | |||
const char * | keyn, | |||
int | authmethods, | |||
struct iax_ie_data * | ied, | |||
struct sockaddr_in * | sin, | |||
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 5920 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, md5(), MD5Final(), MD5Init(), and MD5Update().
05921 { 05922 int res = -1; 05923 int x; 05924 if (!ast_strlen_zero(keyn)) { 05925 if (!(authmethods & IAX_AUTH_RSA)) { 05926 if (ast_strlen_zero(secret)) 05927 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr)); 05928 } else if (ast_strlen_zero(challenge)) { 05929 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 05930 } else { 05931 char sig[256]; 05932 struct ast_key *key; 05933 key = ast_key_get(keyn, AST_KEY_PRIVATE); 05934 if (!key) { 05935 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 05936 } else { 05937 if (ast_sign(key, (char*)challenge, sig)) { 05938 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 05939 res = -1; 05940 } else { 05941 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 05942 res = 0; 05943 } 05944 } 05945 } 05946 } 05947 /* Fall back */ 05948 if (res && !ast_strlen_zero(secret)) { 05949 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 05950 struct MD5Context md5; 05951 unsigned char digest[16]; 05952 char digres[128]; 05953 MD5Init(&md5); 05954 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 05955 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 05956 MD5Final(digest, &md5); 05957 /* If they support md5, authenticate with it. */ 05958 for (x=0;x<16;x++) 05959 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 05960 if (pvt) { 05961 build_encryption_keys(digest, pvt); 05962 } 05963 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 05964 res = 0; 05965 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 05966 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 05967 res = 0; 05968 } else 05969 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 05970 } 05971 return res; 05972 }
static int authenticate_reply | ( | struct chan_iax2_pvt * | p, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies, | |||
const char * | override, | |||
const char * | okey | |||
) | [static] |
Definition at line 5978 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), authenticate(), iax2_peer::authmethods, chan_iax2_pvt::callno, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, iaxs, iaxsl, ies, iax2_peer::mask, merge_encryption(), iax2_peer::name, iax2_peer::outkey, peer_unref(), realtime_peer(), iax2_peer::secret, send_command(), and iax2_peer::username.
Referenced by socket_process().
05979 { 05980 struct iax2_peer *peer = NULL; 05981 /* Start pessimistic */ 05982 int res = -1; 05983 int authmethods = 0; 05984 struct iax_ie_data ied; 05985 uint16_t callno = p->callno; 05986 05987 memset(&ied, 0, sizeof(ied)); 05988 05989 if (ies->username) 05990 ast_string_field_set(p, username, ies->username); 05991 if (ies->challenge) 05992 ast_string_field_set(p, challenge, ies->challenge); 05993 if (ies->authmethods) 05994 authmethods = ies->authmethods; 05995 if (authmethods & IAX_AUTH_MD5) 05996 merge_encryption(p, ies->encmethods); 05997 else 05998 p->encmethods = 0; 05999 06000 /* Check for override RSA authentication first */ 06001 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 06002 /* Normal password authentication */ 06003 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 06004 } else { 06005 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06006 while ((peer = ao2_iterator_next(&i))) { 06007 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 06008 /* No peer specified at our end, or this is the peer */ 06009 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 06010 /* No username specified in peer rule, or this is the right username */ 06011 && (!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))) 06012 /* No specified host, or this is our host */ 06013 ) { 06014 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 06015 if (!res) { 06016 peer_unref(peer); 06017 break; 06018 } 06019 } 06020 peer_unref(peer); 06021 } 06022 if (!peer) { 06023 /* We checked our list and didn't find one. It's unlikely, but possible, 06024 that we're trying to authenticate *to* a realtime peer */ 06025 const char *peer_name = ast_strdupa(p->peer); 06026 ast_mutex_unlock(&iaxsl[callno]); 06027 if ((peer = realtime_peer(peer_name, NULL))) { 06028 ast_mutex_lock(&iaxsl[callno]); 06029 if (!(p = iaxs[callno])) { 06030 peer_unref(peer); 06031 return -1; 06032 } 06033 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 06034 peer_unref(peer); 06035 } 06036 if (!peer) { 06037 ast_mutex_lock(&iaxsl[callno]); 06038 if (!(p = iaxs[callno])) 06039 return -1; 06040 } 06041 } 06042 } 06043 if (ies->encmethods) 06044 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 06045 if (!res) 06046 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 06047 return res; 06048 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 5629 of file chan_iax2.c.
References ao2_find(), AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, iax2_user::maxauthreq, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
05630 { 05631 struct iax_ie_data ied; 05632 int res = -1, authreq_restrict = 0; 05633 char challenge[10]; 05634 struct chan_iax2_pvt *p = iaxs[call_num]; 05635 05636 memset(&ied, 0, sizeof(ied)); 05637 05638 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 05639 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05640 struct iax2_user *user, tmp_user = { 05641 .name = p->username, 05642 }; 05643 05644 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05645 if (user) { 05646 if (user->curauthreq == user->maxauthreq) 05647 authreq_restrict = 1; 05648 else 05649 user->curauthreq++; 05650 user = user_unref(user); 05651 } 05652 } 05653 05654 /* If the AUTHREQ limit test failed, send back an error */ 05655 if (authreq_restrict) { 05656 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 05657 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 05658 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 05659 return 0; 05660 } 05661 05662 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 05663 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 05664 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 05665 ast_string_field_set(p, challenge, challenge); 05666 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 05667 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 05668 } 05669 if (p->encmethods) 05670 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 05671 05672 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 05673 05674 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 05675 05676 if (p->encmethods) 05677 ast_set_flag(p, IAX_ENCRYPTED); 05678 05679 return res; 05680 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5682 of file chan_iax2.c.
References ao2_find(), ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, ies, chan_iax2_pvt::inkeys, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_user::name, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
05683 { 05684 char requeststr[256]; 05685 char md5secret[256] = ""; 05686 char secret[256] = ""; 05687 char rsasecret[256] = ""; 05688 int res = -1; 05689 int x; 05690 struct iax2_user *user, tmp_user = { 05691 .name = p->username, 05692 }; 05693 05694 if (p->authrej) { 05695 return res; 05696 } 05697 user = ao2_find(users, &tmp_user, OBJ_POINTER); 05698 if (user) { 05699 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 05700 ast_atomic_fetchadd_int(&user->curauthreq, -1); 05701 ast_clear_flag(p, IAX_MAXAUTHREQ); 05702 } 05703 ast_string_field_set(p, host, user->name); 05704 user = user_unref(user); 05705 } 05706 05707 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 05708 return res; 05709 if (ies->password) 05710 ast_copy_string(secret, ies->password, sizeof(secret)); 05711 if (ies->md5_result) 05712 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05713 if (ies->rsa_result) 05714 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05715 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 05716 struct ast_key *key; 05717 char *keyn; 05718 char tmpkey[256]; 05719 char *stringp=NULL; 05720 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 05721 stringp=tmpkey; 05722 keyn = strsep(&stringp, ":"); 05723 while(keyn) { 05724 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05725 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 05726 res = 0; 05727 break; 05728 } else if (!key) 05729 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 05730 keyn = strsep(&stringp, ":"); 05731 } 05732 } else if (p->authmethods & IAX_AUTH_MD5) { 05733 struct MD5Context md5; 05734 unsigned char digest[16]; 05735 char *tmppw, *stringp; 05736 05737 tmppw = ast_strdupa(p->secret); 05738 stringp = tmppw; 05739 while((tmppw = strsep(&stringp, ";"))) { 05740 MD5Init(&md5); 05741 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 05742 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05743 MD5Final(digest, &md5); 05744 /* If they support md5, authenticate with it. */ 05745 for (x=0;x<16;x++) 05746 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05747 if (!strcasecmp(requeststr, md5secret)) { 05748 res = 0; 05749 break; 05750 } 05751 } 05752 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 05753 if (!strcmp(secret, p->secret)) 05754 res = 0; 05755 } 05756 return res; 05757 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 3296 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), and sip_call().
03297 { 03298 #ifdef SCHED_MULTITHREADED 03299 if (schedule_action(__auto_congest, data)) 03300 #endif 03301 __auto_congest(data); 03302 return 0; 03303 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 6750 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
06751 { 06752 int callno = (int)(long)(data); 06753 ast_mutex_lock(&iaxsl[callno]); 06754 if (iaxs[callno]) { 06755 iaxs[callno]->autoid = -1; 06756 } 06757 ast_mutex_unlock(&iaxsl[callno]); 06758 #ifdef SCHED_MULTITHREADED 06759 if (schedule_action(__auto_hangup, data)) 06760 #endif 06761 __auto_hangup(data); 06762 return 0; 06763 }
static struct iax2_context* build_context | ( | char * | context | ) | [static] |
Definition at line 9513 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
09514 { 09515 struct iax2_context *con; 09516 09517 if ((con = ast_calloc(1, sizeof(*con)))) 09518 ast_copy_string(con->context, context, sizeof(con->context)); 09519 09520 return con; 09521 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 4352 of file chan_iax2.c.
References aes_decrypt_key128(), aes_encrypt_key128(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.
Referenced by build_encryption_keys().
04353 { 04354 /* it is required to hold the corresponding decrypt key to our encrypt key 04355 * in the pvt struct because queued frames occasionally need to be decrypted and 04356 * re-encrypted when updated for a retransmission */ 04357 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 04358 aes_encrypt_key128(digest, &pvt->ecx); 04359 aes_decrypt_key128(digest, &pvt->mydcx); 04360 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 4346 of file chan_iax2.c.
References aes_decrypt_key128(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
04347 { 04348 build_ecx_key(digest, pvt); 04349 aes_decrypt_key128(digest, &pvt->dcx); 04350 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create peer structure based on configuration.
Definition at line 9660 of file chan_iax2.c.
References ao2_alloc(), ao2_find(), ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, ast_dnsmgr_lookup(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), AST_SCHED_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), cid_name, cid_num, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, mailbox, ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), iax2_peer::peercontext, prefs, iax2_peer::regexten, S_OR, sched, secret, unlink_peer(), ast_variable::value, and zonetag.
09661 { 09662 struct iax2_peer *peer = NULL; 09663 struct ast_ha *oldha = NULL; 09664 int maskfound=0; 09665 int found=0; 09666 int firstpass=1; 09667 struct iax2_peer tmp_peer = { 09668 .name = name, 09669 }; 09670 09671 if (!temponly) { 09672 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 09673 if (peer && !ast_test_flag(peer, IAX_DELME)) 09674 firstpass = 0; 09675 } 09676 09677 if (peer) { 09678 found++; 09679 if (firstpass) { 09680 oldha = peer->ha; 09681 peer->ha = NULL; 09682 } 09683 unlink_peer(peer); 09684 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 09685 peer->expire = -1; 09686 peer->pokeexpire = -1; 09687 peer->sockfd = defaultsockfd; 09688 if (ast_string_field_init(peer, 32)) 09689 peer = peer_unref(peer); 09690 } 09691 09692 if (peer) { 09693 if (firstpass) { 09694 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09695 peer->encmethods = iax2_encryption; 09696 peer->adsi = adsi; 09697 ast_string_field_set(peer,secret,""); 09698 if (!found) { 09699 ast_string_field_set(peer, name, name); 09700 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09701 peer->expiry = min_reg_expire; 09702 } 09703 peer->prefs = prefs; 09704 peer->capability = iax2_capability; 09705 peer->smoothing = 0; 09706 peer->pokefreqok = DEFAULT_FREQ_OK; 09707 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 09708 ast_string_field_set(peer,context,""); 09709 ast_string_field_set(peer,peercontext,""); 09710 ast_clear_flag(peer, IAX_HASCALLERID); 09711 ast_string_field_set(peer, cid_name, ""); 09712 ast_string_field_set(peer, cid_num, ""); 09713 ast_string_field_set(peer, mohinterpret, mohinterpret); 09714 ast_string_field_set(peer, mohsuggest, mohsuggest); 09715 } 09716 09717 if (!v) { 09718 v = alt; 09719 alt = NULL; 09720 } 09721 while(v) { 09722 if (!strcasecmp(v->name, "secret")) { 09723 ast_string_field_set(peer, secret, v->value); 09724 } else if (!strcasecmp(v->name, "mailbox")) { 09725 ast_string_field_set(peer, mailbox, v->value); 09726 } else if (!strcasecmp(v->name, "hasvoicemail")) { 09727 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 09728 ast_string_field_set(peer, mailbox, name); 09729 } 09730 } else if (!strcasecmp(v->name, "mohinterpret")) { 09731 ast_string_field_set(peer, mohinterpret, v->value); 09732 } else if (!strcasecmp(v->name, "mohsuggest")) { 09733 ast_string_field_set(peer, mohsuggest, v->value); 09734 } else if (!strcasecmp(v->name, "dbsecret")) { 09735 ast_string_field_set(peer, dbsecret, v->value); 09736 } else if (!strcasecmp(v->name, "trunk")) { 09737 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 09738 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) { 09739 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name); 09740 ast_clear_flag(peer, IAX_TRUNK); 09741 } 09742 } else if (!strcasecmp(v->name, "auth")) { 09743 peer->authmethods = get_auth_methods(v->value); 09744 } else if (!strcasecmp(v->name, "encryption")) { 09745 peer->encmethods = get_encrypt_methods(v->value); 09746 } else if (!strcasecmp(v->name, "notransfer")) { 09747 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09748 ast_clear_flag(peer, IAX_TRANSFERMEDIA); 09749 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 09750 } else if (!strcasecmp(v->name, "transfer")) { 09751 if (!strcasecmp(v->value, "mediaonly")) { 09752 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 09753 } else if (ast_true(v->value)) { 09754 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 09755 } else 09756 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 09757 } else if (!strcasecmp(v->name, "jitterbuffer")) { 09758 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 09759 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 09760 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 09761 } else if (!strcasecmp(v->name, "host")) { 09762 if (!strcasecmp(v->value, "dynamic")) { 09763 /* They'll register with us */ 09764 ast_set_flag(peer, IAX_DYNAMIC); 09765 if (!found) { 09766 /* Initialize stuff iff we're not found, otherwise 09767 we keep going with what we had */ 09768 memset(&peer->addr.sin_addr, 0, 4); 09769 if (peer->addr.sin_port) { 09770 /* If we've already got a port, make it the default rather than absolute */ 09771 peer->defaddr.sin_port = peer->addr.sin_port; 09772 peer->addr.sin_port = 0; 09773 } 09774 } 09775 } else { 09776 /* Non-dynamic. Make sure we become that way if we're not */ 09777 AST_SCHED_DEL(sched, peer->expire); 09778 ast_clear_flag(peer, IAX_DYNAMIC); 09779 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) 09780 return peer_unref(peer); 09781 if (!peer->addr.sin_port) 09782 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 09783 } 09784 if (!maskfound) 09785 inet_aton("255.255.255.255", &peer->mask); 09786 } else if (!strcasecmp(v->name, "defaultip")) { 09787 if (ast_get_ip(&peer->defaddr, v->value)) 09788 return peer_unref(peer); 09789 } else if (!strcasecmp(v->name, "sourceaddress")) { 09790 peer_set_srcaddr(peer, v->value); 09791 } else if (!strcasecmp(v->name, "permit") || 09792 !strcasecmp(v->name, "deny")) { 09793 peer->ha = ast_append_ha(v->name, v->value, peer->ha); 09794 } else if (!strcasecmp(v->name, "mask")) { 09795 maskfound++; 09796 inet_aton(v->value, &peer->mask); 09797 } else if (!strcasecmp(v->name, "context")) { 09798 ast_string_field_set(peer, context, v->value); 09799 } else if (!strcasecmp(v->name, "regexten")) { 09800 ast_string_field_set(peer, regexten, v->value); 09801 } else if (!strcasecmp(v->name, "peercontext")) { 09802 ast_string_field_set(peer, peercontext, v->value); 09803 } else if (!strcasecmp(v->name, "port")) { 09804 if (ast_test_flag(peer, IAX_DYNAMIC)) 09805 peer->defaddr.sin_port = htons(atoi(v->value)); 09806 else 09807 peer->addr.sin_port = htons(atoi(v->value)); 09808 } else if (!strcasecmp(v->name, "username")) { 09809 ast_string_field_set(peer, username, v->value); 09810 } else if (!strcasecmp(v->name, "allow")) { 09811 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 09812 } else if (!strcasecmp(v->name, "disallow")) { 09813 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 09814 } else if (!strcasecmp(v->name, "callerid")) { 09815 if (!ast_strlen_zero(v->value)) { 09816 char name2[80]; 09817 char num2[80]; 09818 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 09819 ast_string_field_set(peer, cid_name, name2); 09820 ast_string_field_set(peer, cid_num, num2); 09821 } else { 09822 ast_string_field_set(peer, cid_name, ""); 09823 ast_string_field_set(peer, cid_num, ""); 09824 } 09825 ast_set_flag(peer, IAX_HASCALLERID); 09826 } else if (!strcasecmp(v->name, "fullname")) { 09827 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 09828 ast_set_flag(peer, IAX_HASCALLERID); 09829 } else if (!strcasecmp(v->name, "cid_number")) { 09830 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 09831 ast_set_flag(peer, IAX_HASCALLERID); 09832 } else if (!strcasecmp(v->name, "sendani")) { 09833 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 09834 } else if (!strcasecmp(v->name, "inkeys")) { 09835 ast_string_field_set(peer, inkeys, v->value); 09836 } else if (!strcasecmp(v->name, "outkey")) { 09837 ast_string_field_set(peer, outkey, v->value); 09838 } else if (!strcasecmp(v->name, "qualify")) { 09839 if (!strcasecmp(v->value, "no")) { 09840 peer->maxms = 0; 09841 } else if (!strcasecmp(v->value, "yes")) { 09842 peer->maxms = DEFAULT_MAXMS; 09843 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) { 09844 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); 09845 peer->maxms = 0; 09846 } 09847 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 09848 peer->smoothing = ast_true(v->value); 09849 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 09850 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) { 09851 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); 09852 } 09853 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 09854 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) { 09855 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); 09856 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 09857 } else if (!strcasecmp(v->name, "timezone")) { 09858 ast_string_field_set(peer, zonetag, v->value); 09859 } else if (!strcasecmp(v->name, "adsi")) { 09860 peer->adsi = ast_true(v->value); 09861 }/* else if (strcasecmp(v->name,"type")) */ 09862 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 09863 v = v->next; 09864 if (!v) { 09865 v = alt; 09866 alt = NULL; 09867 } 09868 } 09869 if (!peer->authmethods) 09870 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 09871 ast_clear_flag(peer, IAX_DELME); 09872 /* Make sure these are IPv4 addresses */ 09873 peer->addr.sin_family = AF_INET; 09874 } 09875 if (oldha) 09876 ast_free_ha(oldha); 09877 return peer; 09878 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 4336 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
04337 { 04338 long tmp; 04339 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 04340 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 04341 buf += sizeof(tmp); 04342 len -= sizeof(tmp); 04343 } 04344 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create in-memory user structure from configuration.
Definition at line 9894 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc(), ao2_find(), ao2_unlink(), ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_NOTICE, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_user::prefs, prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.
09895 { 09896 struct iax2_user *user = NULL; 09897 struct iax2_context *con, *conl = NULL; 09898 struct ast_ha *oldha = NULL; 09899 struct iax2_context *oldcon = NULL; 09900 int format; 09901 int firstpass=1; 09902 int oldcurauthreq = 0; 09903 char *varname = NULL, *varval = NULL; 09904 struct ast_variable *tmpvar = NULL; 09905 struct iax2_user tmp_user = { 09906 .name = name, 09907 }; 09908 09909 if (!temponly) { 09910 user = ao2_find(users, &tmp_user, OBJ_POINTER); 09911 if (user && !ast_test_flag(user, IAX_DELME)) 09912 firstpass = 0; 09913 } 09914 09915 if (user) { 09916 if (firstpass) { 09917 oldcurauthreq = user->curauthreq; 09918 oldha = user->ha; 09919 oldcon = user->contexts; 09920 user->ha = NULL; 09921 user->contexts = NULL; 09922 } 09923 /* Already in the list, remove it and it will be added back (or FREE'd) */ 09924 ao2_unlink(users, user); 09925 } else { 09926 user = ao2_alloc(sizeof(*user), user_destructor); 09927 } 09928 09929 if (user) { 09930 if (firstpass) { 09931 ast_string_field_free_memory(user); 09932 memset(user, 0, sizeof(struct iax2_user)); 09933 if (ast_string_field_init(user, 32)) { 09934 user = user_unref(user); 09935 goto cleanup; 09936 } 09937 user->maxauthreq = maxauthreq; 09938 user->curauthreq = oldcurauthreq; 09939 user->prefs = prefs; 09940 user->capability = iax2_capability; 09941 user->encmethods = iax2_encryption; 09942 user->adsi = adsi; 09943 ast_string_field_set(user, name, name); 09944 ast_string_field_set(user, language, language); 09945 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 09946 ast_clear_flag(user, IAX_HASCALLERID); 09947 ast_string_field_set(user, cid_name, ""); 09948 ast_string_field_set(user, cid_num, ""); 09949 ast_string_field_set(user, accountcode, accountcode); 09950 ast_string_field_set(user, mohinterpret, mohinterpret); 09951 ast_string_field_set(user, mohsuggest, mohsuggest); 09952 } 09953 if (!v) { 09954 v = alt; 09955 alt = NULL; 09956 } 09957 while(v) { 09958 if (!strcasecmp(v->name, "context")) { 09959 con = build_context(v->value); 09960 if (con) { 09961 if (conl) 09962 conl->next = con; 09963 else 09964 user->contexts = con; 09965 conl = con; 09966 } 09967 } else if (!strcasecmp(v->name, "permit") || 09968 !strcasecmp(v->name, "deny")) { 09969 user->ha = ast_append_ha(v->name, v->value, user->ha); 09970 } else if (!strcasecmp(v->name, "setvar")) { 09971 varname = ast_strdupa(v->value); 09972 if (varname && (varval = strchr(varname,'='))) { 09973 *varval = '\0'; 09974 varval++; 09975 if((tmpvar = ast_variable_new(varname, varval))) { 09976 tmpvar->next = user->vars; 09977 user->vars = tmpvar; 09978 } 09979 } 09980 } else if (!strcasecmp(v->name, "allow")) { 09981 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 09982 } else if (!strcasecmp(v->name, "disallow")) { 09983 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 09984 } else if (!strcasecmp(v->name, "trunk")) { 09985 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 09986 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) { 09987 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name); 09988 ast_clear_flag(user, IAX_TRUNK); 09989 } 09990 } else if (!strcasecmp(v->name, "auth")) { 09991 user->authmethods = get_auth_methods(v->value); 09992 } else if (!strcasecmp(v->name, "encryption")) { 09993 user->encmethods = get_encrypt_methods(v->value); 09994 } else if (!strcasecmp(v->name, "notransfer")) { 09995 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 09996 ast_clear_flag(user, IAX_TRANSFERMEDIA); 09997 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 09998 } else if (!strcasecmp(v->name, "transfer")) { 09999 if (!strcasecmp(v->value, "mediaonly")) { 10000 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10001 } else if (ast_true(v->value)) { 10002 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10003 } else 10004 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10005 } else if (!strcasecmp(v->name, "codecpriority")) { 10006 if(!strcasecmp(v->value, "caller")) 10007 ast_set_flag(user, IAX_CODEC_USER_FIRST); 10008 else if(!strcasecmp(v->value, "disabled")) 10009 ast_set_flag(user, IAX_CODEC_NOPREFS); 10010 else if(!strcasecmp(v->value, "reqonly")) { 10011 ast_set_flag(user, IAX_CODEC_NOCAP); 10012 ast_set_flag(user, IAX_CODEC_NOPREFS); 10013 } 10014 } else if (!strcasecmp(v->name, "jitterbuffer")) { 10015 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 10016 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 10017 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 10018 } else if (!strcasecmp(v->name, "dbsecret")) { 10019 ast_string_field_set(user, dbsecret, v->value); 10020 } else if (!strcasecmp(v->name, "secret")) { 10021 if (!ast_strlen_zero(user->secret)) { 10022 char *old = ast_strdupa(user->secret); 10023 10024 ast_string_field_build(user, secret, "%s;%s", old, v->value); 10025 } else 10026 ast_string_field_set(user, secret, v->value); 10027 } else if (!strcasecmp(v->name, "callerid")) { 10028 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 10029 char name2[80]; 10030 char num2[80]; 10031 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 10032 ast_string_field_set(user, cid_name, name2); 10033 ast_string_field_set(user, cid_num, num2); 10034 ast_set_flag(user, IAX_HASCALLERID); 10035 } else { 10036 ast_clear_flag(user, IAX_HASCALLERID); 10037 ast_string_field_set(user, cid_name, ""); 10038 ast_string_field_set(user, cid_num, ""); 10039 } 10040 } else if (!strcasecmp(v->name, "fullname")) { 10041 if (!ast_strlen_zero(v->value)) { 10042 ast_string_field_set(user, cid_name, v->value); 10043 ast_set_flag(user, IAX_HASCALLERID); 10044 } else { 10045 ast_string_field_set(user, cid_name, ""); 10046 if (ast_strlen_zero(user->cid_num)) 10047 ast_clear_flag(user, IAX_HASCALLERID); 10048 } 10049 } else if (!strcasecmp(v->name, "cid_number")) { 10050 if (!ast_strlen_zero(v->value)) { 10051 ast_string_field_set(user, cid_num, v->value); 10052 ast_set_flag(user, IAX_HASCALLERID); 10053 } else { 10054 ast_string_field_set(user, cid_num, ""); 10055 if (ast_strlen_zero(user->cid_name)) 10056 ast_clear_flag(user, IAX_HASCALLERID); 10057 } 10058 } else if (!strcasecmp(v->name, "accountcode")) { 10059 ast_string_field_set(user, accountcode, v->value); 10060 } else if (!strcasecmp(v->name, "mohinterpret")) { 10061 ast_string_field_set(user, mohinterpret, v->value); 10062 } else if (!strcasecmp(v->name, "mohsuggest")) { 10063 ast_string_field_set(user, mohsuggest, v->value); 10064 } else if (!strcasecmp(v->name, "language")) { 10065 ast_string_field_set(user, language, v->value); 10066 } else if (!strcasecmp(v->name, "amaflags")) { 10067 format = ast_cdr_amaflags2int(v->value); 10068 if (format < 0) { 10069 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10070 } else { 10071 user->amaflags = format; 10072 } 10073 } else if (!strcasecmp(v->name, "inkeys")) { 10074 ast_string_field_set(user, inkeys, v->value); 10075 } else if (!strcasecmp(v->name, "maxauthreq")) { 10076 user->maxauthreq = atoi(v->value); 10077 if (user->maxauthreq < 0) 10078 user->maxauthreq = 0; 10079 } else if (!strcasecmp(v->name, "adsi")) { 10080 user->adsi = ast_true(v->value); 10081 }/* else if (strcasecmp(v->name,"type")) */ 10082 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10083 v = v->next; 10084 if (!v) { 10085 v = alt; 10086 alt = NULL; 10087 } 10088 } 10089 if (!user->authmethods) { 10090 if (!ast_strlen_zero(user->secret)) { 10091 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 10092 if (!ast_strlen_zero(user->inkeys)) 10093 user->authmethods |= IAX_AUTH_RSA; 10094 } else if (!ast_strlen_zero(user->inkeys)) { 10095 user->authmethods = IAX_AUTH_RSA; 10096 } else { 10097 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 10098 } 10099 } 10100 ast_clear_flag(user, IAX_DELME); 10101 } 10102 cleanup: 10103 if (oldha) 10104 ast_free_ha(oldha); 10105 if (oldcon) 10106 free_context(oldcon); 10107 return user; 10108 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 10616 of file chan_iax2.c.
References ARRAY_LEN, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), chan_iax2_pvt::capability, create_addr(), find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
10617 { 10618 struct sockaddr_in sin; 10619 int x; 10620 int callno; 10621 struct iax_ie_data ied; 10622 struct create_addr_info cai; 10623 struct parsed_dial_string pds; 10624 char *tmpstr; 10625 10626 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 10627 /* Look for an *exact match* call. Once a call is negotiated, it can only 10628 look up entries for a single context */ 10629 if (!ast_mutex_trylock(&iaxsl[x])) { 10630 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 10631 return x; 10632 ast_mutex_unlock(&iaxsl[x]); 10633 } 10634 } 10635 10636 /* No match found, we need to create a new one */ 10637 10638 memset(&cai, 0, sizeof(cai)); 10639 memset(&ied, 0, sizeof(ied)); 10640 memset(&pds, 0, sizeof(pds)); 10641 10642 tmpstr = ast_strdupa(data); 10643 parse_dial_string(tmpstr, &pds); 10644 10645 if (ast_strlen_zero(pds.peer)) { 10646 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 10647 return -1; 10648 } 10649 10650 /* Populate our address from the given */ 10651 if (create_addr(pds.peer, NULL, &sin, &cai)) 10652 return -1; 10653 10654 if (option_debug) 10655 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n", 10656 pds.peer, pds.username, pds.password, pds.context); 10657 10658 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 10659 if (callno < 1) { 10660 ast_log(LOG_WARNING, "Unable to create call\n"); 10661 return -1; 10662 } 10663 10664 ast_string_field_set(iaxs[callno], dproot, data); 10665 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 10666 10667 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 10668 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 10669 /* the string format is slightly different from a standard dial string, 10670 because the context appears in the 'exten' position 10671 */ 10672 if (pds.exten) 10673 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 10674 if (pds.username) 10675 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 10676 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 10677 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 10678 /* Keep password handy */ 10679 if (pds.password) 10680 ast_string_field_set(iaxs[callno], secret, pds.password); 10681 if (pds.key) 10682 ast_string_field_set(iaxs[callno], outkey, pds.key); 10683 /* Start the call going */ 10684 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 10685 10686 return callno; 10687 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 4202 of file chan_iax2.c.
References ast_log(), ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, option_debug, and chan_iax2_pvt::rxcore.
04203 { 04204 /* Returns where in "receive time" we are. That is, how many ms 04205 since we received (or would have received) the frame with timestamp 0 */ 04206 int ms; 04207 #ifdef IAXTESTS 04208 int jit; 04209 #endif /* IAXTESTS */ 04210 /* Setup rxcore if necessary */ 04211 if (ast_tvzero(p->rxcore)) { 04212 p->rxcore = ast_tvnow(); 04213 if (option_debug && iaxdebug) 04214 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 04215 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 04216 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 04217 #if 1 04218 if (option_debug && iaxdebug) 04219 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 04220 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 04221 #endif 04222 } 04223 04224 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 04225 #ifdef IAXTESTS 04226 if (test_jit) { 04227 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 04228 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 04229 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 04230 jit = -jit; 04231 ms += jit; 04232 } 04233 } 04234 if (test_late) { 04235 ms += test_late; 04236 test_late = 0; 04237 } 04238 #endif /* IAXTESTS */ 04239 return ms; 04240 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 4069 of file chan_iax2.c.
References ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, and option_debug.
Referenced by iax2_send(), and socket_process().
04070 { 04071 int ms; 04072 int voice = 0; 04073 int genuine = 0; 04074 int adjust; 04075 int rate = ast_format_rate(f->subclass) / 1000; 04076 struct timeval *delivery = NULL; 04077 04078 04079 /* What sort of frame do we have?: voice is self-explanatory 04080 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 04081 non-genuine frames are CONTROL frames [ringing etc], DTMF 04082 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 04083 the others need a timestamp slaved to the voice frames so that they go in sequence 04084 */ 04085 if (f) { 04086 if (f->frametype == AST_FRAME_VOICE) { 04087 voice = 1; 04088 delivery = &f->delivery; 04089 } else if (f->frametype == AST_FRAME_IAX) { 04090 genuine = 1; 04091 } else if (f->frametype == AST_FRAME_CNG) { 04092 p->notsilenttx = 0; 04093 } 04094 } 04095 if (ast_tvzero(p->offset)) { 04096 gettimeofday(&p->offset, NULL); 04097 /* Round to nearest 20ms for nice looking traces */ 04098 p->offset.tv_usec -= p->offset.tv_usec % 20000; 04099 } 04100 /* If the timestamp is specified, just send it as is */ 04101 if (ts) 04102 return ts; 04103 /* If we have a time that the frame arrived, always use it to make our timestamp */ 04104 if (delivery && !ast_tvzero(*delivery)) { 04105 ms = ast_tvdiff_ms(*delivery, p->offset); 04106 if (ms < 0) { 04107 ms = 0; 04108 } 04109 if (option_debug > 2 && iaxdebug) 04110 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 04111 } else { 04112 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 04113 if (ms < 0) 04114 ms = 0; 04115 if (voice) { 04116 /* On a voice frame, use predicted values if appropriate */ 04117 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 04118 /* Adjust our txcore, keeping voice and non-voice synchronized */ 04119 /* AN EXPLANATION: 04120 When we send voice, we usually send "calculated" timestamps worked out 04121 on the basis of the number of samples sent. When we send other frames, 04122 we usually send timestamps worked out from the real clock. 04123 The problem is that they can tend to drift out of step because the 04124 source channel's clock and our clock may not be exactly at the same rate. 04125 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 04126 for this call. Moving it adjusts timestamps for non-voice frames. 04127 We make the adjustment in the style of a moving average. Each time we 04128 adjust p->offset by 10% of the difference between our clock-derived 04129 timestamp and the predicted timestamp. That's why you see "10000" 04130 below even though IAX2 timestamps are in milliseconds. 04131 The use of a moving average avoids offset moving too radically. 04132 Generally, "adjust" roams back and forth around 0, with offset hardly 04133 changing at all. But if a consistent different starts to develop it 04134 will be eliminated over the course of 10 frames (200-300msecs) 04135 */ 04136 adjust = (ms - p->nextpred); 04137 if (adjust < 0) 04138 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 04139 else if (adjust > 0) 04140 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 04141 04142 if (!p->nextpred) { 04143 p->nextpred = ms; /*f->samples / rate;*/ 04144 if (p->nextpred <= p->lastsent) 04145 p->nextpred = p->lastsent + 3; 04146 } 04147 ms = p->nextpred; 04148 } else { 04149 /* in this case, just use the actual 04150 * time, since we're either way off 04151 * (shouldn't happen), or we're ending a 04152 * silent period -- and seed the next 04153 * predicted time. Also, round ms to the 04154 * next multiple of frame size (so our 04155 * silent periods are multiples of 04156 * frame size too) */ 04157 04158 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 04159 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 04160 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 04161 04162 if (f->samples >= rate) /* check to make sure we dont core dump */ 04163 { 04164 int diff = ms % (f->samples / rate); 04165 if (diff) 04166 ms += f->samples/rate - diff; 04167 } 04168 04169 p->nextpred = ms; 04170 p->notsilenttx = 1; 04171 } 04172 } else if ( f->frametype == AST_FRAME_VIDEO ) { 04173 /* 04174 * IAX2 draft 03 says that timestamps MUST be in order. 04175 * It does not say anything about several frames having the same timestamp 04176 * When transporting video, we can have a frame that spans multiple iax packets 04177 * (so called slices), so it would make sense to use the same timestamp for all of 04178 * them 04179 * We do want to make sure that frames don't go backwards though 04180 */ 04181 if ( (unsigned int)ms < p->lastsent ) 04182 ms = p->lastsent; 04183 } else { 04184 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 04185 it's a genuine frame */ 04186 if (genuine) { 04187 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 04188 if (ms <= p->lastsent) 04189 ms = p->lastsent + 3; 04190 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 04191 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 04192 ms = p->lastsent + 3; 04193 } 04194 } 04195 } 04196 p->lastsent = ms; 04197 if (voice) 04198 p->nextpred = p->nextpred + f->samples / rate; 04199 return ms; 04200 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | tv | |||
) | [static] |
Definition at line 4025 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
04026 { 04027 unsigned long int mssincetx; /* unsigned to handle overflows */ 04028 long int ms, pred; 04029 04030 tpeer->trunkact = *tv; 04031 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime); 04032 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 04033 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 04034 tpeer->txtrunktime = *tv; 04035 tpeer->lastsent = 999999; 04036 } 04037 /* Update last transmit time now */ 04038 tpeer->lasttxtime = *tv; 04039 04040 /* Calculate ms offset */ 04041 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime); 04042 /* Predict from last value */ 04043 pred = tpeer->lastsent + sampms; 04044 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 04045 ms = pred; 04046 04047 /* We never send the same timestamp twice, so fudge a little if we must */ 04048 if (ms == tpeer->lastsent) 04049 ms = tpeer->lastsent + 1; 04050 tpeer->lastsent = ms; 04051 return ms; 04052 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 5371 of file chan_iax2.c.
References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_init(), ao2_iterator_next(), apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax2_context::context, chan_iax2_pvt::context, iax2_user::contexts, iax2_user::dbsecret, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, ies, iax2_user::inkeys, iax2_user::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, realtime_user(), secret, iax2_user::secret, user_unref(), ast_variable::value, chan_iax2_pvt::vars, and iax2_user::vars.
Referenced by socket_process().
05372 { 05373 /* Start pessimistic */ 05374 int res = -1; 05375 int version = 2; 05376 struct iax2_user *user = NULL, *best = NULL; 05377 int bestscore = 0; 05378 int gotcapability = 0; 05379 struct ast_variable *v = NULL, *tmpvar = NULL; 05380 struct ao2_iterator i; 05381 05382 if (!iaxs[callno]) 05383 return res; 05384 if (ies->called_number) 05385 ast_string_field_set(iaxs[callno], exten, ies->called_number); 05386 if (ies->calling_number) { 05387 ast_shrink_phone_number(ies->calling_number); 05388 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 05389 } 05390 if (ies->calling_name) 05391 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 05392 if (ies->calling_ani) 05393 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 05394 if (ies->dnid) 05395 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 05396 if (ies->rdnis) 05397 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 05398 if (ies->called_context) 05399 ast_string_field_set(iaxs[callno], context, ies->called_context); 05400 if (ies->language) 05401 ast_string_field_set(iaxs[callno], language, ies->language); 05402 if (ies->username) 05403 ast_string_field_set(iaxs[callno], username, ies->username); 05404 if (ies->calling_ton > -1) 05405 iaxs[callno]->calling_ton = ies->calling_ton; 05406 if (ies->calling_tns > -1) 05407 iaxs[callno]->calling_tns = ies->calling_tns; 05408 if (ies->calling_pres > -1) 05409 iaxs[callno]->calling_pres = ies->calling_pres; 05410 if (ies->format) 05411 iaxs[callno]->peerformat = ies->format; 05412 if (ies->adsicpe) 05413 iaxs[callno]->peeradsicpe = ies->adsicpe; 05414 if (ies->capability) { 05415 gotcapability = 1; 05416 iaxs[callno]->peercapability = ies->capability; 05417 } 05418 if (ies->version) 05419 version = ies->version; 05420 05421 /* Use provided preferences until told otherwise for actual preferences */ 05422 if(ies->codec_prefs) { 05423 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 05424 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 05425 } 05426 05427 if (!gotcapability) 05428 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 05429 if (version > IAX_PROTO_VERSION) { 05430 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 05431 ast_inet_ntoa(sin->sin_addr), version); 05432 return res; 05433 } 05434 /* Search the userlist for a compatible entry, and fill in the rest */ 05435 i = ao2_iterator_init(users, 0); 05436 while ((user = ao2_iterator_next(&i))) { 05437 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 05438 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 05439 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 05440 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 05441 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 05442 if (!ast_strlen_zero(iaxs[callno]->username)) { 05443 /* Exact match, stop right now. */ 05444 if (best) 05445 user_unref(best); 05446 best = user; 05447 break; 05448 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 05449 /* No required authentication */ 05450 if (user->ha) { 05451 /* There was host authentication and we passed, bonus! */ 05452 if (bestscore < 4) { 05453 bestscore = 4; 05454 if (best) 05455 user_unref(best); 05456 best = user; 05457 continue; 05458 } 05459 } else { 05460 /* No host access, but no secret, either, not bad */ 05461 if (bestscore < 3) { 05462 bestscore = 3; 05463 if (best) 05464 user_unref(best); 05465 best = user; 05466 continue; 05467 } 05468 } 05469 } else { 05470 if (user->ha) { 05471 /* Authentication, but host access too, eh, it's something.. */ 05472 if (bestscore < 2) { 05473 bestscore = 2; 05474 if (best) 05475 user_unref(best); 05476 best = user; 05477 continue; 05478 } 05479 } else { 05480 /* Authentication and no host access... This is our baseline */ 05481 if (bestscore < 1) { 05482 bestscore = 1; 05483 if (best) 05484 user_unref(best); 05485 best = user; 05486 continue; 05487 } 05488 } 05489 } 05490 } 05491 user_unref(user); 05492 } 05493 user = best; 05494 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 05495 user = realtime_user(iaxs[callno]->username, sin); 05496 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 05497 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 05498 user = user_unref(user); 05499 } 05500 } 05501 if (user) { 05502 /* We found our match (use the first) */ 05503 /* copy vars */ 05504 for (v = user->vars ; v ; v = v->next) { 05505 if((tmpvar = ast_variable_new(v->name, v->value))) { 05506 tmpvar->next = iaxs[callno]->vars; 05507 iaxs[callno]->vars = tmpvar; 05508 } 05509 } 05510 /* If a max AUTHREQ restriction is in place, activate it */ 05511 if (user->maxauthreq > 0) 05512 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 05513 iaxs[callno]->prefs = user->prefs; 05514 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 05515 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 05516 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 05517 iaxs[callno]->encmethods = user->encmethods; 05518 /* Store the requested username if not specified */ 05519 if (ast_strlen_zero(iaxs[callno]->username)) 05520 ast_string_field_set(iaxs[callno], username, user->name); 05521 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 05522 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 05523 iaxs[callno]->capability = user->capability; 05524 /* And use the default context */ 05525 if (ast_strlen_zero(iaxs[callno]->context)) { 05526 if (user->contexts) 05527 ast_string_field_set(iaxs[callno], context, user->contexts->context); 05528 else 05529 ast_string_field_set(iaxs[callno], context, context); 05530 } 05531 /* And any input keys */ 05532 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 05533 /* And the permitted authentication methods */ 05534 iaxs[callno]->authmethods = user->authmethods; 05535 iaxs[callno]->adsi = user->adsi; 05536 /* If the user has callerid, override the remote caller id. */ 05537 if (ast_test_flag(user, IAX_HASCALLERID)) { 05538 iaxs[callno]->calling_tns = 0; 05539 iaxs[callno]->calling_ton = 0; 05540 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 05541 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 05542 ast_string_field_set(iaxs[callno], ani, user->cid_num); 05543 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 05544 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 05545 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 05546 } /* else user is allowed to set their own CID settings */ 05547 if (!ast_strlen_zero(user->accountcode)) 05548 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 05549 if (!ast_strlen_zero(user->mohinterpret)) 05550 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 05551 if (!ast_strlen_zero(user->mohsuggest)) 05552 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 05553 if (user->amaflags) 05554 iaxs[callno]->amaflags = user->amaflags; 05555 if (!ast_strlen_zero(user->language)) 05556 ast_string_field_set(iaxs[callno], language, user->language); 05557 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 05558 /* Keep this check last */ 05559 if (!ast_strlen_zero(user->dbsecret)) { 05560 char *family, *key=NULL; 05561 char buf[80]; 05562 family = ast_strdupa(user->dbsecret); 05563 key = strchr(family, '/'); 05564 if (key) { 05565 *key = '\0'; 05566 key++; 05567 } 05568 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 05569 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 05570 else 05571 ast_string_field_set(iaxs[callno], secret, buf); 05572 } else 05573 ast_string_field_set(iaxs[callno], secret, user->secret); 05574 res = 0; 05575 user = user_unref(user); 05576 } else { 05577 /* user was not found, but we should still fake an AUTHREQ. 05578 * Set authmethods to the last known authmethod used by the system 05579 * Set a fake secret, it's not looked at, just required to attempt authentication. 05580 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 05581 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 05582 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05583 iaxs[callno]->authrej = 1; 05584 if (!ast_strlen_zero(iaxs[callno]->username)) { 05585 /* only send the AUTHREQ if a username was specified. */ 05586 res = 0; 05587 } 05588 } 05589 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 05590 return res; 05591 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 7108 of file chan_iax2.c.
References ast_log(), iax2_provision(), iax_provision_version(), and option_debug.
Referenced by socket_process().
07109 { 07110 unsigned int ourver; 07111 char rsi[80]; 07112 snprintf(rsi, sizeof(rsi), "si-%s", si); 07113 if (iax_provision_version(&ourver, rsi, 1)) 07114 return 0; 07115 if (option_debug) 07116 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 07117 if (ourver != ver) 07118 iax2_provision(sin, sockfd, NULL, rsi, 1); 07119 return 0; 07120 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 9539 of file chan_iax2.c.
References ast_log(), errno, LOG_ERROR, and option_debug.
Referenced by peer_set_srcaddr().
09540 { 09541 int sd; 09542 int res; 09543 09544 sd = socket(AF_INET, SOCK_DGRAM, 0); 09545 if (sd < 0) { 09546 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 09547 return -1; 09548 } 09549 09550 res = bind(sd, sa, salen); 09551 if (res < 0) { 09552 if (option_debug) 09553 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno)); 09554 close(sd); 09555 return 1; 09556 } 09557 09558 close(sd); 09559 return 0; 09560 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6098 of file chan_iax2.c.
References ARRAY_LEN, ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax2_dpcache::callno, dpcache_lock, chan_iax2_pvt::dpentries, errno, iax2_dpcache::expiry, expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, ies, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peer, and iax2_dpcache::waiters.
Referenced by socket_process().
06099 { 06100 char exten[256] = ""; 06101 int status = CACHE_FLAG_UNKNOWN; 06102 int expiry = iaxdefaultdpcache; 06103 int x; 06104 int matchmore = 0; 06105 struct iax2_dpcache *dp, *prev; 06106 06107 if (ies->called_number) 06108 ast_copy_string(exten, ies->called_number, sizeof(exten)); 06109 06110 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 06111 status = CACHE_FLAG_EXISTS; 06112 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 06113 status = CACHE_FLAG_CANEXIST; 06114 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 06115 status = CACHE_FLAG_NONEXISTENT; 06116 06117 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) { 06118 /* Don't really do anything with this */ 06119 } 06120 if (ies->refresh) 06121 expiry = ies->refresh; 06122 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 06123 matchmore = CACHE_FLAG_MATCHMORE; 06124 ast_mutex_lock(&dpcache_lock); 06125 prev = NULL; 06126 dp = pvt->dpentries; 06127 while(dp) { 06128 if (!strcmp(dp->exten, exten)) { 06129 /* Let them go */ 06130 if (prev) 06131 prev->peer = dp->peer; 06132 else 06133 pvt->dpentries = dp->peer; 06134 dp->peer = NULL; 06135 dp->callno = 0; 06136 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 06137 if (dp->flags & CACHE_FLAG_PENDING) { 06138 dp->flags &= ~CACHE_FLAG_PENDING; 06139 dp->flags |= status; 06140 dp->flags |= matchmore; 06141 } 06142 /* Wake up waiters */ 06143 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 06144 if (dp->waiters[x] > -1) { 06145 if (write(dp->waiters[x], "asdf", 4) < 0) { 06146 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 06147 } 06148 } 06149 } 06150 } 06151 prev = dp; 06152 dp = dp->peer; 06153 } 06154 ast_mutex_unlock(&dpcache_lock); 06155 return 0; 06156 }
static char* complete_iax2_show_peer | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 2565 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_strdup, iax2_peer::name, and peer_unref().
02566 { 02567 int which = 0; 02568 struct iax2_peer *peer; 02569 char *res = NULL; 02570 int wordlen = strlen(word); 02571 struct ao2_iterator i; 02572 02573 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */ 02574 if (pos != 3) 02575 return NULL; 02576 02577 i = ao2_iterator_init(peers, 0); 02578 while ((peer = ao2_iterator_next(&i))) { 02579 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 02580 res = ast_strdup(peer->name); 02581 peer_unref(peer); 02582 break; 02583 } 02584 peer_unref(peer); 02585 } 02586 02587 return res; 02588 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6158 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxq, iaxs, ies, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, iax_frame::list, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_iax2_queue::queue, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
06159 { 06160 int peercallno = 0; 06161 struct chan_iax2_pvt *pvt = iaxs[callno]; 06162 struct iax_frame *cur; 06163 jb_frame frame; 06164 06165 if (ies->callno) 06166 peercallno = ies->callno; 06167 06168 if (peercallno < 1) { 06169 ast_log(LOG_WARNING, "Invalid transfer request\n"); 06170 return -1; 06171 } 06172 remove_by_transfercallno(pvt); 06173 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 06174 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 06175 /* Reset sequence numbers */ 06176 pvt->oseqno = 0; 06177 pvt->rseqno = 0; 06178 pvt->iseqno = 0; 06179 pvt->aseqno = 0; 06180 06181 if (pvt->peercallno) { 06182 remove_by_peercallno(pvt); 06183 } 06184 pvt->peercallno = peercallno; 06185 /*this is where the transfering call swiches hash tables */ 06186 store_by_peercallno(pvt); 06187 pvt->transferring = TRANSFER_NONE; 06188 pvt->svoiceformat = -1; 06189 pvt->voiceformat = 0; 06190 pvt->svideoformat = -1; 06191 pvt->videoformat = 0; 06192 pvt->transfercallno = -1; 06193 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 06194 memset(&pvt->offset, 0, sizeof(pvt->offset)); 06195 /* reset jitterbuffer */ 06196 while(jb_getall(pvt->jb,&frame) == JB_OK) 06197 iax2_frame_free(frame.data); 06198 jb_reset(pvt->jb); 06199 pvt->lag = 0; 06200 pvt->last = 0; 06201 pvt->lastsent = 0; 06202 pvt->nextpred = 0; 06203 pvt->pingtime = DEFAULT_RETRY_TIME; 06204 AST_LIST_LOCK(&iaxq.queue); 06205 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 06206 /* We must cancel any packets that would have been transmitted 06207 because now we're talking to someone new. It's okay, they 06208 were transmitted to someone that didn't care anyway. */ 06209 if (callno == cur->callno) 06210 cur->retries = -1; 06211 } 06212 AST_LIST_UNLOCK(&iaxq.queue); 06213 return 0; 06214 }
static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1096 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01097 { 01098 int x; 01099 int power=-1; 01100 /* If it's 128 or smaller, just return it */ 01101 if (subclass < IAX_FLAG_SC_LOG) 01102 return subclass; 01103 /* Otherwise find its power */ 01104 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01105 if (subclass & (1 << x)) { 01106 if (power > -1) { 01107 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01108 return 0; 01109 } else 01110 power = x; 01111 } 01112 } 01113 return power | IAX_FLAG_SC_LOG; 01114 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 7122 of file chan_iax2.c.
References jb_info::current, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, iax_ie_append_int(), iax_ie_append_short(), IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.
Referenced by socket_process().
07123 { 07124 jb_info stats; 07125 jb_getinfo(pvt->jb, &stats); 07126 07127 memset(iep, 0, sizeof(*iep)); 07128 07129 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 07130 if(stats.frames_in == 0) stats.frames_in = 1; 07131 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 07132 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 07133 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 07134 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 07135 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 07136 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 3188 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ahp, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_gethostbyname(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, hp, IAX_DEFAULT_PORTNO, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
03189 { 03190 struct ast_hostent ahp; 03191 struct hostent *hp; 03192 struct iax2_peer *peer; 03193 int res = -1; 03194 struct ast_codec_pref ourprefs; 03195 03196 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 03197 cai->sockfd = defaultsockfd; 03198 cai->maxtime = 0; 03199 sin->sin_family = AF_INET; 03200 03201 if (!(peer = find_peer(peername, 1))) { 03202 cai->found = 0; 03203 03204 hp = ast_gethostbyname(peername, &ahp); 03205 if (hp) { 03206 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr)); 03207 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 03208 /* use global iax prefs for unknown peer/user */ 03209 /* But move the calling channel's native codec to the top of the preference list */ 03210 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 03211 if (c) 03212 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03213 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03214 return 0; 03215 } else { 03216 ast_log(LOG_WARNING, "No such host: %s\n", peername); 03217 return -1; 03218 } 03219 } 03220 03221 cai->found = 1; 03222 03223 /* if the peer has no address (current or default), return failure */ 03224 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 03225 goto return_unref; 03226 03227 /* if the peer is being monitored and is currently unreachable, return failure */ 03228 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 03229 goto return_unref; 03230 03231 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 03232 cai->maxtime = peer->maxms; 03233 cai->capability = peer->capability; 03234 cai->encmethods = peer->encmethods; 03235 cai->sockfd = peer->sockfd; 03236 cai->adsi = peer->adsi; 03237 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 03238 /* Move the calling channel's native codec to the top of the preference list */ 03239 if (c) { 03240 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats); 03241 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 03242 } 03243 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 03244 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 03245 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 03246 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 03247 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 03248 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 03249 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 03250 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 03251 if (ast_strlen_zero(peer->dbsecret)) { 03252 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 03253 } else { 03254 char *family; 03255 char *key = NULL; 03256 03257 family = ast_strdupa(peer->dbsecret); 03258 key = strchr(family, '/'); 03259 if (key) 03260 *key++ = '\0'; 03261 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 03262 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 03263 goto return_unref; 03264 } 03265 } 03266 03267 if (peer->addr.sin_addr.s_addr) { 03268 sin->sin_addr = peer->addr.sin_addr; 03269 sin->sin_port = peer->addr.sin_port; 03270 } else { 03271 sin->sin_addr = peer->defaddr.sin_addr; 03272 sin->sin_port = peer->defaddr.sin_port; 03273 } 03274 03275 res = 0; 03276 03277 return_unref: 03278 peer_unref(peer); 03279 03280 return res; 03281 }
static int decode_frame | ( | aes_decrypt_ctx * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4410 of file chan_iax2.c.
References AST_FRAME_VIDEO, ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), option_debug, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
04411 { 04412 int padding; 04413 unsigned char *workspace; 04414 04415 workspace = alloca(*datalen); 04416 memset(f, 0, sizeof(*f)); 04417 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04418 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04419 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 04420 return -1; 04421 /* Decrypt */ 04422 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 04423 04424 padding = 16 + (workspace[15] & 0x0f); 04425 if (option_debug && iaxdebug) 04426 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 04427 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 04428 return -1; 04429 04430 *datalen -= padding; 04431 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04432 f->frametype = fh->type; 04433 if (f->frametype == AST_FRAME_VIDEO) { 04434 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 04435 } else { 04436 f->subclass = uncompress_subclass(fh->csub); 04437 } 04438 } else { 04439 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04440 if (option_debug && iaxdebug) 04441 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen); 04442 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 04443 return -1; 04444 /* Decrypt */ 04445 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 04446 padding = 16 + (workspace[15] & 0x0f); 04447 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 04448 return -1; 04449 *datalen -= padding; 04450 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04451 } 04452 return 0; 04453 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 4496 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_encryption_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), and secret.
Referenced by socket_process().
04497 { 04498 int res=-1; 04499 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 04500 /* Search for possible keys, given secrets */ 04501 struct MD5Context md5; 04502 unsigned char digest[16]; 04503 char *tmppw, *stringp; 04504 04505 tmppw = ast_strdupa(iaxs[callno]->secret); 04506 stringp = tmppw; 04507 while ((tmppw = strsep(&stringp, ";"))) { 04508 MD5Init(&md5); 04509 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 04510 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 04511 MD5Final(digest, &md5); 04512 build_encryption_keys(digest, iaxs[callno]); 04513 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04514 if (!res) { 04515 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 04516 break; 04517 } 04518 } 04519 } else 04520 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 04521 return res; 04522 }
static void defer_full_frame | ( | struct iax2_thread * | from_here, | |
struct iax2_thread * | to_here | |||
) | [static] |
Queue the last read full frame for processing by a certain thread.
If there are already any full frames queued, they are sorted by sequence number.
Definition at line 7184 of file chan_iax2.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
07185 { 07186 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 07187 struct ast_iax2_full_hdr *fh, *cur_fh; 07188 07189 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 07190 return; 07191 07192 pkt_buf->len = from_here->buf_len; 07193 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 07194 07195 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 07196 ast_mutex_lock(&to_here->lock); 07197 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 07198 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 07199 if (fh->oseqno < cur_fh->oseqno) { 07200 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry); 07201 break; 07202 } 07203 } 07204 AST_LIST_TRAVERSE_SAFE_END 07205 07206 if (!cur_pkt_buf) 07207 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 07208 07209 ast_mutex_unlock(&to_here->lock); 07210 }
static void delete_users | ( | void | ) | [static] |
Definition at line 10128 of file chan_iax2.c.
References ao2_callback(), ast_dnsmgr_release(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::entry, iax2_registry::expire, free, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), chan_iax2_pvt::reg, sched, and user_delme_cb().
10129 { 10130 struct iax2_registry *reg; 10131 10132 ao2_callback(users, 0, user_delme_cb, NULL); 10133 10134 AST_LIST_LOCK(®istrations); 10135 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 10136 ast_sched_del(sched, reg->expire); 10137 if (reg->callno) { 10138 int callno = reg->callno; 10139 ast_mutex_lock(&iaxsl[callno]); 10140 if (iaxs[callno]) { 10141 iaxs[callno]->reg = NULL; 10142 iax2_destroy(callno); 10143 } 10144 ast_mutex_unlock(&iaxsl[callno]); 10145 } 10146 if (reg->dnsmgr) 10147 ast_dnsmgr_release(reg->dnsmgr); 10148 free(reg); 10149 } 10150 AST_LIST_UNLOCK(®istrations); 10151 10152 ao2_callback(peers, 0, peer_delme_cb, NULL); 10153 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 1883 of file chan_iax2.c.
References ast_iax2_firmware_header::datalen, iax_firmware::fd, free, and iax_firmware::fwh.
Referenced by reload_firmware().
01884 { 01885 /* Close firmware */ 01886 if (cur->fwh) { 01887 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 01888 } 01889 close(cur->fd); 01890 free(cur); 01891 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 6956 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
06957 { 06958 unsigned short dpstatus = 0; 06959 struct iax_ie_data ied1; 06960 int mm; 06961 06962 memset(&ied1, 0, sizeof(ied1)); 06963 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 06964 /* Must be started */ 06965 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 06966 dpstatus = IAX_DPSTATUS_EXISTS; 06967 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 06968 dpstatus = IAX_DPSTATUS_CANEXIST; 06969 } else { 06970 dpstatus = IAX_DPSTATUS_NONEXISTENT; 06971 } 06972 if (ast_ignore_pattern(context, callednum)) 06973 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 06974 if (mm) 06975 dpstatus |= IAX_DPSTATUS_MATCHMORE; 06976 if (!skiplock) 06977 ast_mutex_lock(&iaxsl[callno]); 06978 if (iaxs[callno]) { 06979 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 06980 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 06981 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 06982 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 06983 } 06984 if (!skiplock) 06985 ast_mutex_unlock(&iaxsl[callno]); 06986 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 6988 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().
06989 { 06990 /* Look up for dpreq */ 06991 struct dpreq_data *dpr = data; 06992 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 06993 if (dpr->callerid) 06994 free(dpr->callerid); 06995 free(dpr); 06996 return NULL; 06997 }
static int encrypt_frame | ( | aes_encrypt_ctx * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 4455 of file chan_iax2.c.
References ast_log(), ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), option_debug, ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send(), and update_packet().
04456 { 04457 int padding; 04458 unsigned char *workspace; 04459 workspace = alloca(*datalen + 32); 04460 if (!workspace) 04461 return -1; 04462 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 04463 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 04464 if (option_debug && iaxdebug) 04465 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 04466 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 04467 padding = 16 + (padding & 0xf); 04468 memcpy(workspace, poo, padding); 04469 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 04470 workspace[15] &= 0xf0; 04471 workspace[15] |= (padding & 0xf); 04472 if (option_debug && iaxdebug) 04473 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]); 04474 *datalen += padding; 04475 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 04476 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 04477 memcpy(poo, workspace + *datalen - 32, 32); 04478 } else { 04479 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 04480 if (option_debug && iaxdebug) 04481 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen); 04482 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 04483 padding = 16 + (padding & 0xf); 04484 memcpy(workspace, poo, padding); 04485 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 04486 workspace[15] &= 0xf0; 04487 workspace[15] |= (padding & 0x0f); 04488 *datalen += padding; 04489 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 04490 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 04491 memcpy(poo, workspace + *datalen - 32, 32); 04492 } 04493 return 0; 04494 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 6396 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by iax2_prune_realtime(), reg_source_db(), and update_registry().
06397 { 06398 #ifdef SCHED_MULTITHREADED 06399 if (schedule_action(__expire_registry, data)) 06400 #endif 06401 __expire_registry(data); 06402 return 0; 06403 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 10689 of file chan_iax2.c.
References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_frfree, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), ast_test_flag, ast_tvcmp(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, dpcache, dpcache_lock, chan_iax2_pvt::dpentries, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, free, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::next, iax2_dpcache::orig, iax2_dpcache::peer, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
10690 { 10691 struct iax2_dpcache *dp, *prev = NULL, *next; 10692 struct timeval tv; 10693 int x; 10694 int com[2]; 10695 int timeout; 10696 int old=0; 10697 int outfd; 10698 int abort; 10699 int callno; 10700 struct ast_channel *c; 10701 struct ast_frame *f; 10702 gettimeofday(&tv, NULL); 10703 dp = dpcache; 10704 while(dp) { 10705 next = dp->next; 10706 /* Expire old caches */ 10707 if (ast_tvcmp(tv, dp->expiry) > 0) { 10708 /* It's expired, let it disappear */ 10709 if (prev) 10710 prev->next = dp->next; 10711 else 10712 dpcache = dp->next; 10713 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) { 10714 /* Free memory and go again */ 10715 free(dp); 10716 } else { 10717 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); 10718 } 10719 dp = next; 10720 continue; 10721 } 10722 /* We found an entry that matches us! */ 10723 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 10724 break; 10725 prev = dp; 10726 dp = next; 10727 } 10728 if (!dp) { 10729 /* No matching entry. Create a new one. */ 10730 /* First, can we make a callno? */ 10731 callno = cache_get_callno_locked(data); 10732 if (callno < 0) { 10733 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 10734 return NULL; 10735 } 10736 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 10737 ast_mutex_unlock(&iaxsl[callno]); 10738 return NULL; 10739 } 10740 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 10741 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 10742 gettimeofday(&dp->expiry, NULL); 10743 dp->orig = dp->expiry; 10744 /* Expires in 30 mins by default */ 10745 dp->expiry.tv_sec += iaxdefaultdpcache; 10746 dp->next = dpcache; 10747 dp->flags = CACHE_FLAG_PENDING; 10748 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 10749 dp->waiters[x] = -1; 10750 dpcache = dp; 10751 dp->peer = iaxs[callno]->dpentries; 10752 iaxs[callno]->dpentries = dp; 10753 /* Send the request if we're already up */ 10754 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 10755 iax2_dprequest(dp, callno); 10756 ast_mutex_unlock(&iaxsl[callno]); 10757 } 10758 /* By here we must have a dp */ 10759 if (dp->flags & CACHE_FLAG_PENDING) { 10760 /* Okay, here it starts to get nasty. We need a pipe now to wait 10761 for a reply to come back so long as it's pending */ 10762 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) { 10763 /* Find an empty slot */ 10764 if (dp->waiters[x] < 0) 10765 break; 10766 } 10767 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) { 10768 ast_log(LOG_WARNING, "No more waiter positions available\n"); 10769 return NULL; 10770 } 10771 if (pipe(com)) { 10772 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 10773 return NULL; 10774 } 10775 dp->waiters[x] = com[1]; 10776 /* Okay, now we wait */ 10777 timeout = iaxdefaulttimeout * 1000; 10778 /* Temporarily unlock */ 10779 ast_mutex_unlock(&dpcache_lock); 10780 /* Defer any dtmf */ 10781 if (chan) 10782 old = ast_channel_defer_dtmf(chan); 10783 abort = 0; 10784 while(timeout) { 10785 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 10786 if (outfd > -1) { 10787 break; 10788 } 10789 if (c) { 10790 f = ast_read(c); 10791 if (f) 10792 ast_frfree(f); 10793 else { 10794 /* Got hung up on, abort! */ 10795 break; 10796 abort = 1; 10797 } 10798 } 10799 } 10800 if (!timeout) { 10801 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 10802 } 10803 ast_mutex_lock(&dpcache_lock); 10804 dp->waiters[x] = -1; 10805 close(com[1]); 10806 close(com[0]); 10807 if (abort) { 10808 /* Don't interpret anything, just abort. Not sure what th epoint 10809 of undeferring dtmf on a hung up channel is but hey whatever */ 10810 if (!old && chan) 10811 ast_channel_undefer_dtmf(chan); 10812 return NULL; 10813 } 10814 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 10815 /* Now to do non-independent analysis the results of our wait */ 10816 if (dp->flags & CACHE_FLAG_PENDING) { 10817 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 10818 pending. Don't let it take as long to timeout. */ 10819 dp->flags &= ~CACHE_FLAG_PENDING; 10820 dp->flags |= CACHE_FLAG_TIMEOUT; 10821 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 10822 systems without leaving it unavailable once the server comes back online */ 10823 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 10824 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 10825 if (dp->waiters[x] > -1) { 10826 if (write(dp->waiters[x], "asdf", 4) < 0) { 10827 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 10828 } 10829 } 10830 } 10831 } 10832 } 10833 /* Our caller will obtain the rest */ 10834 if (!old && chan) 10835 ast_channel_undefer_dtmf(chan); 10836 } 10837 return dp; 10838 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1783 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
01783 { 01784 01785 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 01786 }
static int find_callno_locked | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 1788 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process().
01788 { 01789 01790 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 01791 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 929 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_init(), ast_pthread_create, free, iax2_process_thread(), IAX_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::list, and thread.
Referenced by __schedule_action(), and socket_read().
00930 { 00931 pthread_attr_t attr; 00932 struct iax2_thread *thread = NULL; 00933 00934 /* Pop the head of the list off */ 00935 AST_LIST_LOCK(&idle_list); 00936 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 00937 AST_LIST_UNLOCK(&idle_list); 00938 00939 /* If no idle thread is available from the regular list, try dynamic */ 00940 if (thread == NULL) { 00941 AST_LIST_LOCK(&dynamic_list); 00942 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 00943 /* Make sure we absolutely have a thread... if not, try to make one if allowed */ 00944 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) { 00945 /* We need to MAKE a thread! */ 00946 if ((thread = ast_calloc(1, sizeof(*thread)))) { 00947 thread->threadnum = iaxdynamicthreadnum++; 00948 thread->type = IAX_TYPE_DYNAMIC; 00949 ast_mutex_init(&thread->lock); 00950 ast_cond_init(&thread->cond, NULL); 00951 pthread_attr_init(&attr); 00952 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 00953 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 00954 free(thread); 00955 thread = NULL; 00956 } else { 00957 /* All went well and the thread is up, so increment our count */ 00958 iaxdynamicthreadcount++; 00959 00960 /* Wait for the thread to be ready before returning it to the caller */ 00961 while (!thread->ready_for_signal) 00962 usleep(1); 00963 } 00964 } 00965 } 00966 AST_LIST_UNLOCK(&dynamic_list); 00967 } 00968 00969 /* this thread is not processing a full frame (since it is idle), 00970 so ensure that the field for the full frame call number is empty */ 00971 if (thread) 00972 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 00973 00974 return thread; 00975 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1174 of file chan_iax2.c.
References ao2_find(), iax2_peer::name, and realtime_peer().
01175 { 01176 struct iax2_peer *peer = NULL; 01177 struct iax2_peer tmp_peer = { 01178 .name = name, 01179 }; 01180 01181 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01182 01183 /* Now go for realtime if applicable */ 01184 if(!peer && realtime) 01185 peer = realtime_peer(name, NULL); 01186 01187 return peer; 01188 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 4242 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_mutex_lock(), inaddrcmp(), iax2_trunk_peer::lock, iax2_trunk_peer::next, tpeerlock, and tpeers.
Referenced by iax2_trunk_queue(), and socket_process().
04243 { 04244 struct iax2_trunk_peer *tpeer; 04245 04246 /* Finds and locks trunk peer */ 04247 ast_mutex_lock(&tpeerlock); 04248 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) { 04249 /* We don't lock here because tpeer->addr *never* changes */ 04250 if (!inaddrcmp(&tpeer->addr, sin)) { 04251 ast_mutex_lock(&tpeer->lock); 04252 break; 04253 } 04254 } 04255 if (!tpeer) { 04256 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 04257 ast_mutex_init(&tpeer->lock); 04258 tpeer->lastsent = 9999; 04259 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 04260 tpeer->trunkact = ast_tvnow(); 04261 ast_mutex_lock(&tpeer->lock); 04262 tpeer->next = tpeers; 04263 tpeer->sockfd = fd; 04264 tpeers = tpeer; 04265 #ifdef SO_NO_CHECK 04266 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 04267 #endif 04268 if (option_debug) 04269 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04270 } 04271 } 04272 ast_mutex_unlock(&tpeerlock); 04273 return tpeer; 04274 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1202 of file chan_iax2.c.
References ao2_find(), and iax2_user::name.
01203 { 01204 struct iax2_user tmp_user = { 01205 .name = name, 01206 }; 01207 01208 return ao2_find(users, &tmp_user, OBJ_POINTER); 01209 }
static unsigned int fix_peerts | ( | struct timeval * | tv, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 4054 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process().
04055 { 04056 long ms; /* NOT unsigned */ 04057 if (ast_tvzero(iaxs[callno]->rxcore)) { 04058 /* Initialize rxcore time if appropriate */ 04059 gettimeofday(&iaxs[callno]->rxcore, NULL); 04060 /* Round to nearest 20ms so traces look pretty */ 04061 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 04062 } 04063 /* Calculate difference between trunk and channel */ 04064 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore); 04065 /* Return as the sum of trunk time and the difference between trunk and real time */ 04066 return ms + ts; 04067 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 9291 of file chan_iax2.c.
References free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
09292 { 09293 struct iax2_context *conl; 09294 while(con) { 09295 conl = con; 09296 con = con->next; 09297 free(conl); 09298 } 09299 }
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 10962 of file chan_iax2.c.
References iax2_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
10963 { 10964 struct iax2_peer *peer; 10965 char *peername, *colname; 10966 10967 peername = ast_strdupa(data); 10968 10969 /* if our channel, return the IP address of the endpoint of current channel */ 10970 if (!strcmp(peername,"CURRENTCHANNEL")) { 10971 unsigned short callno; 10972 if (chan->tech != &iax2_tech) 10973 return -1; 10974 callno = PTR_TO_CALLNO(chan->tech_pvt); 10975 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 10976 return 0; 10977 } 10978 10979 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */ 10980 *colname++ = '\0'; 10981 else if ((colname = strchr(peername, '|'))) 10982 *colname++ = '\0'; 10983 else 10984 colname = "ip"; 10985 10986 if (!(peer = find_peer(peername, 1))) 10987 return -1; 10988 10989 if (!strcasecmp(colname, "ip")) { 10990 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 10991 } else if (!strcasecmp(colname, "status")) { 10992 peer_status(peer, buf, len); 10993 } else if (!strcasecmp(colname, "mailbox")) { 10994 ast_copy_string(buf, peer->mailbox, len); 10995 } else if (!strcasecmp(colname, "context")) { 10996 ast_copy_string(buf, peer->context, len); 10997 } else if (!strcasecmp(colname, "expire")) { 10998 snprintf(buf, len, "%d", peer->expire); 10999 } else if (!strcasecmp(colname, "dynamic")) { 11000 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 11001 } else if (!strcasecmp(colname, "callerid_name")) { 11002 ast_copy_string(buf, peer->cid_name, len); 11003 } else if (!strcasecmp(colname, "callerid_num")) { 11004 ast_copy_string(buf, peer->cid_num, len); 11005 } else if (!strcasecmp(colname, "codecs")) { 11006 ast_getformatname_multiple(buf, len -1, peer->capability); 11007 } else if (!strncasecmp(colname, "codec[", 6)) { 11008 char *codecnum, *ptr; 11009 int index = 0, codec = 0; 11010 11011 codecnum = strchr(colname, '['); 11012 *codecnum = '\0'; 11013 codecnum++; 11014 if ((ptr = strchr(codecnum, ']'))) { 11015 *ptr = '\0'; 11016 } 11017 index = atoi(codecnum); 11018 if((codec = ast_codec_pref_index(&peer->prefs, index))) { 11019 ast_copy_string(buf, ast_getformatname(codec), len); 11020 } else { 11021 buf[0] = '\0'; 11022 } 11023 } else { 11024 buf[0] = '\0'; 11025 } 11026 11027 peer_unref(peer); 11028 11029 return 0; 11030 }
static int get_auth_methods | ( | char * | value | ) | [static] |
Definition at line 9523 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
09524 { 09525 int methods = 0; 09526 if (strstr(value, "rsa")) 09527 methods |= IAX_AUTH_RSA; 09528 if (strstr(value, "md5")) 09529 methods |= IAX_AUTH_MD5; 09530 if (strstr(value, "plaintext")) 09531 methods |= IAX_AUTH_PLAINTEXT; 09532 return methods; 09533 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1051 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01052 { 01053 int e; 01054 if (!strcasecmp(s, "aes128")) 01055 e = IAX_ENCRYPT_AES128; 01056 else if (ast_true(s)) 01057 e = IAX_ENCRYPT_AES128; 01058 else 01059 e = 0; 01060 return e; 01061 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 2802 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
02803 { 02804 #ifdef SCHED_MULTITHREADED 02805 if (schedule_action(__get_from_jb, data)) 02806 #endif 02807 __get_from_jb(data); 02808 return 0; 02809 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 7154 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_pkt_buf::entry, iax2_pkt_buf::len, socket_process(), and thread.
07155 { 07156 struct iax2_pkt_buf *pkt_buf; 07157 07158 ast_mutex_lock(&thread->lock); 07159 07160 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 07161 ast_mutex_unlock(&thread->lock); 07162 07163 thread->buf = pkt_buf->buf; 07164 thread->buf_len = pkt_buf->len; 07165 thread->buf_size = pkt_buf->len + 1; 07166 07167 socket_process(thread); 07168 07169 thread->buf = NULL; 07170 ast_free(pkt_buf); 07171 07172 ast_mutex_lock(&thread->lock); 07173 } 07174 07175 ast_mutex_unlock(&thread->lock); 07176 }
static int handle_error | ( | void | ) | [static] |
Definition at line 2171 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
02172 { 02173 /* XXX Ideally we should figure out why an error occured and then abort those 02174 rather than continuing to try. Unfortunately, the published interface does 02175 not seem to work XXX */ 02176 #if 0 02177 struct sockaddr_in *sin; 02178 int res; 02179 struct msghdr m; 02180 struct sock_extended_err e; 02181 m.msg_name = NULL; 02182 m.msg_namelen = 0; 02183 m.msg_iov = NULL; 02184 m.msg_control = &e; 02185 m.msg_controllen = sizeof(e); 02186 m.msg_flags = 0; 02187 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 02188 if (res < 0) 02189 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 02190 else { 02191 if (m.msg_controllen) { 02192 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 02193 if (sin) 02194 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 02195 else 02196 ast_log(LOG_WARNING, "No address detected??\n"); 02197 } else { 02198 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 02199 } 02200 } 02201 #endif 02202 return 0; 02203 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 6217 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SCHED_DEL, ast_verbose(), EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_add(), iaxs, ies, inaddrcmp(), LOG_WARNING, manager_event(), iax2_registry::messages, option_verbose, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, sched, iax2_registry::us, and VERBOSE_PREFIX_3.
Referenced by socket_process().
06218 { 06219 struct iax2_registry *reg; 06220 /* Start pessimistic */ 06221 char peer[256] = ""; 06222 char msgstatus[60]; 06223 int refresh = 60; 06224 char ourip[256] = "<Unspecified>"; 06225 struct sockaddr_in oldus; 06226 struct sockaddr_in us; 06227 int oldmsgs; 06228 06229 memset(&us, 0, sizeof(us)); 06230 if (ies->apparent_addr) 06231 bcopy(ies->apparent_addr, &us, sizeof(us)); 06232 if (ies->username) 06233 ast_copy_string(peer, ies->username, sizeof(peer)); 06234 if (ies->refresh) 06235 refresh = ies->refresh; 06236 if (ies->calling_number) { 06237 /* We don't do anything with it really, but maybe we should */ 06238 } 06239 reg = iaxs[callno]->reg; 06240 if (!reg) { 06241 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 06242 return -1; 06243 } 06244 memcpy(&oldus, ®->us, sizeof(oldus)); 06245 oldmsgs = reg->messages; 06246 if (inaddrcmp(®->addr, sin)) { 06247 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06248 return -1; 06249 } 06250 memcpy(®->us, &us, sizeof(reg->us)); 06251 if (ies->msgcount >= 0) 06252 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 06253 /* always refresh the registration at the interval requested by the server 06254 we are registering to 06255 */ 06256 reg->refresh = refresh; 06257 AST_SCHED_DEL(sched, reg->expire); 06258 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 06259 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 06260 if (option_verbose > 2) { 06261 if (reg->messages > 255) 06262 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 06263 else if (reg->messages > 1) 06264 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 06265 else if (reg->messages > 0) 06266 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n"); 06267 else 06268 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n"); 06269 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06270 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 06271 } 06272 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 06273 } 06274 reg->regstate = REG_STATE_REGISTERED; 06275 return 0; 06276 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3860 of file chan_iax2.c.
References AST_CONTROL_ANSWER, AST_FRAME_CONTROL, ast_log(), option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03861 { 03862 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03863 if (option_debug) 03864 ast_log(LOG_DEBUG, "Answering IAX2 call\n"); 03865 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 03866 }
static enum ast_bridge_result iax2_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 3705 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), option_verbose, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, tv, unlock_both(), and VERBOSE_PREFIX_3.
03706 { 03707 struct ast_channel *cs[3]; 03708 struct ast_channel *who, *other; 03709 int to = -1; 03710 int res = -1; 03711 int transferstarted=0; 03712 struct ast_frame *f; 03713 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 03714 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 03715 struct timeval waittimer = {0, 0}, tv; 03716 03717 lock_both(callno0, callno1); 03718 if (!iaxs[callno0] || !iaxs[callno1]) { 03719 unlock_both(callno0, callno1); 03720 return AST_BRIDGE_FAILED; 03721 } 03722 /* Put them in native bridge mode */ 03723 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) { 03724 iaxs[callno0]->bridgecallno = callno1; 03725 iaxs[callno1]->bridgecallno = callno0; 03726 } 03727 /* If the bridge got retried, don't queue up more packets - the transfer request will be retransmitted as necessary */ 03728 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) { 03729 transferstarted = 1; 03730 } 03731 unlock_both(callno0, callno1); 03732 03733 /* If not, try to bridge until we can execute a transfer, if we can */ 03734 cs[0] = c0; 03735 cs[1] = c1; 03736 for (/* ever */;;) { 03737 /* Check in case we got masqueraded into */ 03738 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 03739 if (option_verbose > 2) 03740 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n"); 03741 /* Remove from native mode */ 03742 if (c0->tech == &iax2_tech) { 03743 ast_mutex_lock(&iaxsl[callno0]); 03744 iaxs[callno0]->bridgecallno = 0; 03745 ast_mutex_unlock(&iaxsl[callno0]); 03746 } 03747 if (c1->tech == &iax2_tech) { 03748 ast_mutex_lock(&iaxsl[callno1]); 03749 iaxs[callno1]->bridgecallno = 0; 03750 ast_mutex_unlock(&iaxsl[callno1]); 03751 } 03752 return AST_BRIDGE_FAILED_NOWARN; 03753 } 03754 if (c0->nativeformats != c1->nativeformats) { 03755 if (option_verbose > 2) { 03756 char buf0[255]; 03757 char buf1[255]; 03758 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 03759 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 03760 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 03761 } 03762 /* Remove from native mode */ 03763 lock_both(callno0, callno1); 03764 if (iaxs[callno0]) 03765 iaxs[callno0]->bridgecallno = 0; 03766 if (iaxs[callno1]) 03767 iaxs[callno1]->bridgecallno = 0; 03768 unlock_both(callno0, callno1); 03769 return AST_BRIDGE_FAILED_NOWARN; 03770 } 03771 /* check if transfered and if we really want native bridging */ 03772 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 03773 /* Try the transfer */ 03774 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 03775 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 03776 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 03777 transferstarted = 1; 03778 } 03779 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 03780 /* Call has been transferred. We're no longer involved */ 03781 gettimeofday(&tv, NULL); 03782 if (ast_tvzero(waittimer)) { 03783 waittimer = tv; 03784 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 03785 c0->_softhangup |= AST_SOFTHANGUP_DEV; 03786 c1->_softhangup |= AST_SOFTHANGUP_DEV; 03787 *fo = NULL; 03788 *rc = c0; 03789 res = AST_BRIDGE_COMPLETE; 03790 break; 03791 } 03792 } 03793 to = 1000; 03794 who = ast_waitfor_n(cs, 2, &to); 03795 if (timeoutms > -1) { 03796 timeoutms -= (1000 - to); 03797 if (timeoutms < 0) 03798 timeoutms = 0; 03799 } 03800 if (!who) { 03801 if (!timeoutms) { 03802 res = AST_BRIDGE_RETRY; 03803 break; 03804 } 03805 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03806 res = AST_BRIDGE_FAILED; 03807 break; 03808 } 03809 continue; 03810 } 03811 f = ast_read(who); 03812 if (!f) { 03813 *fo = NULL; 03814 *rc = who; 03815 res = AST_BRIDGE_COMPLETE; 03816 break; 03817 } 03818 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 03819 *fo = f; 03820 *rc = who; 03821 res = AST_BRIDGE_COMPLETE; 03822 break; 03823 } 03824 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 03825 if ((f->frametype == AST_FRAME_VOICE) || 03826 (f->frametype == AST_FRAME_TEXT) || 03827 (f->frametype == AST_FRAME_VIDEO) || 03828 (f->frametype == AST_FRAME_IMAGE) || 03829 (f->frametype == AST_FRAME_DTMF) || 03830 (f->frametype == AST_FRAME_CONTROL)) { 03831 /* monitored dtmf take out of the bridge. 03832 * check if we monitor the specific source. 03833 */ 03834 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 03835 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 03836 *rc = who; 03837 *fo = f; 03838 res = AST_BRIDGE_COMPLETE; 03839 /* Remove from native mode */ 03840 break; 03841 } 03842 /* everything else goes to the other side */ 03843 ast_write(other, f); 03844 } 03845 ast_frfree(f); 03846 /* Swap who gets priority */ 03847 cs[2] = cs[0]; 03848 cs[0] = cs[1]; 03849 cs[1] = cs[2]; 03850 } 03851 lock_both(callno0, callno1); 03852 if(iaxs[callno0]) 03853 iaxs[callno0]->bridgecallno = 0; 03854 if(iaxs[callno1]) 03855 iaxs[callno1]->bridgecallno = 0; 03856 unlock_both(callno0, callno1); 03857 return res; 03858 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 3402 of file chan_iax2.c.
References ast_channel::_state, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_copy_string(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, auto_congest(), CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, create_addr(), chan_iax2_pvt::encmethods, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_LANGUAGE, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, chan_iax2_pvt::initid, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, create_addr_info::outkey, parse_dial_string(), chan_iax2_pvt::pingtime, PTR_TO_CALLNO, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_channel::tech_pvt, and chan_iax2_pvt::username.
03403 { 03404 struct sockaddr_in sin; 03405 char *l=NULL, *n=NULL, *tmpstr; 03406 struct iax_ie_data ied; 03407 char *defaultrdest = "s"; 03408 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03409 struct parsed_dial_string pds; 03410 struct create_addr_info cai; 03411 03412 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 03413 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 03414 return -1; 03415 } 03416 03417 memset(&cai, 0, sizeof(cai)); 03418 cai.encmethods = iax2_encryption; 03419 03420 memset(&pds, 0, sizeof(pds)); 03421 tmpstr = ast_strdupa(dest); 03422 parse_dial_string(tmpstr, &pds); 03423 03424 if (ast_strlen_zero(pds.peer)) { 03425 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 03426 return -1; 03427 } 03428 03429 if (!pds.exten) { 03430 pds.exten = defaultrdest; 03431 } 03432 03433 if (create_addr(pds.peer, c, &sin, &cai)) { 03434 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 03435 return -1; 03436 } 03437 03438 if (!pds.username && !ast_strlen_zero(cai.username)) 03439 pds.username = cai.username; 03440 if (!pds.password && !ast_strlen_zero(cai.secret)) 03441 pds.password = cai.secret; 03442 if (!pds.key && !ast_strlen_zero(cai.outkey)) 03443 pds.key = cai.outkey; 03444 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 03445 pds.context = cai.peercontext; 03446 03447 /* Keep track of the context for outgoing calls too */ 03448 ast_copy_string(c->context, cai.context, sizeof(c->context)); 03449 03450 if (pds.port) 03451 sin.sin_port = htons(atoi(pds.port)); 03452 03453 l = c->cid.cid_num; 03454 n = c->cid.cid_name; 03455 03456 /* Now build request */ 03457 memset(&ied, 0, sizeof(ied)); 03458 03459 /* On new call, first IE MUST be IAX version of caller */ 03460 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 03461 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 03462 if (pds.options && strchr(pds.options, 'a')) { 03463 /* Request auto answer */ 03464 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 03465 } 03466 03467 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 03468 03469 if (l) { 03470 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 03471 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03472 } else { 03473 if (n) 03474 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 03475 else 03476 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 03477 } 03478 03479 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 03480 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 03481 03482 if (n) 03483 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 03484 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 03485 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 03486 03487 if (!ast_strlen_zero(c->language)) 03488 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 03489 if (!ast_strlen_zero(c->cid.cid_dnid)) 03490 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 03491 if (!ast_strlen_zero(c->cid.cid_rdnis)) 03492 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 03493 03494 if (pds.context) 03495 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 03496 03497 if (pds.username) 03498 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 03499 03500 if (cai.encmethods) 03501 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 03502 03503 ast_mutex_lock(&iaxsl[callno]); 03504 03505 if (!ast_strlen_zero(c->context)) 03506 ast_string_field_set(iaxs[callno], context, c->context); 03507 03508 if (pds.username) 03509 ast_string_field_set(iaxs[callno], username, pds.username); 03510 03511 iaxs[callno]->encmethods = cai.encmethods; 03512 03513 iaxs[callno]->adsi = cai.adsi; 03514 03515 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 03516 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 03517 03518 if (pds.key) 03519 ast_string_field_set(iaxs[callno], outkey, pds.key); 03520 if (pds.password) 03521 ast_string_field_set(iaxs[callno], secret, pds.password); 03522 03523 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 03524 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 03525 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 03526 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 03527 03528 if (iaxs[callno]->maxtime) { 03529 /* Initialize pingtime and auto-congest time */ 03530 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 03531 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 03532 } else if (autokill) { 03533 iaxs[callno]->pingtime = autokill / 2; 03534 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 03535 } 03536 03537 /* send the command using the appropriate socket for this peer */ 03538 iaxs[callno]->sockfd = cai.sockfd; 03539 03540 /* Transmit the string in a "NEW" request */ 03541 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 03542 03543 ast_mutex_unlock(&iaxsl[callno]); 03544 ast_setstate(c, AST_STATE_RINGING); 03545 03546 return 0; 03547 }
static int iax2_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 10864 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_CANEXIST, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10865 { 10866 int res = 0; 10867 struct iax2_dpcache *dp; 10868 #if 0 10869 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10870 #endif 10871 if ((priority != 1) && (priority != 2)) 10872 return 0; 10873 ast_mutex_lock(&dpcache_lock); 10874 dp = find_cache(chan, data, context, exten, priority); 10875 if (dp) { 10876 if (dp->flags & CACHE_FLAG_CANEXIST) 10877 res= 1; 10878 } 10879 ast_mutex_unlock(&dpcache_lock); 10880 if (!dp) { 10881 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10882 } 10883 return res; 10884 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 3305 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), and t.
Referenced by iax2_call(), and update_registry().
03306 { 03307 time_t t; 03308 struct tm tm; 03309 unsigned int tmp; 03310 time(&t); 03311 if (!ast_strlen_zero(tz)) 03312 ast_localtime(&t, &tm, tz); 03313 else 03314 ast_localtime(&t, &tm, NULL); 03315 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 03316 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 03317 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 03318 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 03319 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 03320 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 03321 return tmp; 03322 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 1342 of file chan_iax2.c.
References ao2_ref(), ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), AST_SCHED_DEL_SPINLOCK, DEADLOCK_AVOIDANCE, ast_channel::lock, LOG_DEBUG, option_debug, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), sched, chan_iax2_pvt::transfercallno, and update_max_trunk().
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().
01343 { 01344 struct chan_iax2_pvt *pvt; 01345 struct ast_channel *owner; 01346 01347 retry: 01348 pvt = iaxs[callno]; 01349 gettimeofday(&lastused[callno], NULL); 01350 01351 owner = pvt ? pvt->owner : NULL; 01352 01353 if (owner) { 01354 if (ast_mutex_trylock(&owner->lock)) { 01355 if (option_debug > 2) 01356 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n"); 01357 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01358 goto retry; 01359 } 01360 } 01361 01362 /* SPINLOCK gives up the pvt lock so the scheduler and iax2_pvt don't deadlock. Since we 01363 * give up the pvt lock, the pvt could be destroyed from underneath us. To guarantee 01364 * the pvt stays around, a ref count is added to it. */ 01365 if (!owner && pvt) { 01366 ao2_ref(pvt, +1); 01367 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01368 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01369 ao2_ref(pvt, -1); 01370 if (iaxs[callno]) { 01371 iaxs[callno] = NULL; 01372 } else { 01373 pvt = NULL; 01374 } 01375 } 01376 01377 if (pvt) { 01378 if (!owner) { 01379 pvt->owner = NULL; 01380 } else { 01381 /* If there's an owner, prod it to give up */ 01382 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 01383 * because we already hold the owner channel lock. */ 01384 ast_queue_hangup(owner); 01385 } 01386 01387 if (pvt->peercallno) { 01388 remove_by_peercallno(pvt); 01389 } 01390 01391 if (pvt->transfercallno) { 01392 remove_by_transfercallno(pvt); 01393 } 01394 01395 if (!owner) { 01396 ao2_ref(pvt, -1); 01397 pvt = NULL; 01398 } 01399 } 01400 01401 if (owner) { 01402 ast_mutex_unlock(&owner->lock); 01403 } 01404 01405 if (callno & 0x4000) { 01406 update_max_trunk(); 01407 } 01408 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1253 of file chan_iax2.c.
References ao2_find(), ast_atomic_fetchadd_int(), ast_clear_flag, AST_SCHED_DEL, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, iax2_user::curauthreq, IAX_MAXAUTHREQ, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::lagid, iax2_user::name, chan_iax2_pvt::pingid, sched, user_unref(), and chan_iax2_pvt::username.
Referenced by iax2_predestroy(), pvt_destructor(), and stop_stuff().
01254 { 01255 /* Decrement AUTHREQ count if needed */ 01256 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01257 struct iax2_user *user; 01258 struct iax2_user tmp_user = { 01259 .name = pvt->username, 01260 }; 01261 01262 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01263 if (user) { 01264 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01265 user = user_unref(user); 01266 } 01267 01268 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01269 } 01270 01271 /* No more pings or lagrq's */ 01272 AST_SCHED_DEL(sched, pvt->pingid); 01273 AST_SCHED_DEL(sched, pvt->lagid); 01274 AST_SCHED_DEL(sched, pvt->autoid); 01275 AST_SCHED_DEL(sched, pvt->authid); 01276 AST_SCHED_DEL(sched, pvt->initid); 01277 AST_SCHED_DEL(sched, pvt->jbid); 01278 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 11055 of file chan_iax2.c.
References iax2_peer::addr, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, option_debug, parse_dial_string(), and peer_unref().
11056 { 11057 struct parsed_dial_string pds; 11058 char *tmp = ast_strdupa(data); 11059 struct iax2_peer *p; 11060 int res = AST_DEVICE_INVALID; 11061 11062 memset(&pds, 0, sizeof(pds)); 11063 parse_dial_string(tmp, &pds); 11064 11065 if (ast_strlen_zero(pds.peer)) { 11066 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 11067 return res; 11068 } 11069 11070 if (option_debug > 2) 11071 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer); 11072 11073 /* SLD: FIXME: second call to find_peer during registration */ 11074 if (!(p = find_peer(pds.peer, 1))) 11075 return res; 11076 11077 res = AST_DEVICE_UNAVAILABLE; 11078 if (option_debug > 2) 11079 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 11080 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 11081 11082 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 11083 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 11084 /* Peer is registered, or have default IP address 11085 and a valid registration */ 11086 if (p->historicms == 0 || p->historicms <= p->maxms) 11087 /* let the core figure out whether it is in use or not */ 11088 res = AST_DEVICE_UNKNOWN; 11089 } 11090 11091 peer_unref(p); 11092 11093 return res; 11094 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 2921 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02922 { 02923 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 02924 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 2926 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02927 { 02928 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 02929 }
static int iax2_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5222 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05223 { 05224 if (argc < 2 || argc > 3) 05225 return RESULT_SHOWUSAGE; 05226 iaxdebug = 1; 05227 ast_cli(fd, "IAX2 Debugging Enabled\n"); 05228 return RESULT_SUCCESS; 05229 }
static int iax2_do_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5240 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05241 { 05242 if (argc < 3 || argc > 4) 05243 return RESULT_SHOWUSAGE; 05244 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 05245 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 05246 return RESULT_SUCCESS; 05247 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 9009 of file chan_iax2.c.
References iax2_registry::addr, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_add(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, option_debug, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
09010 { 09011 struct iax_ie_data ied; 09012 if (option_debug && iaxdebug) 09013 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username); 09014 09015 if (reg->dnsmgr && 09016 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 09017 /* Maybe the IP has changed, force DNS refresh */ 09018 ast_dnsmgr_refresh(reg->dnsmgr); 09019 } 09020 09021 /* 09022 * if IP has Changed, free allocated call to create a new one with new IP 09023 * call has the pointer to IP and must be updated to the new one 09024 */ 09025 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 09026 int callno = reg->callno; 09027 ast_mutex_lock(&iaxsl[callno]); 09028 iax2_destroy(callno); 09029 ast_mutex_unlock(&iaxsl[callno]); 09030 reg->callno = 0; 09031 } 09032 if (!reg->addr.sin_addr.s_addr) { 09033 if (option_debug && iaxdebug) 09034 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username); 09035 /* Setup the next registration attempt */ 09036 AST_SCHED_DEL(sched, reg->expire); 09037 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 09038 return -1; 09039 } 09040 09041 if (!reg->callno) { 09042 if (option_debug) 09043 ast_log(LOG_DEBUG, "Allocate call number\n"); 09044 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 09045 if (reg->callno < 1) { 09046 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 09047 return -1; 09048 } else if (option_debug) 09049 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno); 09050 iaxs[reg->callno]->reg = reg; 09051 ast_mutex_unlock(&iaxsl[reg->callno]); 09052 } 09053 /* Schedule the next registration attempt */ 09054 AST_SCHED_DEL(sched, reg->expire); 09055 /* Setup the next registration a little early */ 09056 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 09057 /* Send the request */ 09058 memset(&ied, 0, sizeof(ied)); 09059 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 09060 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 09061 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 09062 reg->regstate = REG_STATE_REGSENT; 09063 return 0; 09064 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 6059 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
06060 { 06061 #ifdef SCHED_MULTITHREADED 06062 if (schedule_action(__iax2_do_register_s, data)) 06063 #endif 06064 __iax2_do_register_s(data); 06065 return 0; 06066 }
static int iax2_do_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5231 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05232 { 05233 if (argc < 3 || argc > 4) 05234 return RESULT_SHOWUSAGE; 05235 iaxtrunkdebug = 1; 05236 ast_cli(fd, "IAX2 Trunk Debug Requested\n"); 05237 return RESULT_SUCCESS; 05238 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 6765 of file chan_iax2.c.
References AST_FRAME_IAX, AST_SCHED_DEL, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_add(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
06766 { 06767 struct iax_ie_data ied; 06768 /* Auto-hangup with 30 seconds of inactivity */ 06769 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 06770 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno); 06771 memset(&ied, 0, sizeof(ied)); 06772 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 06773 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 06774 dp->flags |= CACHE_FLAG_TRANSMITTED; 06775 }
static int iax2_exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Execute IAX2 dialplan switch.
Definition at line 10910 of file chan_iax2.c.
References ast_copy_string(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), CACHE_FLAG_EXISTS, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, option_verbose, pbx_builtin_getvar_helper(), pbx_exec(), pbx_findapp(), and VERBOSE_PREFIX_3.
10911 { 10912 char odata[256]; 10913 char req[256]; 10914 char *ncontext; 10915 struct iax2_dpcache *dp; 10916 struct ast_app *dial; 10917 #if 0 10918 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); 10919 #endif 10920 if (priority == 2) { 10921 /* Indicate status, can be overridden in dialplan */ 10922 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 10923 if (dialstatus) { 10924 dial = pbx_findapp(dialstatus); 10925 if (dial) 10926 pbx_exec(chan, dial, ""); 10927 } 10928 return -1; 10929 } else if (priority != 1) 10930 return -1; 10931 ast_mutex_lock(&dpcache_lock); 10932 dp = find_cache(chan, data, context, exten, priority); 10933 if (dp) { 10934 if (dp->flags & CACHE_FLAG_EXISTS) { 10935 ast_copy_string(odata, data, sizeof(odata)); 10936 ncontext = strchr(odata, '/'); 10937 if (ncontext) { 10938 *ncontext = '\0'; 10939 ncontext++; 10940 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 10941 } else { 10942 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 10943 } 10944 if (option_verbose > 2) 10945 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req); 10946 } else { 10947 ast_mutex_unlock(&dpcache_lock); 10948 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 10949 return -1; 10950 } 10951 } 10952 ast_mutex_unlock(&dpcache_lock); 10953 dial = pbx_findapp("Dial"); 10954 if (dial) { 10955 return pbx_exec(chan, dial, req); 10956 } else { 10957 ast_log(LOG_WARNING, "No dial application registered\n"); 10958 } 10959 return -1; 10960 }
static int iax2_exists | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 switch interface.
Definition at line 10841 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_EXISTS, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10842 { 10843 struct iax2_dpcache *dp; 10844 int res = 0; 10845 #if 0 10846 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10847 #endif 10848 if ((priority != 1) && (priority != 2)) 10849 return 0; 10850 ast_mutex_lock(&dpcache_lock); 10851 dp = find_cache(chan, data, context, exten, priority); 10852 if (dp) { 10853 if (dp->flags & CACHE_FLAG_EXISTS) 10854 res= 1; 10855 } 10856 ast_mutex_unlock(&dpcache_lock); 10857 if (!dp) { 10858 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10859 } 10860 return res; 10861 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 2948 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
02949 { 02950 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 02951 ast_mutex_lock(&iaxsl[callno]); 02952 if (iaxs[callno]) 02953 iaxs[callno]->owner = newchan; 02954 else 02955 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 02956 ast_mutex_unlock(&iaxsl[callno]); 02957 return 0; 02958 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1336 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), and schedule_delivery().
01337 { 01338 AST_SCHED_DEL(sched, fr->retrans); 01339 iax_frame_free(fr); 01340 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1223 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_copy_string(), iax2_peer::name, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01224 { 01225 struct iax2_peer *peer = NULL; 01226 int res = 0; 01227 struct ao2_iterator i; 01228 01229 i = ao2_iterator_init(peers, 0); 01230 while ((peer = ao2_iterator_next(&i))) { 01231 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01232 (peer->addr.sin_port == sin.sin_port)) { 01233 ast_copy_string(host, peer->name, len); 01234 peer_unref(peer); 01235 res = 1; 01236 break; 01237 } 01238 peer_unref(peer); 01239 } 01240 01241 if (!peer) { 01242 peer = realtime_peer(NULL, &sin); 01243 if (peer) { 01244 ast_copy_string(host, peer->name, len); 01245 peer_unref(peer); 01246 res = 1; 01247 } 01248 } 01249 01250 return res; 01251 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 3927 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_TRUNK, and peer_unref().
Referenced by check_access().
03928 { 03929 struct iax2_peer *peer; 03930 int res = 0; 03931 struct ao2_iterator i; 03932 03933 i = ao2_iterator_init(peers, 0); 03934 while ((peer = ao2_iterator_next(&i))) { 03935 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 03936 (peer->addr.sin_port == sin.sin_port)) { 03937 res = ast_test_flag(peer, IAX_TRUNK); 03938 peer_unref(peer); 03939 break; 03940 } 03941 peer_unref(peer); 03942 } 03943 03944 return res; 03945 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3549 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_verbose(), CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), iax2_sched_add(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_WARNING, ast_channel::name, option_debug, option_verbose, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03550 { 03551 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03552 struct iax_ie_data ied; 03553 int alreadygone; 03554 memset(&ied, 0, sizeof(ied)); 03555 ast_mutex_lock(&iaxsl[callno]); 03556 if (callno && iaxs[callno]) { 03557 if (option_debug) 03558 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name); 03559 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 03560 /* Send the hangup unless we have had a transmission error or are already gone */ 03561 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 03562 if (!iaxs[callno]->error && !alreadygone) { 03563 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 03564 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 03565 } 03566 if (!iaxs[callno]) { 03567 ast_mutex_unlock(&iaxsl[callno]); 03568 return 0; 03569 } 03570 } 03571 /* Explicitly predestroy it */ 03572 iax2_predestroy(callno); 03573 /* If we were already gone to begin with, destroy us now */ 03574 if (iaxs[callno] && alreadygone) { 03575 if (option_debug) 03576 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name); 03577 iax2_destroy(callno); 03578 } else if (iaxs[callno]) { 03579 iax2_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)); 03580 } 03581 } else if (c->tech_pvt) { 03582 /* If this call no longer exists, but the channel still 03583 * references it we need to set the channel's tech_pvt to null 03584 * to avoid ast_channel_free() trying to free it. 03585 */ 03586 c->tech_pvt = NULL; 03587 } 03588 ast_mutex_unlock(&iaxsl[callno]); 03589 if (option_verbose > 2) 03590 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name); 03591 return 0; 03592 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 3868 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_FRAME_CONTROL, ast_log(), ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, chan_iax2_pvt::mohinterpret, option_debug, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
03869 { 03870 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03871 struct chan_iax2_pvt *pvt; 03872 int res = 0; 03873 03874 if (option_debug && iaxdebug) 03875 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition); 03876 03877 ast_mutex_lock(&iaxsl[callno]); 03878 pvt = iaxs[callno]; 03879 03880 if (wait_for_peercallno(pvt)) { 03881 res = -1; 03882 goto done; 03883 } 03884 03885 switch (condition) { 03886 case AST_CONTROL_HOLD: 03887 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03888 ast_moh_start(c, data, pvt->mohinterpret); 03889 goto done; 03890 } 03891 break; 03892 case AST_CONTROL_UNHOLD: 03893 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 03894 ast_moh_stop(c); 03895 goto done; 03896 } 03897 } 03898 03899 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 03900 03901 done: 03902 ast_mutex_unlock(&iaxsl[callno]); 03903 03904 return res; 03905 }
static int iax2_matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 Switch interface.
Definition at line 10887 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), CACHE_FLAG_MATCHMORE, dpcache_lock, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
10888 { 10889 int res = 0; 10890 struct iax2_dpcache *dp; 10891 #if 0 10892 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 10893 #endif 10894 if ((priority != 1) && (priority != 2)) 10895 return 0; 10896 ast_mutex_lock(&dpcache_lock); 10897 dp = find_cache(chan, data, context, exten, priority); 10898 if (dp) { 10899 if (dp->flags & CACHE_FLAG_MATCHMORE) 10900 res= 1; 10901 } 10902 ast_mutex_unlock(&dpcache_lock); 10903 if (!dp) { 10904 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 10905 } 10906 return res; 10907 }
static int iax2_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5249 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05250 { 05251 if (argc < 3 || argc > 4) 05252 return RESULT_SHOWUSAGE; 05253 iaxdebug = 0; 05254 ast_cli(fd, "IAX2 Debugging Disabled\n"); 05255 return RESULT_SUCCESS; 05256 }
static int iax2_no_jb_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5267 of file chan_iax2.c.
References ast_cli(), jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05268 { 05269 if (argc < 4 || argc > 5) 05270 return RESULT_SHOWUSAGE; 05271 jb_setoutput(jb_error_output, jb_warning_output, NULL); 05272 jb_debug_output("\n"); 05273 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 05274 return RESULT_SUCCESS; 05275 }
static int iax2_no_trunk_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5258 of file chan_iax2.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05259 { 05260 if (argc < 4 || argc > 5) 05261 return RESULT_SHOWUSAGE; 05262 iaxtrunkdebug = 0; 05263 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n"); 05264 return RESULT_SUCCESS; 05265 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 9208 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
09209 { 09210 struct iax2_peer *peer = (struct iax2_peer *)data; 09211 peer->pokeexpire = -1; 09212 #ifdef SCHED_MULTITHREADED 09213 if (schedule_action(__iax2_poke_noanswer, data)) 09214 #endif 09215 __iax2_poke_noanswer(data); 09216 peer_unref(peer); 09217 return 0; 09218 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 9229 of file chan_iax2.c.
References iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, sched, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
09230 { 09231 int callno; 09232 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 09233 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 09234 immediately after clearing things out */ 09235 peer->lastms = 0; 09236 peer->historicms = 0; 09237 peer->pokeexpire = -1; 09238 peer->callno = 0; 09239 return 0; 09240 } 09241 09242 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 09243 if ((callno = peer->callno) > 0) { 09244 ast_log(LOG_NOTICE, "Still have a callno...\n"); 09245 ast_mutex_lock(&iaxsl[callno]); 09246 iax2_destroy(callno); 09247 ast_mutex_unlock(&iaxsl[callno]); 09248 } 09249 if (heldcall) 09250 ast_mutex_unlock(&iaxsl[heldcall]); 09251 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 09252 if (heldcall) 09253 ast_mutex_lock(&iaxsl[heldcall]); 09254 if (peer->callno < 1) { 09255 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 09256 return -1; 09257 } 09258 09259 /* Speed up retransmission times for this qualify call */ 09260 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 09261 iaxs[peer->callno]->peerpoke = peer; 09262 09263 /* Remove any pending pokeexpire task */ 09264 if (peer->pokeexpire > -1) { 09265 if (!ast_sched_del(sched, peer->pokeexpire)) { 09266 peer->pokeexpire = -1; 09267 peer_unref(peer); 09268 } 09269 } 09270 09271 /* Queue up a new task to handle no reply */ 09272 /* If the host is already unreachable then use the unreachable interval instead */ 09273 if (peer->lastms < 0) { 09274 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 09275 } else 09276 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 09277 09278 if (peer->pokeexpire == -1) 09279 peer_unref(peer); 09280 09281 /* And send the poke */ 09282 ast_mutex_lock(&iaxsl[callno]); 09283 if (iaxs[callno]) { 09284 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1); 09285 } 09286 ast_mutex_unlock(&iaxsl[callno]); 09287 09288 return 0; 09289 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 9220 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
09221 { 09222 struct iax2_peer *peer = obj; 09223 09224 iax2_poke_peer(peer, 0); 09225 09226 return 0; 09227 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 6805 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
06806 { 06807 struct iax2_peer *peer = (struct iax2_peer *)data; 06808 peer->pokeexpire = -1; 06809 #ifdef SCHED_MULTITHREADED 06810 if (schedule_action(__iax2_poke_peer_s, data)) 06811 #endif 06812 __iax2_poke_peer_s(data); 06813 return 0; 06814 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 2255 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag, ast_test_flag, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
02256 { 02257 struct ast_channel *c; 02258 struct chan_iax2_pvt *pvt = iaxs[callno]; 02259 02260 if (!pvt) 02261 return -1; 02262 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 02263 iax2_destroy_helper(pvt); 02264 ast_set_flag(pvt, IAX_ALREADYGONE); 02265 } 02266 c = pvt->owner; 02267 if (c) { 02268 c->tech_pvt = NULL; 02269 iax2_queue_hangup(callno); 02270 pvt->owner = NULL; 02271 ast_module_unref(ast_module_info->self); 02272 } 02273 return 0; 02274 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 8884 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), t, and thread.
Referenced by find_idle_thread(), and start_network_thread().
08885 { 08886 struct iax2_thread *thread = data; 08887 struct timeval tv; 08888 struct timespec ts; 08889 int put_into_idle = 0; 08890 08891 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 08892 pthread_cleanup_push(iax2_process_thread_cleanup, data); 08893 for(;;) { 08894 /* Wait for something to signal us to be awake */ 08895 ast_mutex_lock(&thread->lock); 08896 08897 /* Flag that we're ready to accept signals */ 08898 thread->ready_for_signal = 1; 08899 08900 /* Put into idle list if applicable */ 08901 if (put_into_idle) 08902 insert_idle_thread(thread); 08903 08904 if (thread->type == IAX_TYPE_DYNAMIC) { 08905 struct iax2_thread *t = NULL; 08906 /* Wait to be signalled or time out */ 08907 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08908 ts.tv_sec = tv.tv_sec; 08909 ts.tv_nsec = tv.tv_usec * 1000; 08910 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 08911 /* This thread was never put back into the available dynamic 08912 * thread list, so just go away. */ 08913 if (!put_into_idle) { 08914 ast_mutex_unlock(&thread->lock); 08915 break; 08916 } 08917 AST_LIST_LOCK(&dynamic_list); 08918 /* Account for the case where this thread is acquired *right* after a timeout */ 08919 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 08920 iaxdynamicthreadcount--; 08921 AST_LIST_UNLOCK(&dynamic_list); 08922 if (t) { 08923 /* This dynamic thread timed out waiting for a task and was 08924 * not acquired immediately after the timeout, 08925 * so it's time to go away. */ 08926 ast_mutex_unlock(&thread->lock); 08927 break; 08928 } 08929 /* Someone grabbed our thread *right* after we timed out. 08930 * Wait for them to set us up with something to do and signal 08931 * us to continue. */ 08932 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 08933 ts.tv_sec = tv.tv_sec; 08934 ts.tv_nsec = tv.tv_usec * 1000; 08935 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 08936 { 08937 ast_mutex_unlock(&thread->lock); 08938 break; 08939 } 08940 } 08941 } else { 08942 ast_cond_wait(&thread->cond, &thread->lock); 08943 } 08944 08945 /* Go back into our respective list */ 08946 put_into_idle = 1; 08947 08948 ast_mutex_unlock(&thread->lock); 08949 08950 if (thread->iostate == IAX_IOSTATE_IDLE) 08951 continue; 08952 08953 /* Add ourselves to the active list now */ 08954 AST_LIST_LOCK(&active_list); 08955 AST_LIST_INSERT_HEAD(&active_list, thread, list); 08956 AST_LIST_UNLOCK(&active_list); 08957 08958 /* See what we need to do */ 08959 switch(thread->iostate) { 08960 case IAX_IOSTATE_READY: 08961 thread->actions++; 08962 thread->iostate = IAX_IOSTATE_PROCESSING; 08963 socket_process(thread); 08964 handle_deferred_full_frames(thread); 08965 break; 08966 case IAX_IOSTATE_SCHEDREADY: 08967 thread->actions++; 08968 thread->iostate = IAX_IOSTATE_PROCESSING; 08969 #ifdef SCHED_MULTITHREADED 08970 thread->schedfunc(thread->scheddata); 08971 #endif 08972 break; 08973 } 08974 time(&thread->checktime); 08975 thread->iostate = IAX_IOSTATE_IDLE; 08976 #ifdef DEBUG_SCHED_MULTITHREAD 08977 thread->curfunc[0]='\0'; 08978 #endif 08979 08980 /* Now... remove ourselves from the active list, and return to the idle list */ 08981 AST_LIST_LOCK(&active_list); 08982 AST_LIST_REMOVE(&active_list, thread, list); 08983 AST_LIST_UNLOCK(&active_list); 08984 08985 /* Make sure another frame didn't sneak in there after we thought we were done. */ 08986 handle_deferred_full_frames(thread); 08987 } 08988 08989 /*!\note For some reason, idle threads are exiting without being removed 08990 * from an idle list, which is causing memory corruption. Forcibly remove 08991 * it from the list, if it's there. 08992 */ 08993 AST_LIST_LOCK(&idle_list); 08994 AST_LIST_REMOVE(&idle_list, thread, list); 08995 AST_LIST_UNLOCK(&idle_list); 08996 08997 AST_LIST_LOCK(&dynamic_list); 08998 AST_LIST_REMOVE(&dynamic_list, thread, list); 08999 AST_LIST_UNLOCK(&dynamic_list); 09000 09001 /* I am exiting here on my own volition, I need to clean up my own data structures 09002 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 09003 */ 09004 pthread_cleanup_pop(1); 09005 09006 return NULL; 09007 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 8875 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy(), ast_mutex_destroy(), free, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
08876 { 08877 struct iax2_thread *thread = data; 08878 ast_mutex_destroy(&thread->lock); 08879 ast_cond_destroy(&thread->cond); 08880 free(thread); 08881 ast_atomic_dec_and_test(&iaxactivethreadcount); 08882 }
static int iax2_prov_cmd | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 9163 of file chan_iax2.c.
References ast_cli(), iax2_provision(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
09164 { 09165 int force = 0; 09166 int res; 09167 if (argc < 4) 09168 return RESULT_SHOWUSAGE; 09169 if ((argc > 4)) { 09170 if (!strcasecmp(argv[4], "forced")) 09171 force = 1; 09172 else 09173 return RESULT_SHOWUSAGE; 09174 } 09175 res = iax2_provision(NULL, -1, argv[2], argv[3], force); 09176 if (res < 0) 09177 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]); 09178 else if (res < 1) 09179 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]); 09180 else 09181 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : ""); 09182 return RESULT_SUCCESS; 09183 }
static char* iax2_prov_complete_template_3rd | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 9066 of file chan_iax2.c.
References iax_prov_complete_template().
09067 { 09068 if (pos != 3) 09069 return NULL; 09070 return iax_prov_complete_template(line, word, pos, state); 09071 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 9073 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), ast_mutex_unlock(), AST_SCHED_DEL, ast_set_flag, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_add(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, option_debug, iax_ie_data::pos, sched, and send_command().
Referenced by check_provisioning(), iax2_prov_app(), and iax2_prov_cmd().
09074 { 09075 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 09076 is found for template */ 09077 struct iax_ie_data provdata; 09078 struct iax_ie_data ied; 09079 unsigned int sig; 09080 struct sockaddr_in sin; 09081 int callno; 09082 struct create_addr_info cai; 09083 09084 memset(&cai, 0, sizeof(cai)); 09085 09086 if (option_debug) 09087 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template); 09088 09089 if (iax_provision_build(&provdata, &sig, template, force)) { 09090 if (option_debug) 09091 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template); 09092 return 0; 09093 } 09094 09095 if (end) { 09096 memcpy(&sin, end, sizeof(sin)); 09097 cai.sockfd = sockfd; 09098 } else if (create_addr(dest, NULL, &sin, &cai)) 09099 return -1; 09100 09101 /* Build the rest of the message */ 09102 memset(&ied, 0, sizeof(ied)); 09103 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 09104 09105 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09106 if (!callno) 09107 return -1; 09108 09109 if (iaxs[callno]) { 09110 /* Schedule autodestruct in case they don't ever give us anything back */ 09111 AST_SCHED_DEL(sched, iaxs[callno]->autoid); 09112 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno); 09113 ast_set_flag(iaxs[callno], IAX_PROVISION); 09114 /* Got a call number now, so go ahead and send the provisioning information */ 09115 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 09116 } 09117 ast_mutex_unlock(&iaxsl[callno]); 09118 09119 return 1; 09120 }
static int iax2_prune_realtime | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2393 of file chan_iax2.c.
References ao2_unlink(), ast_cli(), ast_set_flag, ast_test_flag, expire_registry(), find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, peer_ref(), peer_unref(), prune_peers(), prune_users(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and user_unref().
02394 { 02395 struct iax2_peer *peer = NULL; 02396 struct iax2_user *user = NULL; 02397 02398 if (argc != 4) 02399 return RESULT_SHOWUSAGE; 02400 if (!strcmp(argv[3],"all")) { 02401 prune_users(); 02402 prune_peers(); 02403 ast_cli(fd, "OK cache is flushed.\n"); 02404 return RESULT_SUCCESS; 02405 } 02406 peer = find_peer(argv[3], 0); 02407 user = find_user(argv[3]); 02408 if (peer || user) { 02409 if (peer) { 02410 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 02411 ast_set_flag(peer, IAX_RTAUTOCLEAR); 02412 expire_registry(peer_ref(peer)); 02413 ast_cli(fd, "Peer %s was removed from the cache.\n", argv[3]); 02414 } else { 02415 ast_cli(fd, "Peer %s is not eligible for this operation.\n", argv[3]); 02416 } 02417 peer_unref(peer); 02418 } 02419 if (user) { 02420 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 02421 ast_set_flag(user, IAX_RTAUTOCLEAR); 02422 ast_cli(fd, "User %s was removed from the cache.\n", argv[3]); 02423 } else { 02424 ast_cli(fd, "User %s is not eligible for this operation.\n", argv[3]); 02425 } 02426 ao2_unlink(users,user); 02427 user_unref(user); 02428 } 02429 } else { 02430 ast_cli(fd, "%s was not found in the cache.\n", argv[3]); 02431 } 02432 02433 return RESULT_SUCCESS; 02434 }
static int iax2_queue_control_data | ( | int | callno, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 1865 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_control_data(), DEADLOCK_AVOIDANCE, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by socket_process().
01867 { 01868 for (;;) { 01869 if (iaxs[callno] && iaxs[callno]->owner) { 01870 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01871 /* Avoid deadlock by pausing and trying again */ 01872 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01873 } else { 01874 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 01875 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01876 break; 01877 } 01878 } else 01879 break; 01880 } 01881 return 0; 01882 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 1803 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_frame(), DEADLOCK_AVOIDANCE, f, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
01804 { 01805 for (;;) { 01806 if (iaxs[callno] && iaxs[callno]->owner) { 01807 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01808 /* Avoid deadlock by pausing and trying again */ 01809 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01810 } else { 01811 ast_queue_frame(iaxs[callno]->owner, f); 01812 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01813 break; 01814 } 01815 } else 01816 break; 01817 } 01818 return 0; 01819 }
static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 1834 of file chan_iax2.c.
References ast_mutex_trylock(), ast_mutex_unlock(), ast_queue_hangup(), DEADLOCK_AVOIDANCE, ast_channel::lock, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
01835 { 01836 for (;;) { 01837 if (iaxs[callno] && iaxs[callno]->owner) { 01838 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) { 01839 /* Avoid deadlock by pausing and trying again */ 01840 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01841 } else { 01842 ast_queue_hangup(iaxs[callno]->owner); 01843 ast_mutex_unlock(&iaxs[callno]->owner->lock); 01844 break; 01845 } 01846 } else 01847 break; 01848 } 01849 return 0; 01850 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 3658 of file chan_iax2.c.
References ast_log(), and LOG_NOTICE.
03659 { 03660 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n"); 03661 return NULL; 03662 }
static int iax2_register | ( | char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 6278 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), copy(), iax2_registry::entry, free, hostname, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, and secret.
Referenced by set_config().
06279 { 06280 struct iax2_registry *reg; 06281 char copy[256]; 06282 char *username, *hostname, *secret; 06283 char *porta; 06284 char *stringp=NULL; 06285 06286 if (!value) 06287 return -1; 06288 ast_copy_string(copy, value, sizeof(copy)); 06289 stringp=copy; 06290 username = strsep(&stringp, "@"); 06291 hostname = strsep(&stringp, "@"); 06292 if (!hostname) { 06293 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 06294 return -1; 06295 } 06296 stringp=username; 06297 username = strsep(&stringp, ":"); 06298 secret = strsep(&stringp, ":"); 06299 stringp=hostname; 06300 hostname = strsep(&stringp, ":"); 06301 porta = strsep(&stringp, ":"); 06302 06303 if (porta && !atoi(porta)) { 06304 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 06305 return -1; 06306 } 06307 if (!(reg = ast_calloc(1, sizeof(*reg)))) 06308 return -1; 06309 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) { 06310 free(reg); 06311 return -1; 06312 } 06313 ast_copy_string(reg->username, username, sizeof(reg->username)); 06314 if (secret) 06315 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 06316 reg->expire = -1; 06317 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 06318 reg->addr.sin_family = AF_INET; 06319 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 06320 AST_LIST_LOCK(®istrations); 06321 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 06322 AST_LIST_UNLOCK(®istrations); 06323 06324 return 0; 06325 }
static int iax2_reload | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 10606 of file chan_iax2.c.
References reload_config().
10607 { 10608 return reload_config(); 10609 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
int | format, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 9301 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock(), AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_translator_best_choice(), create_addr(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.
09302 { 09303 int callno; 09304 int res; 09305 int fmt, native; 09306 struct sockaddr_in sin; 09307 struct ast_channel *c; 09308 struct parsed_dial_string pds; 09309 struct create_addr_info cai; 09310 char *tmpstr; 09311 09312 memset(&pds, 0, sizeof(pds)); 09313 tmpstr = ast_strdupa(data); 09314 parse_dial_string(tmpstr, &pds); 09315 09316 if (ast_strlen_zero(pds.peer)) { 09317 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 09318 return NULL; 09319 } 09320 09321 memset(&cai, 0, sizeof(cai)); 09322 cai.capability = iax2_capability; 09323 09324 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09325 09326 /* Populate our address from the given */ 09327 if (create_addr(pds.peer, NULL, &sin, &cai)) { 09328 *cause = AST_CAUSE_UNREGISTERED; 09329 return NULL; 09330 } 09331 09332 if (pds.port) 09333 sin.sin_port = htons(atoi(pds.port)); 09334 09335 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 09336 if (callno < 1) { 09337 ast_log(LOG_WARNING, "Unable to create call\n"); 09338 *cause = AST_CAUSE_CONGESTION; 09339 return NULL; 09340 } 09341 09342 /* If this is a trunk, update it now */ 09343 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 09344 if (ast_test_flag(&cai, IAX_TRUNK)) { 09345 int new_callno; 09346 if ((new_callno = make_trunk(callno, 1)) != -1) 09347 callno = new_callno; 09348 } 09349 iaxs[callno]->maxtime = cai.maxtime; 09350 if (cai.found) 09351 ast_string_field_set(iaxs[callno], host, pds.peer); 09352 09353 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 09354 09355 ast_mutex_unlock(&iaxsl[callno]); 09356 09357 if (c) { 09358 /* Choose a format we can live with */ 09359 if (c->nativeformats & format) 09360 c->nativeformats &= format; 09361 else { 09362 native = c->nativeformats; 09363 fmt = format; 09364 res = ast_translator_best_choice(&fmt, &native); 09365 if (res < 0) { 09366 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 09367 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 09368 ast_hangup(c); 09369 return NULL; 09370 } 09371 c->nativeformats = native; 09372 } 09373 c->readformat = ast_best_codec(c->nativeformats); 09374 c->writeformat = c->readformat; 09375 } 09376 09377 return c; 09378 }
static int iax2_sched_add | ( | struct sched_context * | con, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1006 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), and sched_lock.
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), auth_fail(), iax2_ack_registry(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_hangup(), iax2_poke_peer(), iax2_provision(), make_trunk(), network_thread(), reg_source_db(), socket_process(), update_jbsched(), and update_registry().
01007 { 01008 int res; 01009 01010 ast_mutex_lock(&sched_lock); 01011 res = ast_sched_add(con, when, callback, data); 01012 ast_cond_signal(&sched_cond); 01013 ast_mutex_unlock(&sched_lock); 01014 01015 return res; 01016 }
static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f, | |||
unsigned int | ts, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 4524 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), f, iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_transmit(), iax2_trunk_queue(), IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_showframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, chan_iax2_pvt::lastvsent, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), and socket_process().
04525 { 04526 /* Queue a packet for delivery on a given private structure. Use "ts" for 04527 timestamp, or calculate if ts is 0. Send immediately without retransmission 04528 or delayed, with retransmission */ 04529 struct ast_iax2_full_hdr *fh; 04530 struct ast_iax2_mini_hdr *mh; 04531 struct ast_iax2_video_hdr *vh; 04532 struct { 04533 struct iax_frame fr2; 04534 unsigned char buffer[4096]; 04535 } frb; 04536 struct iax_frame *fr; 04537 int res; 04538 int sendmini=0; 04539 unsigned int lastsent; 04540 unsigned int fts; 04541 04542 frb.fr2.afdatalen = sizeof(frb.buffer); 04543 04544 if (!pvt) { 04545 ast_log(LOG_WARNING, "No private structure for packet?\n"); 04546 return -1; 04547 } 04548 04549 lastsent = pvt->lastsent; 04550 04551 /* Calculate actual timestamp */ 04552 fts = calc_timestamp(pvt, ts, f); 04553 04554 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 04555 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 04556 * increment the "predicted timestamps" for voice, if we're predecting */ 04557 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 04558 return 0; 04559 04560 04561 if ((ast_test_flag(pvt, IAX_TRUNK) || 04562 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 04563 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 04564 /* High two bytes are the same on timestamp, or sending on a trunk */ && 04565 (f->frametype == AST_FRAME_VOICE) 04566 /* is a voice frame */ && 04567 (f->subclass == pvt->svoiceformat) 04568 /* is the same type */ ) { 04569 /* Force immediate rather than delayed transmission */ 04570 now = 1; 04571 /* Mark that mini-style frame is appropriate */ 04572 sendmini = 1; 04573 } 04574 if ( f->frametype == AST_FRAME_VIDEO ) { 04575 /* 04576 * If the lower 15 bits of the timestamp roll over, or if 04577 * the video format changed then send a full frame. 04578 * Otherwise send a mini video frame 04579 */ 04580 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 04581 ((f->subclass & ~0x1) == pvt->svideoformat) 04582 ) { 04583 now = 1; 04584 sendmini = 1; 04585 } else { 04586 now = 0; 04587 sendmini = 0; 04588 } 04589 pvt->lastvsent = fts; 04590 } 04591 if (f->frametype == AST_FRAME_IAX) { 04592 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 04593 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 04594 if (!pvt->first_iax_message) { 04595 pvt->first_iax_message = pvt->last_iax_message; 04596 } 04597 } 04598 /* Allocate an iax_frame */ 04599 if (now) { 04600 fr = &frb.fr2; 04601 } else 04602 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO)); 04603 if (!fr) { 04604 ast_log(LOG_WARNING, "Out of memory\n"); 04605 return -1; 04606 } 04607 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 04608 iax_frame_wrap(fr, f); 04609 04610 fr->ts = fts; 04611 fr->callno = pvt->callno; 04612 fr->transfer = transfer; 04613 fr->final = final; 04614 fr->encmethods = 0; 04615 if (!sendmini) { 04616 /* We need a full frame */ 04617 if (seqno > -1) 04618 fr->oseqno = seqno; 04619 else 04620 fr->oseqno = pvt->oseqno++; 04621 fr->iseqno = pvt->iseqno; 04622 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr)); 04623 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 04624 fh->ts = htonl(fr->ts); 04625 fh->oseqno = fr->oseqno; 04626 if (transfer) { 04627 fh->iseqno = 0; 04628 } else 04629 fh->iseqno = fr->iseqno; 04630 /* Keep track of the last thing we've acknowledged */ 04631 if (!transfer) 04632 pvt->aseqno = fr->iseqno; 04633 fh->type = fr->af.frametype & 0xFF; 04634 if (fr->af.frametype == AST_FRAME_VIDEO) 04635 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 04636 else 04637 fh->csub = compress_subclass(fr->af.subclass); 04638 if (transfer) { 04639 fr->dcallno = pvt->transfercallno; 04640 } else 04641 fr->dcallno = pvt->peercallno; 04642 fh->dcallno = htons(fr->dcallno); 04643 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 04644 fr->data = fh; 04645 fr->retries = 0; 04646 /* Retry after 2x the ping time has passed */ 04647 fr->retrytime = pvt->pingtime * 2; 04648 if (fr->retrytime < MIN_RETRY_TIME) 04649 fr->retrytime = MIN_RETRY_TIME; 04650 if (fr->retrytime > MAX_RETRY_TIME) 04651 fr->retrytime = MAX_RETRY_TIME; 04652 /* Acks' don't get retried */ 04653 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 04654 fr->retries = -1; 04655 else if (f->frametype == AST_FRAME_VOICE) 04656 pvt->svoiceformat = f->subclass; 04657 else if (f->frametype == AST_FRAME_VIDEO) 04658 pvt->svideoformat = f->subclass & ~0x1; 04659 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04660 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04661 if (iaxdebug) { 04662 if (fr->transfer) 04663 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04664 else 04665 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 04666 } 04667 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 04668 fr->encmethods = pvt->encmethods; 04669 fr->ecx = pvt->ecx; 04670 fr->mydcx = pvt->mydcx; 04671 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 04672 } else 04673 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04674 } 04675 04676 if (now) { 04677 res = send_packet(fr); 04678 } else 04679 res = iax2_transmit(fr); 04680 } else { 04681 if (ast_test_flag(pvt, IAX_TRUNK)) { 04682 iax2_trunk_queue(pvt, fr); 04683 res = 0; 04684 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 04685 /* Video frame have no sequence number */ 04686 fr->oseqno = -1; 04687 fr->iseqno = -1; 04688 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr)); 04689 vh->zeros = 0; 04690 vh->callno = htons(0x8000 | fr->callno); 04691 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 04692 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 04693 fr->data = vh; 04694 fr->retries = -1; 04695 res = send_packet(fr); 04696 } else { 04697 /* Mini-frames have no sequence number */ 04698 fr->oseqno = -1; 04699 fr->iseqno = -1; 04700 /* Mini frame will do */ 04701 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr)); 04702 mh->callno = htons(fr->callno); 04703 mh->ts = htons(fr->ts & 0xFFFF); 04704 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 04705 fr->data = mh; 04706 fr->retries = -1; 04707 if (pvt->transferring == TRANSFER_MEDIAPASS) 04708 fr->transfer = 1; 04709 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 04710 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 04711 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 04712 } else 04713 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 04714 } 04715 res = send_packet(fr); 04716 } 04717 } 04718 return res; 04719 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 2943 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02944 { 02945 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 02946 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 2938 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.
02939 { 02940 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1); 02941 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 2931 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
02932 { 02933 02934 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 02935 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 02936 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 3616 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, errno, free, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
03617 { 03618 struct ast_option_header *h; 03619 int res; 03620 03621 switch (option) { 03622 case AST_OPTION_TXGAIN: 03623 case AST_OPTION_RXGAIN: 03624 /* these two cannot be sent, because they require a result */ 03625 errno = ENOSYS; 03626 return -1; 03627 default: 03628 { 03629 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03630 struct chan_iax2_pvt *pvt; 03631 03632 ast_mutex_lock(&iaxsl[callno]); 03633 pvt = iaxs[callno]; 03634 03635 if (wait_for_peercallno(pvt)) { 03636 ast_mutex_unlock(&iaxsl[callno]); 03637 return -1; 03638 } 03639 03640 ast_mutex_unlock(&iaxsl[callno]); 03641 03642 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 03643 return -1; 03644 } 03645 03646 h->flag = AST_OPTION_FLAG_REQUEST; 03647 h->option = htons(option); 03648 memcpy(h->data, data, datalen); 03649 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 03650 AST_CONTROL_OPTION, 0, (unsigned char *) h, 03651 datalen + sizeof(*h), -1); 03652 free(h); 03653 return res; 03654 } 03655 } 03656 }
static int iax2_show_cache | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2616 of file chan_iax2.c.
References ast_cli(), ast_copy_string(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, dpcache, dpcache_lock, iax2_dpcache::expiry, iax2_dpcache::exten, iax2_dpcache::flags, iax2_dpcache::next, iax2_dpcache::peercontext, RESULT_SUCCESS, s, and iax2_dpcache::waiters.
02617 { 02618 struct iax2_dpcache *dp; 02619 char tmp[1024], *pc; 02620 int s; 02621 int x,y; 02622 struct timeval tv; 02623 gettimeofday(&tv, NULL); 02624 ast_mutex_lock(&dpcache_lock); 02625 dp = dpcache; 02626 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 02627 while(dp) { 02628 s = dp->expiry.tv_sec - tv.tv_sec; 02629 tmp[0] = '\0'; 02630 if (dp->flags & CACHE_FLAG_EXISTS) 02631 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 02632 if (dp->flags & CACHE_FLAG_NONEXISTENT) 02633 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 02634 if (dp->flags & CACHE_FLAG_CANEXIST) 02635 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 02636 if (dp->flags & CACHE_FLAG_PENDING) 02637 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 02638 if (dp->flags & CACHE_FLAG_TIMEOUT) 02639 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 02640 if (dp->flags & CACHE_FLAG_TRANSMITTED) 02641 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 02642 if (dp->flags & CACHE_FLAG_MATCHMORE) 02643 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 02644 if (dp->flags & CACHE_FLAG_UNKNOWN) 02645 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 02646 /* Trim trailing pipe */ 02647 if (!ast_strlen_zero(tmp)) 02648 tmp[strlen(tmp) - 1] = '\0'; 02649 else 02650 ast_copy_string(tmp, "(none)", sizeof(tmp)); 02651 y=0; 02652 pc = strchr(dp->peercontext, '@'); 02653 if (!pc) 02654 pc = dp->peercontext; 02655 else 02656 pc++; 02657 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) 02658 if (dp->waiters[x] > -1) 02659 y++; 02660 if (s > 0) 02661 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 02662 else 02663 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 02664 dp = dp->next; 02665 } 02666 ast_mutex_unlock(&dpcache_lock); 02667 return RESULT_SUCCESS; 02668 }
static int iax2_show_channels | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5063 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, jb_info::current, iax_rr::delay, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::remote_rr, RESULT_SHOWUSAGE, RESULT_SUCCESS, and S_OR.
05064 { 05065 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 05066 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" 05067 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 05068 int x; 05069 int numchans = 0; 05070 int usedchans = 0; 05071 char first_message[10] = { 0, }; 05072 char last_message[10] = { 0, }; 05073 05074 if (argc != 3) 05075 return RESULT_SHOWUSAGE; 05076 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 05077 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 05078 ast_mutex_lock(&iaxsl[x]); 05079 if (iaxs[x]) { 05080 int lag, jitter, localdelay; 05081 jb_info jbinfo; 05082 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 05083 jb_getinfo(iaxs[x]->jb, &jbinfo); 05084 jitter = jbinfo.jitter; 05085 localdelay = jbinfo.current - jbinfo.min; 05086 } else { 05087 jitter = -1; 05088 localdelay = 0; 05089 } 05090 05091 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 05092 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 05093 lag = iaxs[x]->remote_rr.delay; 05094 ast_cli(fd, FORMAT, 05095 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 05096 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 05097 S_OR(iaxs[x]->username, "(None)"), 05098 iaxs[x]->callno, iaxs[x]->peercallno, 05099 iaxs[x]->oseqno, iaxs[x]->iseqno, 05100 lag, 05101 jitter, 05102 localdelay, 05103 ast_getformatname(iaxs[x]->voiceformat), 05104 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 05105 first_message, 05106 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 05107 last_message); 05108 numchans++; 05109 if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */ 05110 usedchans++; 05111 } 05112 } 05113 ast_mutex_unlock(&iaxsl[x]); 05114 } 05115 ast_cli(fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 05116 ast_cli(fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 05117 return RESULT_SUCCESS; 05118 #undef FORMAT 05119 #undef FORMAT2 05120 #undef FORMATB 05121 }
static int iax2_show_firmware | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4974 of file chan_iax2.c.
References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, FORMAT, FORMAT2, iax_firmware::fwh, ast_firmware_list::lock, iax_firmware::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
04975 { 04976 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n" 04977 #if !defined(__FreeBSD__) 04978 #define FORMAT "%-15.15s %-15d %-15d\n" 04979 #else /* __FreeBSD__ */ 04980 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */ 04981 #endif /* __FreeBSD__ */ 04982 struct iax_firmware *cur; 04983 if ((argc != 3) && (argc != 4)) 04984 return RESULT_SHOWUSAGE; 04985 ast_mutex_lock(&waresl.lock); 04986 04987 ast_cli(fd, FORMAT2, "Device", "Version", "Size"); 04988 for (cur = waresl.wares;cur;cur = cur->next) { 04989 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 04990 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version), 04991 (int)ntohl(cur->fwh->datalen)); 04992 } 04993 ast_mutex_unlock(&waresl.lock); 04994 return RESULT_SUCCESS; 04995 #undef FORMAT 04996 #undef FORMAT2 04997 }
static int iax2_show_netstats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5210 of file chan_iax2.c.
References ast_cli(), ast_cli_netstats(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
05211 { 05212 int numchans = 0; 05213 if (argc != 3) 05214 return RESULT_SHOWUSAGE; 05215 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 05216 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 05217 numchans = ast_cli_netstats(NULL, fd, 1); 05218 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 05219 return RESULT_SUCCESS; 05220 }
static int iax2_show_peer | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Show one peer in detail.
Definition at line 2505 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, iax2_peer::expire, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mailbox, iax2_peer::name, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax2_peer::prefs, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_peer::secret, iax2_peer::smoothing, and iax2_peer::username.
02506 { 02507 char status[30]; 02508 char cbuf[256]; 02509 struct iax2_peer *peer; 02510 char codec_buf[512]; 02511 int x = 0, codec = 0, load_realtime = 0; 02512 02513 if (argc < 4) 02514 return RESULT_SHOWUSAGE; 02515 02516 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0; 02517 02518 peer = find_peer(argv[3], load_realtime); 02519 if (peer) { 02520 ast_cli(fd,"\n\n"); 02521 ast_cli(fd, " * Name : %s\n", peer->name); 02522 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>"); 02523 ast_cli(fd, " Context : %s\n", peer->context); 02524 ast_cli(fd, " Mailbox : %s\n", peer->mailbox); 02525 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No"); 02526 ast_cli(fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 02527 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 02528 ast_cli(fd, " Expire : %d\n", peer->expire); 02529 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No")); 02530 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port)); 02531 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 02532 ast_cli(fd, " Username : %s\n", peer->username); 02533 ast_cli(fd, " Codecs : "); 02534 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 02535 ast_cli(fd, "%s\n", codec_buf); 02536 02537 ast_cli(fd, " Codec Order : ("); 02538 for(x = 0; x < 32 ; x++) { 02539 codec = ast_codec_pref_index(&peer->prefs,x); 02540 if(!codec) 02541 break; 02542 ast_cli(fd, "%s", ast_getformatname(codec)); 02543 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 02544 ast_cli(fd, "|"); 02545 } 02546 02547 if (!x) 02548 ast_cli(fd, "none"); 02549 ast_cli(fd, ")\n"); 02550 02551 ast_cli(fd, " Status : "); 02552 peer_status(peer, status, sizeof(status)); 02553 ast_cli(fd, "%s\n",status); 02554 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 02555 ast_cli(fd,"\n"); 02556 peer_unref(peer); 02557 } else { 02558 ast_cli(fd,"Peer %s not found.\n", argv[3]); 02559 ast_cli(fd,"\n"); 02560 } 02561 02562 return RESULT_SUCCESS; 02563 }
static int iax2_show_peers | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4963 of file chan_iax2.c.
References __iax2_show_peers().
04964 { 04965 return __iax2_show_peers(0, fd, NULL, argc, argv); 04966 }
static int iax2_show_registry | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 5035 of file chan_iax2.c.
References iax2_registry::addr, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::dnsmgr, iax2_registry::entry, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_registry::us, and iax2_registry::username.
05036 { 05037 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 05038 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 05039 struct iax2_registry *reg = NULL; 05040 05041 char host[80]; 05042 char perceived[80]; 05043 if (argc != 3) 05044 return RESULT_SHOWUSAGE; 05045 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 05046 AST_LIST_LOCK(®istrations); 05047 AST_LIST_TRAVERSE(®istrations, reg, entry) { 05048 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 05049 if (reg->us.sin_addr.s_addr) 05050 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 05051 else 05052 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 05053 ast_cli(fd, FORMAT, host, 05054 (reg->dnsmgr) ? "Y" : "N", 05055 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 05056 } 05057 AST_LIST_UNLOCK(®istrations); 05058 return RESULT_SUCCESS; 05059 #undef FORMAT 05060 #undef FORMAT2 05061 }
static int iax2_show_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2590 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxq, iax_frame::list, ast_iax2_queue::queue, RESULT_SHOWUSAGE, RESULT_SUCCESS, and iax_frame::retries.
02591 { 02592 struct iax_frame *cur; 02593 int cnt = 0, dead=0, final=0; 02594 02595 if (argc != 3) 02596 return RESULT_SHOWUSAGE; 02597 02598 AST_LIST_LOCK(&iaxq.queue); 02599 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 02600 if (cur->retries < 0) 02601 dead++; 02602 if (cur->final) 02603 final++; 02604 cnt++; 02605 } 02606 AST_LIST_UNLOCK(&iaxq.queue); 02607 02608 ast_cli(fd, " IAX Statistics\n"); 02609 ast_cli(fd, "---------------------\n"); 02610 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 02611 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 02612 02613 return RESULT_SUCCESS; 02614 }
static int iax2_show_threads | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4904 of file chan_iax2.c.
References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::list, RESULT_SHOWUSAGE, RESULT_SUCCESS, t, and thread.
04905 { 04906 struct iax2_thread *thread = NULL; 04907 time_t t; 04908 int threadcount = 0, dynamiccount = 0; 04909 char type; 04910 04911 if (argc != 3) 04912 return RESULT_SHOWUSAGE; 04913 04914 ast_cli(fd, "IAX2 Thread Information\n"); 04915 time(&t); 04916 ast_cli(fd, "Idle Threads:\n"); 04917 AST_LIST_LOCK(&idle_list); 04918 AST_LIST_TRAVERSE(&idle_list, thread, list) { 04919 #ifdef DEBUG_SCHED_MULTITHREAD 04920 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04921 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04922 #else 04923 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04924 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04925 #endif 04926 threadcount++; 04927 } 04928 AST_LIST_UNLOCK(&idle_list); 04929 ast_cli(fd, "Active Threads:\n"); 04930 AST_LIST_LOCK(&active_list); 04931 AST_LIST_TRAVERSE(&active_list, thread, list) { 04932 if (thread->type == IAX_TYPE_DYNAMIC) 04933 type = 'D'; 04934 else 04935 type = 'P'; 04936 #ifdef DEBUG_SCHED_MULTITHREAD 04937 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 04938 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04939 #else 04940 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 04941 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04942 #endif 04943 threadcount++; 04944 } 04945 AST_LIST_UNLOCK(&active_list); 04946 ast_cli(fd, "Dynamic Threads:\n"); 04947 AST_LIST_LOCK(&dynamic_list); 04948 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 04949 #ifdef DEBUG_SCHED_MULTITHREAD 04950 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 04951 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 04952 #else 04953 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 04954 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 04955 #endif 04956 dynamiccount++; 04957 } 04958 AST_LIST_UNLOCK(&dynamic_list); 04959 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 04960 return RESULT_SUCCESS; 04961 }
static int iax2_show_users | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 4721 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag, iax2_user::authmethods, iax2_context::context, iax2_user::contexts, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::name, RESULT_SHOWUSAGE, RESULT_SUCCESS, iax2_user::secret, and user_unref().
04722 { 04723 regex_t regexbuf; 04724 int havepattern = 0; 04725 04726 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 04727 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 04728 04729 struct iax2_user *user = NULL; 04730 char auth[90]; 04731 char *pstr = ""; 04732 struct ao2_iterator i; 04733 04734 switch (argc) { 04735 case 5: 04736 if (!strcasecmp(argv[3], "like")) { 04737 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 04738 return RESULT_SHOWUSAGE; 04739 havepattern = 1; 04740 } else 04741 return RESULT_SHOWUSAGE; 04742 case 3: 04743 break; 04744 default: 04745 return RESULT_SHOWUSAGE; 04746 } 04747 04748 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 04749 i = ao2_iterator_init(users, 0); 04750 for (user = ao2_iterator_next(&i); user; 04751 user_unref(user), user = ao2_iterator_next(&i)) { 04752 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 04753 continue; 04754 04755 if (!ast_strlen_zero(user->secret)) { 04756 ast_copy_string(auth,user->secret,sizeof(auth)); 04757 } else if (!ast_strlen_zero(user->inkeys)) { 04758 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 04759 } else 04760 ast_copy_string(auth, "-no secret-", sizeof(auth)); 04761 04762 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 04763 pstr = "REQ Only"; 04764 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 04765 pstr = "Disabled"; 04766 else 04767 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 04768 04769 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 04770 user->contexts ? user->contexts->context : context, 04771 user->ha ? "Yes" : "No", pstr); 04772 } 04773 04774 if (havepattern) 04775 regfree(®exbuf); 04776 04777 return RESULT_SUCCESS; 04778 #undef FORMAT 04779 #undef FORMAT2 04780 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 3664 of file chan_iax2.c.
References AST_FRAME_IAX, ast_random(), IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, iaxs, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
03665 { 03666 int res; 03667 struct iax_ie_data ied0; 03668 struct iax_ie_data ied1; 03669 unsigned int transferid = (unsigned int)ast_random(); 03670 memset(&ied0, 0, sizeof(ied0)); 03671 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 03672 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 03673 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 03674 03675 memset(&ied1, 0, sizeof(ied1)); 03676 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 03677 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 03678 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 03679 03680 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 03681 if (res) 03682 return -1; 03683 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 03684 if (res) 03685 return -1; 03686 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03687 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 03688 return 0; 03689 }
static int iax2_test_losspct | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 2436 of file chan_iax2.c.
References RESULT_SHOWUSAGE, and RESULT_SUCCESS.
02437 { 02438 if (argc != 4) 02439 return RESULT_SHOWUSAGE; 02440 02441 test_losspct = atoi(argv[3]); 02442 02443 return RESULT_SUCCESS; 02444 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 3907 of file chan_iax2.c.
References ast_copy_string(), AST_FRAME_IAX, ast_log(), chan_iax2_pvt::callno, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, option_debug, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03908 { 03909 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 03910 struct iax_ie_data ied; 03911 char tmp[256], *context; 03912 ast_copy_string(tmp, dest, sizeof(tmp)); 03913 context = strchr(tmp, '@'); 03914 if (context) { 03915 *context = '\0'; 03916 context++; 03917 } 03918 memset(&ied, 0, sizeof(ied)); 03919 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 03920 if (context) 03921 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 03922 if (option_debug) 03923 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest); 03924 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 03925 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2902 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_iax2_queue::count, iaxq, ast_iax2_queue::queue, sched_lock, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
02903 { 02904 /* Lock the queue and place this packet at the end */ 02905 /* By setting this to 0, the network thread will send it for us, and 02906 queue retransmission if necessary */ 02907 fr->sentyet = 0; 02908 AST_LIST_LOCK(&iaxq.queue); 02909 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list); 02910 iaxq.count++; 02911 AST_LIST_UNLOCK(&iaxq.queue); 02912 /* Wake up the network and scheduler thread */ 02913 if (netthreadid != AST_PTHREADT_NULL) 02914 pthread_kill(netthreadid, SIGURG); 02915 signal_condition(&sched_lock, &sched_cond); 02916 return 0; 02917 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 6860 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
06861 { 06862 /* Drop when trunk is about 5 seconds idle */ 06863 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 06864 return 1; 06865 return 0; 06866 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 4276 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_realloc, ast_test_flag, ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, ast_iax2_meta_trunk_mini::mini, option_debug, chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
04277 { 04278 struct ast_frame *f; 04279 struct iax2_trunk_peer *tpeer; 04280 void *tmp, *ptr; 04281 struct ast_iax2_meta_trunk_entry *met; 04282 struct ast_iax2_meta_trunk_mini *mtm; 04283 04284 f = &fr->af; 04285 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 04286 if (tpeer) { 04287 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 04288 /* Need to reallocate space */ 04289 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) { 04290 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 04291 ast_mutex_unlock(&tpeer->lock); 04292 return -1; 04293 } 04294 04295 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 04296 tpeer->trunkdata = tmp; 04297 if (option_debug) 04298 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 04299 } else { 04300 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 04301 ast_mutex_unlock(&tpeer->lock); 04302 return -1; 04303 } 04304 } 04305 04306 /* Append to meta frame */ 04307 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 04308 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 04309 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 04310 mtm->len = htons(f->datalen); 04311 mtm->mini.callno = htons(pvt->callno); 04312 mtm->mini.ts = htons(0xffff & fr->ts); 04313 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 04314 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 04315 } else { 04316 met = (struct ast_iax2_meta_trunk_entry *)ptr; 04317 /* Store call number and length in meta header */ 04318 met->callno = htons(pvt->callno); 04319 met->len = htons(f->datalen); 04320 /* Advance pointers/decrease length past trunk entry header */ 04321 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 04322 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 04323 } 04324 /* Copy actual trunk data */ 04325 memcpy(ptr, f->data, f->datalen); 04326 tpeer->trunkdatalen += f->datalen; 04327 04328 tpeer->calls++; 04329 ast_mutex_unlock(&tpeer->lock); 04330 } 04331 return 0; 04332 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 6777 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process().
06778 { 06779 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 06780 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 5277 of file chan_iax2.c.
References AST_FRAME_NULL, AST_FRAME_VOICE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_registry::callno, errno, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, option_debug, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05278 { 05279 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05280 int res = -1; 05281 ast_mutex_lock(&iaxsl[callno]); 05282 if (iaxs[callno]) { 05283 /* If there's an outstanding error, return failure now */ 05284 if (!iaxs[callno]->error) { 05285 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 05286 res = 0; 05287 /* Don't waste bandwidth sending null frames */ 05288 else if (f->frametype == AST_FRAME_NULL) 05289 res = 0; 05290 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 05291 res = 0; 05292 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 05293 res = 0; 05294 else 05295 /* Simple, just queue for transmission */ 05296 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 05297 } else { 05298 if (option_debug) 05299 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno)); 05300 } 05301 } 05302 /* If it's already gone, just return */ 05303 ast_mutex_unlock(&iaxsl[callno]); 05304 return res; 05305 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2038 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().
02039 { 02040 int res = 0; 02041 struct iax_firmware *cur; 02042 if (!ast_strlen_zero(dev)) { 02043 ast_mutex_lock(&waresl.lock); 02044 cur = waresl.wares; 02045 while(cur) { 02046 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02047 res = ntohs(cur->fwh->version); 02048 break; 02049 } 02050 cur = cur->next; 02051 } 02052 ast_mutex_unlock(&waresl.lock); 02053 } 02054 return res; 02055 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 772 of file chan_iax2.c.
References ast_verbose().
Referenced by load_module().
00773 { 00774 if (iaxdebug) 00775 ast_verbose("%s", data); 00776 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 778 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00779 { 00780 ast_log(LOG_WARNING, "%s", data); 00781 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 2057 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, ast_firmware_list::lock, iax_firmware::next, ast_firmware_list::wares, and waresl.
Referenced by socket_process().
02058 { 02059 int res = -1; 02060 unsigned int bs = desc & 0xff; 02061 unsigned int start = (desc >> 8) & 0xffffff; 02062 unsigned int bytes; 02063 struct iax_firmware *cur; 02064 if (!ast_strlen_zero((char *)dev) && bs) { 02065 start *= bs; 02066 ast_mutex_lock(&waresl.lock); 02067 cur = waresl.wares; 02068 while(cur) { 02069 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) { 02070 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02071 if (start < ntohl(cur->fwh->datalen)) { 02072 bytes = ntohl(cur->fwh->datalen) - start; 02073 if (bytes > bs) 02074 bytes = bs; 02075 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02076 } else { 02077 bytes = 0; 02078 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02079 } 02080 if (bytes == bs) 02081 res = 0; 02082 else 02083 res = 1; 02084 break; 02085 } 02086 cur = cur->next; 02087 } 02088 ast_mutex_unlock(&waresl.lock); 02089 } 02090 return res; 02091 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2 | |||
) | [static] |
Definition at line 7048 of file chan_iax2.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc(), ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_hangup(), ast_log(), ast_pthread_create_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, free, iax_park_thread(), LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
07049 { 07050 struct iax_dual *d; 07051 struct ast_channel *chan1m, *chan2m; 07052 pthread_t th; 07053 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 07054 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 07055 if (chan2m && chan1m) { 07056 /* Make formats okay */ 07057 chan1m->readformat = chan1->readformat; 07058 chan1m->writeformat = chan1->writeformat; 07059 ast_channel_masquerade(chan1m, chan1); 07060 /* Setup the extensions and such */ 07061 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 07062 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 07063 chan1m->priority = chan1->priority; 07064 07065 /* We make a clone of the peer channel too, so we can play 07066 back the announcement */ 07067 /* Make formats okay */ 07068 chan2m->readformat = chan2->readformat; 07069 chan2m->writeformat = chan2->writeformat; 07070 ast_channel_masquerade(chan2m, chan2); 07071 /* Setup the extensions and such */ 07072 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 07073 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 07074 chan2m->priority = chan2->priority; 07075 if (ast_do_masquerade(chan2m)) { 07076 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 07077 ast_hangup(chan2m); 07078 return -1; 07079 } 07080 } else { 07081 if (chan1m) 07082 ast_hangup(chan1m); 07083 if (chan2m) 07084 ast_hangup(chan2m); 07085 return -1; 07086 } 07087 if ((d = ast_calloc(1, sizeof(*d)))) { 07088 pthread_attr_t attr; 07089 07090 pthread_attr_init(&attr); 07091 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07092 07093 d->chan1 = chan1m; 07094 d->chan2 = chan2m; 07095 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) { 07096 pthread_attr_destroy(&attr); 07097 return 0; 07098 } 07099 pthread_attr_destroy(&attr); 07100 free(d); 07101 } 07102 return -1; 07103 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 7028 of file chan_iax2.c.
References ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, free, and LOG_NOTICE.
Referenced by iax_park().
07029 { 07030 struct ast_channel *chan1, *chan2; 07031 struct iax_dual *d; 07032 struct ast_frame *f; 07033 int ext; 07034 int res; 07035 d = stuff; 07036 chan1 = d->chan1; 07037 chan2 = d->chan2; 07038 free(d); 07039 f = ast_read(chan1); 07040 if (f) 07041 ast_frfree(f); 07042 res = ast_park_call(chan1, chan2, 0, &ext); 07043 ast_hangup(chan2); 07044 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 07045 return NULL; 07046 }
Definition at line 1502 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process().
01503 { 01504 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01505 if (new) { 01506 size_t afdatalen = new->afdatalen; 01507 memcpy(new, fr, sizeof(*new)); 01508 iax_frame_wrap(new, &fr->af); 01509 new->afdatalen = afdatalen; 01510 new->data = NULL; 01511 new->datalen = 0; 01512 new->direction = DIRECTION_INGRESS; 01513 new->retrans = -1; 01514 } 01515 return new; 01516 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 914 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_TYPE_DYNAMIC, and thread.
Referenced by iax2_process_thread().
00915 { 00916 if (thread->type == IAX_TYPE_DYNAMIC) { 00917 AST_LIST_LOCK(&dynamic_list); 00918 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 00919 AST_LIST_UNLOCK(&dynamic_list); 00920 } else { 00921 AST_LIST_LOCK(&idle_list); 00922 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 00923 AST_LIST_UNLOCK(&idle_list); 00924 } 00925 00926 return; 00927 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 807 of file chan_iax2.c.
References ast_verbose().
Referenced by iax2_do_jb_debug(), and iax2_no_jb_debug().
00808 { 00809 va_list args; 00810 char buf[1024]; 00811 00812 va_start(args, fmt); 00813 vsnprintf(buf, 1024, fmt, args); 00814 va_end(args); 00815 00816 ast_verbose("%s", buf); 00817 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 783 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00784 { 00785 va_list args; 00786 char buf[1024]; 00787 00788 va_start(args, fmt); 00789 vsnprintf(buf, 1024, fmt, args); 00790 va_end(args); 00791 00792 ast_log(LOG_ERROR, "%s", buf); 00793 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 795 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by iax2_do_jb_debug(), iax2_no_jb_debug(), and load_module().
00796 { 00797 va_list args; 00798 char buf[1024]; 00799 00800 va_start(args, fmt); 00801 vsnprintf(buf, 1024, fmt, args); 00802 va_end(args); 00803 00804 ast_log(LOG_WARNING, "%s", buf); 00805 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 11468 of file chan_iax2.c.
References __unload_module(), ao2_callback(), ao2_container_alloc(), ao2_ref(), ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register(), AST_LIST_HEAD_INIT, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, ast_mutex_init(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_register_application(), ast_register_switch(), ast_verbose(), cli_iax2, config, DAHDI_FILE_PSEUDO, DAHDI_FILE_TIMER, iax2_registry::entry, errno, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), IAX_MAX_CALLS, iax_peercallno_pvts, iax_provision_reload(), iax_set_error(), iax_set_output(), iax_transfercallno_pvts, iaxpeer_function, iaxq, iaxs, iaxsl, io, io_context_create(), jb_error_output(), jb_setoutput(), jb_warning_output(), ast_firmware_list::lock, LOG_ERROR, LOG_WARNING, manager_iax2_show_netstats(), manager_iax2_show_peers(), MAX_PEER_BUCKETS, MAX_USER_BUCKETS, netsock, option_verbose, outsock, peer_cmp_cb(), peer_hash_cb(), peer_set_sock_cb(), pvt_cmp_cb(), pvt_hash_cb(), ast_iax2_queue::queue, reload_firmware(), sched, sched_context_create(), set_config(), start_network_thread(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), VERBOSE_PREFIX_2, and waresl.
11469 { 11470 char *config = "iax.conf"; 11471 int res = 0; 11472 int x; 11473 struct iax2_registry *reg = NULL; 11474 11475 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb); 11476 if (!peers) 11477 return AST_MODULE_LOAD_FAILURE; 11478 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb); 11479 if (!users) { 11480 ao2_ref(peers, -1); 11481 return AST_MODULE_LOAD_FAILURE; 11482 } 11483 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb); 11484 if (!iax_peercallno_pvts) { 11485 ao2_ref(peers, -1); 11486 ao2_ref(users, -1); 11487 return AST_MODULE_LOAD_FAILURE; 11488 } 11489 iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb); 11490 if (!iax_transfercallno_pvts) { 11491 ao2_ref(peers, -1); 11492 ao2_ref(users, -1); 11493 ao2_ref(iax_peercallno_pvts, -1); 11494 return AST_MODULE_LOAD_FAILURE; 11495 } 11496 ast_custom_function_register(&iaxpeer_function); 11497 11498 iax_set_output(iax_debug_output); 11499 iax_set_error(iax_error_output); 11500 jb_setoutput(jb_error_output, jb_warning_output, NULL); 11501 11502 #ifdef HAVE_DAHDI 11503 #ifdef DAHDI_TIMERACK 11504 timingfd = open(DAHDI_FILE_TIMER, O_RDWR); 11505 if (timingfd < 0) 11506 #endif 11507 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR); 11508 if (timingfd < 0) 11509 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno)); 11510 #endif 11511 11512 memset(iaxs, 0, sizeof(iaxs)); 11513 11514 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 11515 ast_mutex_init(&iaxsl[x]); 11516 } 11517 11518 ast_cond_init(&sched_cond, NULL); 11519 11520 io = io_context_create(); 11521 sched = sched_context_create(); 11522 11523 if (!io || !sched) { 11524 ast_log(LOG_ERROR, "Out of memory\n"); 11525 return -1; 11526 } 11527 11528 netsock = ast_netsock_list_alloc(); 11529 if (!netsock) { 11530 ast_log(LOG_ERROR, "Could not allocate netsock list.\n"); 11531 return -1; 11532 } 11533 ast_netsock_init(netsock); 11534 11535 outsock = ast_netsock_list_alloc(); 11536 if (!outsock) { 11537 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 11538 return -1; 11539 } 11540 ast_netsock_init(outsock); 11541 11542 ast_mutex_init(&waresl.lock); 11543 11544 AST_LIST_HEAD_INIT(&iaxq.queue); 11545 11546 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 11547 11548 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 11549 11550 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" ); 11551 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" ); 11552 11553 if(set_config(config, 0) == -1) 11554 return AST_MODULE_LOAD_DECLINE; 11555 11556 if (ast_channel_register(&iax2_tech)) { 11557 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 11558 __unload_module(); 11559 return -1; 11560 } 11561 11562 if (ast_register_switch(&iax2_switch)) 11563 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 11564 11565 res = start_network_thread(); 11566 if (!res) { 11567 if (option_verbose > 1) 11568 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n"); 11569 } else { 11570 ast_log(LOG_ERROR, "Unable to start network thread\n"); 11571 ast_netsock_release(netsock); 11572 ast_netsock_release(outsock); 11573 } 11574 11575 AST_LIST_LOCK(®istrations); 11576 AST_LIST_TRAVERSE(®istrations, reg, entry) 11577 iax2_do_register(reg); 11578 AST_LIST_UNLOCK(®istrations); 11579 11580 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 11581 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 11582 11583 reload_firmware(0); 11584 iax_provision_reload(); 11585 return res; 11586 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3691 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
03692 { 03693 ast_mutex_lock(&iaxsl[callno0]); 03694 while (ast_mutex_trylock(&iaxsl[callno1])) { 03695 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 03696 } 03697 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 1556 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, iax2_sched_add(), LOG_DEBUG, LOG_WARNING, MIN_REUSE_TIME, option_debug, sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), and update_max_trunk().
Referenced by iax2_request(), and socket_process().
01557 { 01558 int x; 01559 int res= 0; 01560 struct timeval now; 01561 if (iaxs[callno]->oseqno) { 01562 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01563 return -1; 01564 } 01565 if (callno & TRUNK_CALL_START) { 01566 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01567 return -1; 01568 } 01569 gettimeofday(&now, NULL); 01570 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01571 ast_mutex_lock(&iaxsl[x]); 01572 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) { 01573 /* Update the two timers that should have been started */ 01574 /*! 01575 * \note We delete these before switching the slot, because if 01576 * they fire in the meantime, they will generate a warning. 01577 */ 01578 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01579 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01580 iaxs[x] = iaxs[callno]; 01581 iaxs[x]->callno = x; 01582 iaxs[callno] = NULL; 01583 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 01584 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 01585 if (locked) 01586 ast_mutex_unlock(&iaxsl[callno]); 01587 res = x; 01588 if (!locked) 01589 ast_mutex_unlock(&iaxsl[x]); 01590 break; 01591 } 01592 ast_mutex_unlock(&iaxsl[x]); 01593 } 01594 if (x >= ARRAY_LEN(iaxs) - 1) { 01595 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01596 return -1; 01597 } 01598 if (option_debug) 01599 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x); 01600 /* We move this call from a non-trunked to a trunked call */ 01601 update_max_trunk(); 01602 update_max_nontrunk(); 01603 return res; 01604 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 4967 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), RESULT_SUCCESS, and s.
Referenced by load_module().
04968 { 04969 ast_cli_netstats(s, -1, 0); 04970 astman_append(s, "\r\n"); 04971 return RESULT_SUCCESS; 04972 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 5000 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), and s.
Referenced by load_module().
05001 { 05002 char *a[] = { "iax2", "show", "users" }; 05003 int ret; 05004 const char *id = astman_get_header(m,"ActionID"); 05005 05006 if (!ast_strlen_zero(id)) 05007 astman_append(s, "ActionID: %s\r\n",id); 05008 ret = __iax2_show_peers(1, -1, s, 3, a ); 05009 astman_append(s, "\r\n\r\n" ); 05010 return ret; 05011 } /* /JDG */
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 1522 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), ao2_callback(), ast_parse_device_state(), check_blacklist(), find_command(), get_sip_pvt_byid_locked(), handle_updates(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), softhangup_exec(), and transfercallno_pvt_cmp_cb().
01523 { 01524 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01525 (cur->addr.sin_port == sin->sin_port)) { 01526 /* This is the main host */ 01527 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01528 (check_dcallno ? dcallno == cur->callno : 1) ) { 01529 /* That's us. Be sure we keep track of the peer call number */ 01530 return 1; 01531 } 01532 } 01533 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01534 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01535 /* We're transferring */ 01536 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01537 return 1; 01538 } 01539 return 0; 01540 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_decrypt_ctx * | dcx | |||
) | [static] |
Definition at line 4362 of file chan_iax2.c.
References aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
04363 { 04364 #if 0 04365 /* Debug with "fake encryption" */ 04366 int x; 04367 if (len % 16) 04368 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04369 for (x=0;x<len;x++) 04370 dst[x] = src[x] ^ 0xff; 04371 #else 04372 unsigned char lastblock[16] = { 0 }; 04373 int x; 04374 while(len > 0) { 04375 aes_decrypt(src, dst, dcx); 04376 for (x=0;x<16;x++) 04377 dst[x] ^= lastblock[x]; 04378 memcpy(lastblock, src, sizeof(lastblock)); 04379 dst += 16; 04380 src += 16; 04381 len -= 16; 04382 } 04383 #endif 04384 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
aes_encrypt_ctx * | ecx | |||
) | [static] |
Definition at line 4386 of file chan_iax2.c.
References aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
04387 { 04388 #if 0 04389 /* Debug with "fake encryption" */ 04390 int x; 04391 if (len % 16) 04392 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 04393 for (x=0;x<len;x++) 04394 dst[x] = src[x] ^ 0xff; 04395 #else 04396 unsigned char curblock[16] = { 0 }; 04397 int x; 04398 while(len > 0) { 04399 for (x=0;x<16;x++) 04400 curblock[x] ^= src[x]; 04401 aes_encrypt(curblock, dst, ecx); 04402 memcpy(curblock, dst, sizeof(curblock)); 04403 dst += 16; 04404 src += 16; 04405 len -= 16; 04406 } 04407 #endif 04408 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 5611 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, and IAX_ENCRYPT_AES128.
Referenced by authenticate_reply(), and socket_process().
05612 { 05613 /* Select exactly one common encryption if there are any */ 05614 p->encmethods &= enc; 05615 if (p->encmethods) { 05616 if (p->encmethods & IAX_ENCRYPT_AES128) 05617 p->encmethods = IAX_ENCRYPT_AES128; 05618 else 05619 p->encmethods = 0; 05620 } 05621 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 9415 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), attempt_transmit(), ast_iax2_queue::count, f, iax2_sched_add(), iax_frame_free(), iaxq, iaxs, iaxsl, io, iax_frame::list, option_debug, ast_iax2_queue::queue, sched, send_packet(), and timing_read().
Referenced by start_network_thread().
09416 { 09417 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 09418 from the network, and queue them for delivery to the channels */ 09419 int res, count, wakeup; 09420 struct iax_frame *f; 09421 09422 if (timingfd > -1) 09423 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL); 09424 09425 for(;;) { 09426 pthread_testcancel(); 09427 09428 /* Go through the queue, sending messages which have not yet been 09429 sent, and scheduling retransmissions if appropriate */ 09430 AST_LIST_LOCK(&iaxq.queue); 09431 count = 0; 09432 wakeup = -1; 09433 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) { 09434 if (f->sentyet) 09435 continue; 09436 09437 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 09438 if (ast_mutex_trylock(&iaxsl[f->callno])) { 09439 wakeup = 1; 09440 continue; 09441 } 09442 09443 f->sentyet++; 09444 09445 if (iaxs[f->callno]) { 09446 send_packet(f); 09447 count++; 09448 } 09449 09450 ast_mutex_unlock(&iaxsl[f->callno]); 09451 09452 if (f->retries < 0) { 09453 /* This is not supposed to be retransmitted */ 09454 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list); 09455 iaxq.count--; 09456 /* Free the iax frame */ 09457 iax_frame_free(f); 09458 } else { 09459 /* We need reliable delivery. Schedule a retransmission */ 09460 f->retries++; 09461 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 09462 } 09463 } 09464 AST_LIST_TRAVERSE_SAFE_END 09465 AST_LIST_UNLOCK(&iaxq.queue); 09466 09467 pthread_testcancel(); 09468 09469 if (option_debug && count >= 20) 09470 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 09471 09472 /* Now do the IO, and run scheduled tasks */ 09473 res = ast_io_wait(io, wakeup); 09474 if (res >= 0) { 09475 if (option_debug && res >= 20) 09476 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 09477 } 09478 } 09479 return NULL; 09480 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1463 of file chan_iax2.c.
References ao2_alloc(), ao2_ref(), ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), and jb_conf::resync_threshold.
Referenced by __find_callno().
01464 { 01465 struct chan_iax2_pvt *tmp; 01466 jb_conf jbconf; 01467 01468 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01469 return NULL; 01470 } 01471 01472 if (ast_string_field_init(tmp, 32)) { 01473 ao2_ref(tmp, -1); 01474 tmp = NULL; 01475 return NULL; 01476 } 01477 01478 tmp->prefs = prefs; 01479 tmp->callno = 0; 01480 tmp->peercallno = 0; 01481 tmp->transfercallno = 0; 01482 tmp->bridgecallno = 0; 01483 tmp->pingid = -1; 01484 tmp->lagid = -1; 01485 tmp->autoid = -1; 01486 tmp->authid = -1; 01487 tmp->initid = -1; 01488 01489 ast_string_field_set(tmp,exten, "s"); 01490 ast_string_field_set(tmp,host, host); 01491 01492 tmp->jb = jb_new(); 01493 tmp->jbid = -1; 01494 jbconf.max_jitterbuf = maxjitterbuffer; 01495 jbconf.resync_threshold = resyncthreshold; 01496 jbconf.max_contig_interp = maxjitterinterps; 01497 jb_setconf(tmp->jb,&jbconf); 01498 01499 return tmp; 01500 }
static void parse_dial_string | ( | char * | data, | |
struct parsed_dial_string * | pds | |||
) | [static] |
Parses an IAX dial string into its component parts.
data | the string to be parsed | |
pds | pointer to a struct parsed_dial_string to be filled in |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 3362 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
03363 { 03364 if (ast_strlen_zero(data)) 03365 return; 03366 03367 pds->peer = strsep(&data, "/"); 03368 pds->exten = strsep(&data, "/"); 03369 pds->options = data; 03370 03371 if (pds->exten) { 03372 data = pds->exten; 03373 pds->exten = strsep(&data, "@"); 03374 pds->context = data; 03375 } 03376 03377 if (strchr(pds->peer, '@')) { 03378 data = pds->peer; 03379 pds->username = strsep(&data, "@"); 03380 pds->peer = data; 03381 } 03382 03383 if (pds->username) { 03384 data = pds->username; 03385 pds->username = strsep(&data, ":"); 03386 pds->password = data; 03387 } 03388 03389 data = pds->peer; 03390 pds->peer = strsep(&data, ":"); 03391 pds->port = data; 03392 03393 /* check for a key name wrapped in [] in the secret position, if found, 03394 move it to the key field instead 03395 */ 03396 if (pds->password && (pds->password[0] == '[')) { 03397 pds->key = ast_strip_quoted(pds->password, "[", "]"); 03398 pds->password = NULL; 03399 } 03400 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1143 of file chan_iax2.c.
References iax2_peer::name.
Referenced by load_module().
01144 { 01145 struct iax2_peer *peer = obj, *peer2 = arg; 01146 01147 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01148 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10110 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
10111 { 10112 struct iax2_peer *peer = obj; 10113 10114 ast_set_flag(peer, IAX_DELME); 10115 10116 return 0; 10117 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 9638 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_free_ha(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, and register_peer_exten().
Referenced by build_peer().
09639 { 09640 struct iax2_peer *peer = obj; 09641 int callno = peer->callno; 09642 09643 ast_free_ha(peer->ha); 09644 09645 if (callno > 0) { 09646 ast_mutex_lock(&iaxsl[callno]); 09647 iax2_destroy(callno); 09648 ast_mutex_unlock(&iaxsl[callno]); 09649 } 09650 09651 register_peer_exten(peer, 0); 09652 09653 if (peer->dnsmgr) 09654 ast_dnsmgr_release(peer->dnsmgr); 09655 09656 ast_string_field_free_memory(peer); 09657 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1133 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module().
01134 { 01135 const struct iax2_peer *peer = obj; 01136 01137 return ast_str_hash(peer->name); 01138 }
Definition at line 1190 of file chan_iax2.c.
References ao2_ref().
Referenced by __iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), reg_source_db(), socket_process(), and update_registry().
01191 { 01192 ao2_ref(peer, +1); 01193 return peer; 01194 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11422 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
11423 { 11424 struct iax2_peer *peer = obj; 11425 11426 if (peer->sockfd < 0) 11427 peer->sockfd = defaultsockfd; 11428 11429 return 0; 11430 }
static int peer_set_srcaddr | ( | struct iax2_peer * | peer, | |
const char * | srcaddr | |||
) | [static] |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
Definition at line 9565 of file chan_iax2.c.
References ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, io, LOG_WARNING, iax2_peer::name, netsock, option_debug, outsock, socket_read(), and iax2_peer::sockfd.
Referenced by build_peer().
09566 { 09567 struct sockaddr_in sin; 09568 int nonlocal = 1; 09569 int port = IAX_DEFAULT_PORTNO; 09570 int sockfd = defaultsockfd; 09571 char *tmp; 09572 char *addr; 09573 char *portstr; 09574 09575 if (!(tmp = ast_strdupa(srcaddr))) 09576 return -1; 09577 09578 addr = strsep(&tmp, ":"); 09579 portstr = tmp; 09580 09581 if (portstr) { 09582 port = atoi(portstr); 09583 if (port < 1) 09584 port = IAX_DEFAULT_PORTNO; 09585 } 09586 09587 if (!ast_get_ip(&sin, addr)) { 09588 struct ast_netsock *sock; 09589 int res; 09590 09591 sin.sin_port = 0; 09592 sin.sin_family = AF_INET; 09593 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 09594 if (res == 0) { 09595 /* ip address valid. */ 09596 sin.sin_port = htons(port); 09597 if (!(sock = ast_netsock_find(netsock, &sin))) 09598 sock = ast_netsock_find(outsock, &sin); 09599 if (sock) { 09600 sockfd = ast_netsock_sockfd(sock); 09601 nonlocal = 0; 09602 } else { 09603 unsigned int orig_saddr = sin.sin_addr.s_addr; 09604 /* INADDR_ANY matches anyway! */ 09605 sin.sin_addr.s_addr = INADDR_ANY; 09606 if (ast_netsock_find(netsock, &sin)) { 09607 sin.sin_addr.s_addr = orig_saddr; 09608 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL); 09609 if (sock) { 09610 sockfd = ast_netsock_sockfd(sock); 09611 ast_netsock_unref(sock); 09612 nonlocal = 0; 09613 } else { 09614 nonlocal = 2; 09615 } 09616 } 09617 } 09618 } 09619 } 09620 09621 peer->sockfd = sockfd; 09622 09623 if (nonlocal == 1) { 09624 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 09625 srcaddr, peer->name); 09626 return -1; 09627 } else if (nonlocal == 2) { 09628 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 09629 srcaddr, peer->name); 09630 return -1; 09631 } else { 09632 if (option_debug) 09633 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 09634 return 0; 09635 } 09636 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 2482 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), and iax2_show_peer().
02483 { 02484 int res = 0; 02485 if (peer->maxms) { 02486 if (peer->lastms < 0) { 02487 ast_copy_string(status, "UNREACHABLE", statuslen); 02488 } else if (peer->lastms > peer->maxms) { 02489 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 02490 res = 1; 02491 } else if (peer->lastms) { 02492 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 02493 res = 1; 02494 } else { 02495 ast_copy_string(status, "UNKNOWN", statuslen); 02496 } 02497 } else { 02498 ast_copy_string(status, "Unmonitored", statuslen); 02499 res = -1; 02500 } 02501 return res; 02502 }
Definition at line 1196 of file chan_iax2.c.
References ao2_ref().
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), complete_iax2_show_peer(), create_addr(), function_iaxpeer(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), iax2_prune_realtime(), iax2_show_peer(), poke_all_peers(), prune_peers(), reg_source_db(), registry_authrequest(), set_config(), socket_process(), unlink_peer(), and update_registry().
01197 { 01198 ao2_ref(peer, -1); 01199 return NULL; 01200 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 10574 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
10575 { 10576 struct ao2_iterator i; 10577 struct iax2_peer *peer; 10578 10579 i = ao2_iterator_init(peers, 0); 10580 while ((peer = ao2_iterator_next(&i))) { 10581 iax2_poke_peer(peer, 0); 10582 peer_unref(peer); 10583 } 10584 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 10170 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().
10171 { 10172 struct iax2_peer *peer; 10173 struct ao2_iterator i; 10174 10175 i = ao2_iterator_init(peers, 0); 10176 while ((peer = ao2_iterator_next(&i))) { 10177 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 10178 unlink_peer(peer); 10179 } 10180 peer_unref(peer); 10181 } 10182 }
static void prune_users | ( | void | ) | [static] |
Definition at line 10155 of file chan_iax2.c.
References ao2_iterator_init(), ao2_iterator_next(), ao2_unlink(), ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().
Referenced by iax2_prune_realtime(), and reload_config().
10156 { 10157 struct iax2_user *user; 10158 struct ao2_iterator i; 10159 10160 i = ao2_iterator_init(users, 0); 10161 while ((user = ao2_iterator_next(&i))) { 10162 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 10163 ao2_unlink(users, user); 10164 } 10165 user_unref(user); 10166 } 10167 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11439 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11440 { 11441 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11442 11443 /* The frames_received field is used to hold whether we're matching 11444 * against a full frame or not ... */ 11445 11446 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 11447 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 11448 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1424 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, iax_frame::callno, jb_frame::data, iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxq, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax_frame::list, chan_iax2_pvt::owner, ast_iax2_queue::queue, chan_iax2_pvt::reg, iax_frame::retries, and chan_iax2_pvt::vars.
Referenced by new_iax().
01425 { 01426 struct chan_iax2_pvt *pvt = obj; 01427 struct iax_frame *cur = NULL; 01428 01429 iax2_destroy_helper(pvt); 01430 01431 /* Already gone */ 01432 ast_set_flag(pvt, IAX_ALREADYGONE); 01433 01434 AST_LIST_LOCK(&iaxq.queue); 01435 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 01436 /* Cancel any pending transmissions */ 01437 if (cur->callno == pvt->callno) { 01438 cur->retries = -1; 01439 } 01440 } 01441 AST_LIST_UNLOCK(&iaxq.queue); 01442 01443 if (pvt->reg) { 01444 pvt->reg->callno = 0; 01445 } 01446 01447 if (!pvt->owner) { 01448 jb_frame frame; 01449 if (pvt->vars) { 01450 ast_variables_destroy(pvt->vars); 01451 pvt->vars = NULL; 01452 } 01453 01454 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01455 iax2_frame_free(frame.data); 01456 } 01457 01458 jb_destroy(pvt->jb); 01459 ast_string_field_free_memory(pvt); 01460 } 01461 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11432 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_module().
11433 { 11434 const struct chan_iax2_pvt *pvt = obj; 11435 11436 return pvt->peercallno; 11437 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 5593 of file chan_iax2.c.
References AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_showframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
05594 { 05595 struct ast_iax2_full_hdr fh; 05596 fh.scallno = htons(src | IAX_FLAG_FULL); 05597 fh.dcallno = htons(dst); 05598 fh.ts = 0; 05599 fh.oseqno = 0; 05600 fh.iseqno = 0; 05601 fh.type = AST_FRAME_IAX; 05602 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 05603 if (iaxdebug) 05604 iax_showframe(NULL, &fh, 0, sin, 0); 05605 if (option_debug) 05606 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n", 05607 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 05608 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 05609 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 2964 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
02965 { 02966 struct ast_variable *var = NULL; 02967 struct ast_variable *tmp; 02968 struct iax2_peer *peer=NULL; 02969 time_t regseconds = 0, nowtime; 02970 int dynamic=0; 02971 02972 if (peername) { 02973 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL); 02974 if (!var && sin) 02975 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL); 02976 } else if (sin) { 02977 char porta[25]; 02978 sprintf(porta, "%d", ntohs(sin->sin_port)); 02979 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 02980 if (var) { 02981 /* We'll need the peer name in order to build the structure! */ 02982 for (tmp = var; tmp; tmp = tmp->next) { 02983 if (!strcasecmp(tmp->name, "name")) 02984 peername = tmp->value; 02985 } 02986 } 02987 } 02988 if (!var && peername) { /* Last ditch effort */ 02989 var = ast_load_realtime("iaxpeers", "name", peername, NULL); 02990 /*!\note 02991 * If this one loaded something, then we need to ensure that the host 02992 * field matched. The only reason why we can't have this as a criteria 02993 * is because we only have the IP address and the host field might be 02994 * set as a name (and the reverse PTR might not match). 02995 */ 02996 if (var && sin) { 02997 for (tmp = var; tmp; tmp = tmp->next) { 02998 if (!strcasecmp(tmp->name, "host")) { 02999 struct ast_hostent ahp; 03000 struct hostent *hp; 03001 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03002 /* No match */ 03003 ast_variables_destroy(var); 03004 var = NULL; 03005 } 03006 break; 03007 } 03008 } 03009 } 03010 } 03011 if (!var) 03012 return NULL; 03013 03014 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 03015 03016 if (!peer) { 03017 ast_variables_destroy(var); 03018 return NULL; 03019 } 03020 03021 for (tmp = var; tmp; tmp = tmp->next) { 03022 /* Make sure it's not a user only... */ 03023 if (!strcasecmp(tmp->name, "type")) { 03024 if (strcasecmp(tmp->value, "friend") && 03025 strcasecmp(tmp->value, "peer")) { 03026 /* Whoops, we weren't supposed to exist! */ 03027 peer = peer_unref(peer); 03028 break; 03029 } 03030 } else if (!strcasecmp(tmp->name, "regseconds")) { 03031 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 03032 } else if (!strcasecmp(tmp->name, "ipaddr")) { 03033 inet_aton(tmp->value, &(peer->addr.sin_addr)); 03034 } else if (!strcasecmp(tmp->name, "port")) { 03035 peer->addr.sin_port = htons(atoi(tmp->value)); 03036 } else if (!strcasecmp(tmp->name, "host")) { 03037 if (!strcasecmp(tmp->value, "dynamic")) 03038 dynamic = 1; 03039 } 03040 } 03041 03042 ast_variables_destroy(var); 03043 03044 if (!peer) 03045 return NULL; 03046 03047 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03048 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 03049 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 03050 if (peer->expire > -1) { 03051 if (!ast_sched_del(sched, peer->expire)) { 03052 peer->expire = -1; 03053 peer_unref(peer); 03054 } 03055 } 03056 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 03057 if (peer->expire == -1) 03058 peer_unref(peer); 03059 } 03060 ao2_link(peers, peer); 03061 if (ast_test_flag(peer, IAX_DYNAMIC)) 03062 reg_source_db(peer); 03063 } else { 03064 ast_set_flag(peer, IAX_TEMPONLY); 03065 } 03066 03067 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 03068 time(&nowtime); 03069 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 03070 memset(&peer->addr, 0, sizeof(peer->addr)); 03071 realtime_update_peer(peer->name, &peer->addr, 0); 03072 if (option_debug) 03073 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 03074 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03075 } 03076 else { 03077 if (option_debug) 03078 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 03079 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 03080 } 03081 } 03082 03083 return peer; 03084 }
static void realtime_update_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin, | |||
time_t | regtime | |||
) | [static] |
Definition at line 3157 of file chan_iax2.c.
References ast_inet_ntoa(), and ast_update_realtime().
Referenced by __expire_registry(), update_peer(), and update_registry().
03158 { 03159 char port[10]; 03160 char regseconds[20]; 03161 03162 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 03163 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 03164 ast_update_realtime("iaxpeers", "name", peername, 03165 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 03166 "regseconds", regseconds, NULL); 03167 }
static struct iax2_user* realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 3086 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, ast_variable::value, and var.
03087 { 03088 struct ast_variable *var; 03089 struct ast_variable *tmp; 03090 struct iax2_user *user=NULL; 03091 03092 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL); 03093 if (!var) 03094 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL); 03095 if (!var && sin) { 03096 char porta[6]; 03097 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 03098 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03099 if (!var) 03100 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL); 03101 } 03102 if (!var) { /* Last ditch effort */ 03103 var = ast_load_realtime("iaxusers", "name", username, NULL); 03104 /*!\note 03105 * If this one loaded something, then we need to ensure that the host 03106 * field matched. The only reason why we can't have this as a criteria 03107 * is because we only have the IP address and the host field might be 03108 * set as a name (and the reverse PTR might not match). 03109 */ 03110 if (var) { 03111 for (tmp = var; tmp; tmp = tmp->next) { 03112 if (!strcasecmp(tmp->name, "host")) { 03113 struct ast_hostent ahp; 03114 struct hostent *hp; 03115 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 03116 /* No match */ 03117 ast_variables_destroy(var); 03118 var = NULL; 03119 } 03120 break; 03121 } 03122 } 03123 } 03124 } 03125 if (!var) 03126 return NULL; 03127 03128 tmp = var; 03129 while(tmp) { 03130 /* Make sure it's not a peer only... */ 03131 if (!strcasecmp(tmp->name, "type")) { 03132 if (strcasecmp(tmp->value, "friend") && 03133 strcasecmp(tmp->value, "user")) { 03134 return NULL; 03135 } 03136 } 03137 tmp = tmp->next; 03138 } 03139 03140 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 03141 03142 ast_variables_destroy(var); 03143 03144 if (!user) 03145 return NULL; 03146 03147 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 03148 ast_set_flag(user, IAX_RTCACHEFRIENDS); 03149 ao2_link(users, user); 03150 } else { 03151 ast_set_flag(user, IAX_TEMPONLY); 03152 } 03153 03154 return user; 03155 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 6407 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), ast_device_state_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verbose(), iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, iax2_peer::name, option_verbose, peer_ref(), peer_unref(), register_peer_exten(), sched, and VERBOSE_PREFIX_3.
Referenced by build_peer(), set_config(), and temp_peer().
06408 { 06409 char data[80]; 06410 struct in_addr in; 06411 char *c, *d; 06412 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 06413 c = strchr(data, ':'); 06414 if (c) { 06415 *c = '\0'; 06416 c++; 06417 if (inet_aton(data, &in)) { 06418 d = strchr(c, ':'); 06419 if (d) { 06420 *d = '\0'; 06421 d++; 06422 if (option_verbose > 2) 06423 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 06424 ast_inet_ntoa(in), atoi(c), atoi(d)); 06425 iax2_poke_peer(p, 0); 06426 p->expiry = atoi(d); 06427 memset(&p->addr, 0, sizeof(p->addr)); 06428 p->addr.sin_family = AF_INET; 06429 p->addr.sin_addr = in; 06430 p->addr.sin_port = htons(atoi(c)); 06431 if (p->expire > -1) { 06432 if (!ast_sched_del(sched, p->expire)) { 06433 p->expire = -1; 06434 peer_unref(p); 06435 } 06436 } 06437 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06438 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06439 if (p->expire == -1) 06440 peer_unref(p); 06441 if (iax2_regfunk) 06442 iax2_regfunk(p->name, 1); 06443 register_peer_exten(p, 1); 06444 } 06445 06446 } 06447 } 06448 } 06449 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 6327 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_strdup, ast_strlen_zero(), ext, iax2_peer::name, iax2_peer::regexten, and S_OR.
Referenced by __expire_registry(), expire_register(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), and update_registry().
06328 { 06329 char multi[256]; 06330 char *stringp, *ext; 06331 if (!ast_strlen_zero(regcontext)) { 06332 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 06333 stringp = multi; 06334 while((ext = strsep(&stringp, "&"))) { 06335 if (onoff) { 06336 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 06337 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 06338 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 06339 } else 06340 ast_context_remove_extension(regcontext, ext, 1, NULL); 06341 } 06342 } 06343 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 5760 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, ies, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax2_peer::secret, and secret.
Referenced by handle_request_register(), and socket_process().
05761 { 05762 char requeststr[256] = ""; 05763 char peer[256] = ""; 05764 char md5secret[256] = ""; 05765 char rsasecret[256] = ""; 05766 char secret[256] = ""; 05767 struct iax2_peer *p = NULL; 05768 struct ast_key *key; 05769 char *keyn; 05770 int x; 05771 int expire = 0; 05772 int res = -1; 05773 05774 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05775 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 05776 if (ies->username) 05777 ast_copy_string(peer, ies->username, sizeof(peer)); 05778 if (ies->password) 05779 ast_copy_string(secret, ies->password, sizeof(secret)); 05780 if (ies->md5_result) 05781 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 05782 if (ies->rsa_result) 05783 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 05784 if (ies->refresh) 05785 expire = ies->refresh; 05786 05787 if (ast_strlen_zero(peer)) { 05788 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 05789 return -1; 05790 } 05791 05792 /* SLD: first call to lookup peer during registration */ 05793 ast_mutex_unlock(&iaxsl[callno]); 05794 p = find_peer(peer, 1); 05795 ast_mutex_lock(&iaxsl[callno]); 05796 if (!p || !iaxs[callno]) { 05797 if (iaxs[callno]) { 05798 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 05799 05800 ast_string_field_set(iaxs[callno], secret, "badsecret"); 05801 05802 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 05803 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 05804 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 05805 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 05806 * to be plaintext, indicating it is an authmethod used by other peers on the system. 05807 * 05808 * If none of these cases exist, res will be returned as 0 without authentication indicating 05809 * an AUTHREQ needs to be sent out. */ 05810 05811 if (ast_strlen_zero(iaxs[callno]->challenge) && 05812 !(!ast_strlen_zero(secret) && plaintext)) { 05813 /* by setting res to 0, an REGAUTH will be sent */ 05814 res = 0; 05815 } 05816 } 05817 if (authdebug && !p) 05818 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05819 05820 goto return_unref; 05821 } 05822 05823 if (!ast_test_flag(p, IAX_DYNAMIC)) { 05824 if (authdebug) 05825 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 05826 goto return_unref; 05827 } 05828 05829 if (!ast_apply_ha(p->ha, sin)) { 05830 if (authdebug) 05831 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05832 goto return_unref; 05833 } 05834 ast_string_field_set(iaxs[callno], secret, p->secret); 05835 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 05836 /* Check secret against what we have on file */ 05837 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05838 if (!ast_strlen_zero(p->inkeys)) { 05839 char tmpkeys[256]; 05840 char *stringp=NULL; 05841 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 05842 stringp=tmpkeys; 05843 keyn = strsep(&stringp, ":"); 05844 while(keyn) { 05845 key = ast_key_get(keyn, AST_KEY_PUBLIC); 05846 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 05847 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05848 break; 05849 } else if (!key) 05850 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 05851 keyn = strsep(&stringp, ":"); 05852 } 05853 if (!keyn) { 05854 if (authdebug) 05855 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 05856 goto return_unref; 05857 } 05858 } else { 05859 if (authdebug) 05860 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 05861 goto return_unref; 05862 } 05863 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 05864 struct MD5Context md5; 05865 unsigned char digest[16]; 05866 char *tmppw, *stringp; 05867 05868 tmppw = ast_strdupa(p->secret); 05869 stringp = tmppw; 05870 while((tmppw = strsep(&stringp, ";"))) { 05871 MD5Init(&md5); 05872 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05873 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05874 MD5Final(digest, &md5); 05875 for (x=0;x<16;x++) 05876 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 05877 if (!strcasecmp(requeststr, md5secret)) 05878 break; 05879 } 05880 if (tmppw) { 05881 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05882 } else { 05883 if (authdebug) 05884 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 05885 goto return_unref; 05886 } 05887 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 05888 /* They've provided a plain text password and we support that */ 05889 if (strcmp(secret, p->secret)) { 05890 if (authdebug) 05891 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 05892 goto return_unref; 05893 } else 05894 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 05895 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 05896 /* if challenge has been sent, but no challenge response if given, reject. */ 05897 goto return_unref; 05898 } 05899 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 05900 05901 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 05902 res = 0; 05903 return_unref: 05904 05905 if (iaxs[callno]) { 05906 ast_string_field_set(iaxs[callno], peer, peer); 05907 05908 /* Choose lowest expiry number */ 05909 if (expire && (expire < iaxs[callno]->expiry)) { 05910 iaxs[callno]->expiry = expire; 05911 } 05912 } 05913 05914 if (p) { 05915 peer_unref(p); 05916 } 05917 return res; 05918 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 6586 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, peer_unref(), and send_command().
Referenced by socket_process().
06587 { 06588 struct iax_ie_data ied; 06589 struct iax2_peer *p; 06590 char challenge[10]; 06591 const char *peer_name; 06592 int sentauthmethod; 06593 06594 peer_name = ast_strdupa(iaxs[callno]->peer); 06595 06596 /* SLD: third call to find_peer in registration */ 06597 ast_mutex_unlock(&iaxsl[callno]); 06598 if ((p = find_peer(peer_name, 1))) { 06599 last_authmethod = p->authmethods; 06600 } 06601 06602 ast_mutex_lock(&iaxsl[callno]); 06603 if (!iaxs[callno]) 06604 goto return_unref; 06605 06606 memset(&ied, 0, sizeof(ied)); 06607 /* The selection of which delayed reject is sent may leak information, 06608 * if it sets a static response. For example, if a host is known to only 06609 * use MD5 authentication, then an RSA response would indicate that the 06610 * peer does not exist, and vice-versa. 06611 * Therefore, we use whatever the last peer used (which may vary over the 06612 * course of a server, which should leak minimal information). */ 06613 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 06614 if (!p) { 06615 iaxs[callno]->authmethods = sentauthmethod; 06616 } 06617 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 06618 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 06619 /* Build the challenge */ 06620 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 06621 ast_string_field_set(iaxs[callno], challenge, challenge); 06622 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 06623 } 06624 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 06625 06626 return_unref: 06627 if (p) { 06628 peer_unref(p); 06629 } 06630 06631 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 06632 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 6634 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_strlen_zero(), authenticate(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, ies, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), and iax2_registry::username.
Referenced by socket_process().
06635 { 06636 struct iax2_registry *reg; 06637 /* Start pessimistic */ 06638 struct iax_ie_data ied; 06639 char peer[256] = ""; 06640 char challenge[256] = ""; 06641 int res; 06642 int authmethods = 0; 06643 if (ies->authmethods) 06644 authmethods = ies->authmethods; 06645 if (ies->username) 06646 ast_copy_string(peer, ies->username, sizeof(peer)); 06647 if (ies->challenge) 06648 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 06649 memset(&ied, 0, sizeof(ied)); 06650 reg = iaxs[callno]->reg; 06651 if (reg) { 06652 if (inaddrcmp(®->addr, sin)) { 06653 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 06654 return -1; 06655 } 06656 if (ast_strlen_zero(reg->secret)) { 06657 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 06658 reg->regstate = REG_STATE_NOAUTH; 06659 return -1; 06660 } 06661 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 06662 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 06663 if (reg->secret[0] == '[') { 06664 char tmpkey[256]; 06665 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 06666 tmpkey[strlen(tmpkey) - 1] = '\0'; 06667 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 06668 } else 06669 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 06670 if (!res) { 06671 reg->regstate = REG_STATE_AUTHSENT; 06672 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 06673 } else 06674 return -1; 06675 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 06676 } else 06677 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 06678 return -1; 06679 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 5013 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_response_register(), iax2_show_registry(), sip_reg_timeout(), and sip_show_registry().
05014 { 05015 switch(regstate) { 05016 case REG_STATE_UNREGISTERED: 05017 return "Unregistered"; 05018 case REG_STATE_REGSENT: 05019 return "Request Sent"; 05020 case REG_STATE_AUTHSENT: 05021 return "Auth. Sent"; 05022 case REG_STATE_REGISTERED: 05023 return "Registered"; 05024 case REG_STATE_REJECTED: 05025 return "Rejected"; 05026 case REG_STATE_TIMEOUT: 05027 return "Timeout"; 05028 case REG_STATE_NOAUTH: 05029 return "No Authentication"; 05030 default: 05031 return "Unknown"; 05032 } 05033 }
static int reload | ( | void | ) | [static] |
Definition at line 10611 of file chan_iax2.c.
References reload_config().
10612 { 10613 return reload_config(); 10614 }
static int reload_config | ( | void | ) | [static] |
Definition at line 10585 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, config, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), poke_all_peers(), prune_peers(), prune_users(), reload_firmware(), and set_config().
10586 { 10587 char *config = "iax.conf"; 10588 struct iax2_registry *reg; 10589 10590 if (set_config(config, 1) > 0) { 10591 prune_peers(); 10592 prune_users(); 10593 AST_LIST_LOCK(®istrations); 10594 AST_LIST_TRAVERSE(®istrations, reg, entry) 10595 iax2_do_register(reg); 10596 AST_LIST_UNLOCK(®istrations); 10597 /* Qualify hosts, too */ 10598 poke_all_peers(); 10599 } 10600 reload_firmware(0); 10601 iax_provision_reload(); 10602 10603 return 0; 10604 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2094 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), iax_firmware::dead, destroy_firmware(), errno, ast_firmware_list::lock, LOG_WARNING, iax_firmware::next, option_verbose, try_firmware(), VERBOSE_PREFIX_2, ast_firmware_list::wares, and waresl.
Referenced by __unload_module(), load_module(), and reload_config().
02095 { 02096 struct iax_firmware *cur, *curl, *curp; 02097 DIR *fwd; 02098 struct dirent *de; 02099 char dir[256]; 02100 char fn[256]; 02101 /* Mark all as dead */ 02102 ast_mutex_lock(&waresl.lock); 02103 cur = waresl.wares; 02104 while(cur) { 02105 cur->dead = 1; 02106 cur = cur->next; 02107 } 02108 02109 /* Now that we've freed them, load the new ones */ 02110 if (!unload) { 02111 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR); 02112 fwd = opendir(dir); 02113 if (fwd) { 02114 while((de = readdir(fwd))) { 02115 if (de->d_name[0] != '.') { 02116 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02117 if (!try_firmware(fn)) { 02118 if (option_verbose > 1) 02119 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name); 02120 } 02121 } 02122 } 02123 closedir(fwd); 02124 } else 02125 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02126 } 02127 02128 /* Clean up leftovers */ 02129 cur = waresl.wares; 02130 curp = NULL; 02131 while(cur) { 02132 curl = cur; 02133 cur = cur->next; 02134 if (curl->dead) { 02135 if (curp) { 02136 curp->next = cur; 02137 } else { 02138 waresl.wares = cur; 02139 } 02140 destroy_firmware(curl); 02141 } else { 02142 curp = cur; 02143 } 02144 } 02145 ast_mutex_unlock(&waresl.lock); 02146 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1309 of file chan_iax2.c.
References ao2_unlink(), ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), and socket_process().
01310 { 01311 if (!pvt->peercallno) { 01312 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01313 return; 01314 } 01315 01316 ao2_unlink(iax_peercallno_pvts, pvt); 01317 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1290 of file chan_iax2.c.
References ao2_unlink(), ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
01291 { 01292 if (!pvt->transfercallno) { 01293 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01294 return; 01295 } 01296 01297 ao2_unlink(iax_transfercallno_pvts, pvt); 01298 }
Definition at line 7138 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, ies, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
07139 { 07140 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 07141 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 07142 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 07143 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 07144 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 07145 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 07146 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 07147 }
static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 9380 of file chan_iax2.c.
References ast_cond_timedwait(), ast_cond_wait(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), option_debug, sched, and sched_lock.
Referenced by start_network_thread().
09381 { 09382 for (;;) { 09383 int ms, count; 09384 struct timespec ts; 09385 09386 pthread_testcancel(); 09387 09388 ast_mutex_lock(&sched_lock); 09389 09390 ms = ast_sched_wait(sched); 09391 09392 if (ms == -1) { 09393 ast_cond_wait(&sched_cond, &sched_lock); 09394 } else { 09395 struct timeval tv; 09396 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(ms, 1000)); 09397 ts.tv_sec = tv.tv_sec; 09398 ts.tv_nsec = tv.tv_usec * 1000; 09399 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 09400 } 09401 09402 ast_mutex_unlock(&sched_lock); 09403 09404 pthread_testcancel(); 09405 09406 count = ast_sched_runq(sched); 09407 if (option_debug && count >= 20) { 09408 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 09409 } 09410 } 09411 09412 return NULL; 09413 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 2817 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_log(), ast_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, LOG_DEBUG, option_debug, ast_channel_tech::properties, sched, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process().
02818 { 02819 int type, len; 02820 int ret; 02821 int needfree = 0; 02822 struct ast_channel *owner = NULL; 02823 struct ast_channel *bridge = NULL; 02824 02825 /* Attempt to recover wrapped timestamps */ 02826 unwrap_timestamp(fr); 02827 02828 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 02829 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 02830 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 02831 else { 02832 #if 0 02833 if (option_debug) 02834 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 02835 #endif 02836 fr->af.delivery = ast_tv(0,0); 02837 } 02838 02839 type = JB_TYPE_CONTROL; 02840 len = 0; 02841 02842 if(fr->af.frametype == AST_FRAME_VOICE) { 02843 type = JB_TYPE_VOICE; 02844 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 02845 } else if(fr->af.frametype == AST_FRAME_CNG) { 02846 type = JB_TYPE_SILENCE; 02847 } 02848 02849 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 02850 if (tsout) 02851 *tsout = fr->ts; 02852 __do_deliver(fr); 02853 return -1; 02854 } 02855 02856 if ((owner = iaxs[fr->callno]->owner)) 02857 bridge = ast_bridged_channel(owner); 02858 02859 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 02860 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 02861 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 02862 jb_frame frame; 02863 02864 /* deliver any frames in the jb */ 02865 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 02866 __do_deliver(frame.data); 02867 /* __do_deliver() can make the call disappear */ 02868 if (!iaxs[fr->callno]) 02869 return -1; 02870 } 02871 02872 jb_reset(iaxs[fr->callno]->jb); 02873 02874 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 02875 02876 /* deliver this frame now */ 02877 if (tsout) 02878 *tsout = fr->ts; 02879 __do_deliver(fr); 02880 return -1; 02881 } 02882 02883 /* insert into jitterbuffer */ 02884 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 02885 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 02886 calc_rxstamp(iaxs[fr->callno],fr->ts)); 02887 if (ret == JB_DROP) { 02888 needfree++; 02889 } else if (ret == JB_SCHED) { 02890 update_jbsched(iaxs[fr->callno]); 02891 } 02892 if (tsout) 02893 *tsout = fr->ts; 02894 if (needfree) { 02895 /* Free our iax frame */ 02896 iax2_frame_free(fr); 02897 return -1; 02898 } 02899 return 0; 02900 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1410 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_registry::callno, iax2_destroy(), LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01411 { 01412 short callno = PTR_TO_CALLNO(vid); 01413 ast_mutex_lock(&iaxsl[callno]); 01414 if (iaxs[callno]) { 01415 if (option_debug) { 01416 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01417 } 01418 iax2_destroy(callno); 01419 } 01420 ast_mutex_unlock(&iaxsl[callno]); 01421 return 0; 01422 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno | |||
) | [static] |
Definition at line 3335 of file chan_iax2.c.
References AST_FRAME_IAX, compress_subclass(), and f.
Referenced by socket_process().
03336 { 03337 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno), 03338 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX, 03339 .csub = compress_subclass(command) }; 03340 03341 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin)); 03342 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5321 of file chan_iax2.c.
References __send_command().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), send_command_locked(), and socket_process().
05322 { 05323 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 05324 }
static int send_command_final | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 5340 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
05341 { 05342 int call_num = i->callno; 05343 /* It is assumed that the callno has already been locked */ 05344 iax2_predestroy(i->callno); 05345 if (!iaxs[call_num]) 05346 return -1; 05347 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 05348 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5350 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
05351 { 05352 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 05353 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 5326 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), iaxs, iaxsl, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
05327 { 05328 int res; 05329 ast_mutex_lock(&iaxsl[callno]); 05330 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 05331 ast_mutex_unlock(&iaxsl[callno]); 05332 return res; 05333 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 5355 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
05356 { 05357 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 05358 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1086 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01087 { 01088 #ifdef SCHED_MULTITHREADED 01089 if (schedule_action(__send_lagrq, data)) 01090 #endif 01091 __send_lagrq(data); 01092 01093 return 0; 01094 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2219 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_inet_ntoa(), ast_log(), iax2_registry::callno, errno, f, handle_error(), iax_showframe(), iaxs, LOG_DEBUG, option_debug, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, and transfer.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
02220 { 02221 int res; 02222 int callno = f->callno; 02223 02224 /* Don't send if there was an error, but return error instead */ 02225 if (!callno || !iaxs[callno] || iaxs[callno]->error) 02226 return -1; 02227 02228 /* Called with iaxsl held */ 02229 if (option_debug > 2 && iaxdebug) 02230 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 02231 if (f->transfer) { 02232 if (iaxdebug) 02233 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02234 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, 02235 sizeof(iaxs[callno]->transfer)); 02236 } else { 02237 if (iaxdebug) 02238 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 02239 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, 02240 sizeof(iaxs[callno]->addr)); 02241 } 02242 if (res < 0) { 02243 if (option_debug && iaxdebug) 02244 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02245 handle_error(); 02246 } else 02247 res = 0; 02248 return res; 02249 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1041 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01042 { 01043 #ifdef SCHED_MULTITHREADED 01044 if (schedule_action(__send_ping, data)) 01045 #endif 01046 __send_ping(data); 01047 01048 return 0; 01049 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 6816 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_inet_ntoa(), ast_log(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, globalflags, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, option_debug, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by timing_read().
06817 { 06818 int res = 0; 06819 struct iax_frame *fr; 06820 struct ast_iax2_meta_hdr *meta; 06821 struct ast_iax2_meta_trunk_hdr *mth; 06822 int calls = 0; 06823 06824 /* Point to frame */ 06825 fr = (struct iax_frame *)tpeer->trunkdata; 06826 /* Point to meta data */ 06827 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 06828 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 06829 if (tpeer->trunkdatalen) { 06830 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 06831 meta->zeros = 0; 06832 meta->metacmd = IAX_META_TRUNK; 06833 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 06834 meta->cmddata = IAX_META_TRUNK_MINI; 06835 else 06836 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 06837 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 06838 /* And the rest of the ast_iax2 header */ 06839 fr->direction = DIRECTION_OUTGRESS; 06840 fr->retrans = -1; 06841 fr->transfer = 0; 06842 /* Any appropriate call will do */ 06843 fr->data = fr->afdata; 06844 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 06845 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 06846 calls = tpeer->calls; 06847 #if 0 06848 if (option_debug) 06849 ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts)); 06850 #endif 06851 /* Reset transmit trunk side data */ 06852 tpeer->trunkdatalen = 0; 06853 tpeer->calls = 0; 06854 } 06855 if (res < 0) 06856 return res; 06857 return calls; 06858 }
static int set_config | ( | char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 10215 of file chan_iax2.c.
References __ao2_link(), ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_config_destroy(), ast_config_load(), ast_context_create(), ast_context_find(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verbose(), build_peer(), build_user(), capability, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_PEER_BUCKETS, ast_variable::name, netsock, ast_variable::next, option_verbose, outsock, peer_unref(), portno, prefs, reg_source_db(), secret, set_config_destroy(), set_timing(), socket_read(), user_unref(), ast_variable::value, and VERBOSE_PREFIX_2.
Referenced by load_module(), reload(), and reload_config().
10216 { 10217 struct ast_config *cfg, *ucfg; 10218 int capability=iax2_capability; 10219 struct ast_variable *v; 10220 char *cat; 10221 const char *utype; 10222 const char *tosval; 10223 int format; 10224 int portno = IAX_DEFAULT_PORTNO; 10225 int x; 10226 struct iax2_user *user; 10227 struct iax2_peer *peer; 10228 struct ast_netsock *ns; 10229 #if 0 10230 static unsigned short int last_port=0; 10231 #endif 10232 10233 cfg = ast_config_load(config_file); 10234 10235 if (!cfg) { 10236 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 10237 return -1; 10238 } 10239 10240 if (reload) { 10241 set_config_destroy(); 10242 } 10243 10244 /* Reset global codec prefs */ 10245 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 10246 10247 /* Reset Global Flags */ 10248 memset(&globalflags, 0, sizeof(globalflags)); 10249 ast_set_flag(&globalflags, IAX_RTUPDATE); 10250 10251 #ifdef SO_NO_CHECK 10252 nochecksums = 0; 10253 #endif 10254 10255 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 10256 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 10257 10258 maxauthreq = 3; 10259 10260 v = ast_variable_browse(cfg, "general"); 10261 10262 /* Seed initial tos value */ 10263 tosval = ast_variable_retrieve(cfg, "general", "tos"); 10264 if (tosval) { 10265 if (ast_str2tos(tosval, &tos)) 10266 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n"); 10267 } 10268 while(v) { 10269 if (!strcasecmp(v->name, "bindport")){ 10270 if (reload) 10271 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 10272 else 10273 portno = atoi(v->value); 10274 } else if (!strcasecmp(v->name, "pingtime")) 10275 ping_time = atoi(v->value); 10276 else if (!strcasecmp(v->name, "iaxthreadcount")) { 10277 if (reload) { 10278 if (atoi(v->value) != iaxthreadcount) 10279 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 10280 } else { 10281 iaxthreadcount = atoi(v->value); 10282 if (iaxthreadcount < 1) { 10283 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 10284 iaxthreadcount = 1; 10285 } else if (iaxthreadcount > 256) { 10286 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 10287 iaxthreadcount = 256; 10288 } 10289 } 10290 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 10291 if (reload) { 10292 AST_LIST_LOCK(&dynamic_list); 10293 iaxmaxthreadcount = atoi(v->value); 10294 AST_LIST_UNLOCK(&dynamic_list); 10295 } else { 10296 iaxmaxthreadcount = atoi(v->value); 10297 if (iaxmaxthreadcount < 0) { 10298 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 10299 iaxmaxthreadcount = 0; 10300 } else if (iaxmaxthreadcount > 256) { 10301 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 10302 iaxmaxthreadcount = 256; 10303 } 10304 } 10305 } else if (!strcasecmp(v->name, "nochecksums")) { 10306 #ifdef SO_NO_CHECK 10307 if (ast_true(v->value)) 10308 nochecksums = 1; 10309 else 10310 nochecksums = 0; 10311 #else 10312 if (ast_true(v->value)) 10313 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 10314 #endif 10315 } 10316 else if (!strcasecmp(v->name, "maxjitterbuffer")) 10317 maxjitterbuffer = atoi(v->value); 10318 else if (!strcasecmp(v->name, "resyncthreshold")) 10319 resyncthreshold = atoi(v->value); 10320 else if (!strcasecmp(v->name, "maxjitterinterps")) 10321 maxjitterinterps = atoi(v->value); 10322 else if (!strcasecmp(v->name, "lagrqtime")) 10323 lagrq_time = atoi(v->value); 10324 else if (!strcasecmp(v->name, "maxregexpire")) 10325 max_reg_expire = atoi(v->value); 10326 else if (!strcasecmp(v->name, "minregexpire")) 10327 min_reg_expire = atoi(v->value); 10328 else if (!strcasecmp(v->name, "bindaddr")) { 10329 if (reload) { 10330 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 10331 } else { 10332 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) { 10333 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 10334 } else { 10335 if (option_verbose > 1) { 10336 if (strchr(v->value, ':')) 10337 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value); 10338 else 10339 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno); 10340 } 10341 if (defaultsockfd < 0) 10342 defaultsockfd = ast_netsock_sockfd(ns); 10343 ast_netsock_unref(ns); 10344 } 10345 } 10346 } else if (!strcasecmp(v->name, "authdebug")) 10347 authdebug = ast_true(v->value); 10348 else if (!strcasecmp(v->name, "encryption")) 10349 iax2_encryption = get_encrypt_methods(v->value); 10350 else if (!strcasecmp(v->name, "notransfer")) { 10351 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n"); 10352 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10353 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER); 10354 } else if (!strcasecmp(v->name, "transfer")) { 10355 if (!strcasecmp(v->value, "mediaonly")) { 10356 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 10357 } else if (ast_true(v->value)) { 10358 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 10359 } else 10360 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 10361 } else if (!strcasecmp(v->name, "codecpriority")) { 10362 if(!strcasecmp(v->value, "caller")) 10363 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 10364 else if(!strcasecmp(v->value, "disabled")) 10365 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10366 else if(!strcasecmp(v->value, "reqonly")) { 10367 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 10368 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 10369 } 10370 } else if (!strcasecmp(v->name, "jitterbuffer")) 10371 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 10372 else if (!strcasecmp(v->name, "forcejitterbuffer")) 10373 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 10374 else if (!strcasecmp(v->name, "delayreject")) 10375 delayreject = ast_true(v->value); 10376 else if (!strcasecmp(v->name, "allowfwdownload")) 10377 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 10378 else if (!strcasecmp(v->name, "rtcachefriends")) 10379 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 10380 else if (!strcasecmp(v->name, "rtignoreregexpire")) 10381 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 10382 else if (!strcasecmp(v->name, "rtupdate")) 10383 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 10384 else if (!strcasecmp(v->name, "trunktimestamps")) 10385 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 10386 else if (!strcasecmp(v->name, "rtautoclear")) { 10387 int i = atoi(v->value); 10388 if(i > 0) 10389 global_rtautoclear = i; 10390 else 10391 i = 0; 10392 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 10393 } else if (!strcasecmp(v->name, "trunkfreq")) { 10394 trunkfreq = atoi(v->value); 10395 if (trunkfreq < 10) 10396 trunkfreq = 10; 10397 } else if (!strcasecmp(v->name, "autokill")) { 10398 if (sscanf(v->value, "%d", &x) == 1) { 10399 if (x >= 0) 10400 autokill = x; 10401 else 10402 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 10403 } else if (ast_true(v->value)) { 10404 autokill = DEFAULT_MAXMS; 10405 } else { 10406 autokill = 0; 10407 } 10408 } else if (!strcasecmp(v->name, "bandwidth")) { 10409 if (!strcasecmp(v->value, "low")) { 10410 capability = IAX_CAPABILITY_LOWBANDWIDTH; 10411 } else if (!strcasecmp(v->value, "medium")) { 10412 capability = IAX_CAPABILITY_MEDBANDWIDTH; 10413 } else if (!strcasecmp(v->value, "high")) { 10414 capability = IAX_CAPABILITY_FULLBANDWIDTH; 10415 } else 10416 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 10417 } else if (!strcasecmp(v->name, "allow")) { 10418 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 10419 } else if (!strcasecmp(v->name, "disallow")) { 10420 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 10421 } else if (!strcasecmp(v->name, "register")) { 10422 iax2_register(v->value, v->lineno); 10423 } else if (!strcasecmp(v->name, "iaxcompat")) { 10424 iaxcompat = ast_true(v->value); 10425 } else if (!strcasecmp(v->name, "regcontext")) { 10426 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 10427 /* Create context if it doesn't exist already */ 10428 if (!ast_context_find(regcontext)) 10429 ast_context_create(NULL, regcontext, "IAX2"); 10430 } else if (!strcasecmp(v->name, "tos")) { 10431 if (ast_str2tos(v->value, &tos)) 10432 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno); 10433 } else if (!strcasecmp(v->name, "accountcode")) { 10434 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 10435 } else if (!strcasecmp(v->name, "mohinterpret")) { 10436 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 10437 } else if (!strcasecmp(v->name, "mohsuggest")) { 10438 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 10439 } else if (!strcasecmp(v->name, "amaflags")) { 10440 format = ast_cdr_amaflags2int(v->value); 10441 if (format < 0) { 10442 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 10443 } else { 10444 amaflags = format; 10445 } 10446 } else if (!strcasecmp(v->name, "language")) { 10447 ast_copy_string(language, v->value, sizeof(language)); 10448 } else if (!strcasecmp(v->name, "maxauthreq")) { 10449 maxauthreq = atoi(v->value); 10450 if (maxauthreq < 0) 10451 maxauthreq = 0; 10452 } else if (!strcasecmp(v->name, "adsi")) { 10453 adsi = ast_true(v->value); 10454 } /*else if (strcasecmp(v->name,"type")) */ 10455 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 10456 v = v->next; 10457 } 10458 10459 if (defaultsockfd < 0) { 10460 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) { 10461 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 10462 } else { 10463 if (option_verbose > 1) 10464 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 10465 defaultsockfd = ast_netsock_sockfd(ns); 10466 ast_netsock_unref(ns); 10467 } 10468 } 10469 if (reload) { 10470 ast_netsock_release(outsock); 10471 outsock = ast_netsock_list_alloc(); 10472 if (!outsock) { 10473 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 10474 return -1; 10475 } 10476 ast_netsock_init(outsock); 10477 } 10478 10479 if (min_reg_expire > max_reg_expire) { 10480 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 10481 min_reg_expire, max_reg_expire, max_reg_expire); 10482 min_reg_expire = max_reg_expire; 10483 } 10484 iax2_capability = capability; 10485 10486 ucfg = ast_config_load("users.conf"); 10487 if (ucfg) { 10488 struct ast_variable *gen; 10489 int genhasiax; 10490 int genregisteriax; 10491 const char *hasiax, *registeriax; 10492 10493 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 10494 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 10495 gen = ast_variable_browse(ucfg, "general"); 10496 cat = ast_category_browse(ucfg, NULL); 10497 while (cat) { 10498 if (strcasecmp(cat, "general")) { 10499 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 10500 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 10501 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 10502 /* Start with general parameters, then specific parameters, user and peer */ 10503 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 10504 if (user) { 10505 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10506 user = user_unref(user); 10507 } 10508 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 10509 if (peer) { 10510 if (ast_test_flag(peer, IAX_DYNAMIC)) 10511 reg_source_db(peer); 10512 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10513 peer = peer_unref(peer); 10514 } 10515 } 10516 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 10517 char tmp[256]; 10518 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 10519 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 10520 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 10521 if (!host) 10522 host = ast_variable_retrieve(ucfg, "general", "host"); 10523 if (!username) 10524 username = ast_variable_retrieve(ucfg, "general", "username"); 10525 if (!secret) 10526 secret = ast_variable_retrieve(ucfg, "general", "secret"); 10527 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 10528 if (!ast_strlen_zero(secret)) 10529 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 10530 else 10531 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 10532 iax2_register(tmp, 0); 10533 } 10534 } 10535 } 10536 cat = ast_category_browse(ucfg, cat); 10537 } 10538 ast_config_destroy(ucfg); 10539 } 10540 10541 cat = ast_category_browse(cfg, NULL); 10542 while(cat) { 10543 if (strcasecmp(cat, "general")) { 10544 utype = ast_variable_retrieve(cfg, cat, "type"); 10545 if (utype) { 10546 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 10547 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 10548 if (user) { 10549 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10550 user = user_unref(user); 10551 } 10552 } 10553 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 10554 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 10555 if (peer) { 10556 if (ast_test_flag(peer, IAX_DYNAMIC)) 10557 reg_source_db(peer); 10558 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0); 10559 peer = peer_unref(peer); 10560 } 10561 } else if (strcasecmp(utype, "user")) { 10562 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 10563 } 10564 } else 10565 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 10566 } 10567 cat = ast_category_browse(cfg, cat); 10568 } 10569 ast_config_destroy(cfg); 10570 set_timing(); 10571 return 1; 10572 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 10199 of file chan_iax2.c.
References ast_clear_flag, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, and IAX_USEJITTERBUF.
Referenced by set_config().
10200 { 10201 strcpy(accountcode, ""); 10202 strcpy(language, ""); 10203 strcpy(mohinterpret, "default"); 10204 strcpy(mohsuggest, ""); 10205 amaflags = 0; 10206 delayreject = 0; 10207 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 10208 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 10209 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 10210 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 10211 delete_users(); 10212 }
static void set_timing | ( | void | ) | [static] |
Definition at line 10184 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by set_config().
10185 { 10186 #ifdef HAVE_DAHDI 10187 int bs = trunkfreq * 8; 10188 if (timingfd > -1) { 10189 if ( 10190 #ifdef DAHDI_TIMERACK 10191 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) && 10192 #endif 10193 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs)) 10194 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n"); 10195 } 10196 #endif 10197 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 765 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_transmit(), and socket_read().
00766 { 00767 ast_mutex_lock(lock); 00768 ast_cond_signal(cond); 00769 ast_mutex_unlock(lock); 00770 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 7290 of file chan_iax2.c.
References ast_async_goto(), ast_best_codec(), ast_bridged_channel(), AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_device_state_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_tvzero(), ast_verbose(), auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax2_peer::callno, iax2_dpcache::callno, iax_frame::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, check_access(), check_provisioning(), cid_num, complete_dpreply(), complete_transfer(), construct_rr(), ast_channel::context, DEADLOCK_AVOIDANCE, decrypt_frame(), dp_lookup(), dpcache_lock, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), find_callno_locked(), find_tpeer(), chan_iax2_pvt::first_iax_message, fix_peerts(), iax2_dpcache::flags, format, chan_iax2_pvt::frames_received, ast_frame::frametype, globalflags, ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, iax_showframe(), IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iaxfrdup2(), iaxq, iaxs, iaxsl, ies, inaddrcmp(), chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event(), iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_PREVENT, option_debug, option_verbose, iax_frame::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), iax2_dpcache::peer, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, ast_iax2_queue::queue, raw_hangup(), REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, iax2_trunk_peer::rxtrunktime, S_OR, save_rr(), sched, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), iax2_peer::smoothing, spawn_dp_lookup(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, iax2_trunk_peer::trunkact, try_transfer(), iax_frame::ts, ast_iax2_mini_hdr::ts, uncompress_subclass(), update_registry(), VERBOSE_PREFIX_3, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames().
07291 { 07292 struct sockaddr_in sin; 07293 int res; 07294 int updatehistory=1; 07295 int new = NEW_PREVENT; 07296 void *ptr; 07297 int dcallno = 0; 07298 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 07299 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 07300 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 07301 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 07302 struct ast_iax2_meta_trunk_hdr *mth; 07303 struct ast_iax2_meta_trunk_entry *mte; 07304 struct ast_iax2_meta_trunk_mini *mtm; 07305 struct iax_frame *fr; 07306 struct iax_frame *cur; 07307 struct ast_frame f = { 0, }; 07308 struct ast_channel *c; 07309 struct iax2_dpcache *dp; 07310 struct iax2_peer *peer; 07311 struct iax2_trunk_peer *tpeer; 07312 struct timeval rxtrunktime; 07313 struct iax_ies ies; 07314 struct iax_ie_data ied0, ied1; 07315 int format; 07316 int fd; 07317 int exists; 07318 int minivid = 0; 07319 unsigned int ts; 07320 char empty[32]=""; /* Safety measure */ 07321 struct iax_frame *duped_fr; 07322 char host_pref_buf[128]; 07323 char caller_pref_buf[128]; 07324 struct ast_codec_pref pref; 07325 char *using_prefs = "mine"; 07326 07327 /* allocate an iax_frame with 4096 bytes of data buffer */ 07328 fr = alloca(sizeof(*fr) + 4096); 07329 memset(fr, 0, sizeof(*fr)); 07330 fr->afdatalen = 4096; /* From alloca() above */ 07331 07332 /* Copy frequently used parameters to the stack */ 07333 res = thread->buf_len; 07334 fd = thread->iofd; 07335 memcpy(&sin, &thread->iosin, sizeof(sin)); 07336 07337 if (res < sizeof(*mh)) { 07338 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh)); 07339 return 1; 07340 } 07341 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 07342 if (res < sizeof(*vh)) { 07343 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07344 return 1; 07345 } 07346 07347 /* This is a video frame, get call number */ 07348 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 07349 minivid = 1; 07350 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) { 07351 unsigned char metatype; 07352 07353 if (res < sizeof(*meta)) { 07354 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07355 return 1; 07356 } 07357 07358 /* This is a meta header */ 07359 switch(meta->metacmd) { 07360 case IAX_META_TRUNK: 07361 if (res < (sizeof(*meta) + sizeof(*mth))) { 07362 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res, 07363 sizeof(*meta) + sizeof(*mth)); 07364 return 1; 07365 } 07366 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 07367 ts = ntohl(mth->ts); 07368 metatype = meta->cmddata; 07369 res -= (sizeof(*meta) + sizeof(*mth)); 07370 ptr = mth->data; 07371 tpeer = find_tpeer(&sin, fd); 07372 if (!tpeer) { 07373 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07374 return 1; 07375 } 07376 tpeer->trunkact = ast_tvnow(); 07377 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 07378 tpeer->rxtrunktime = tpeer->trunkact; 07379 rxtrunktime = tpeer->rxtrunktime; 07380 ast_mutex_unlock(&tpeer->lock); 07381 while(res >= sizeof(*mte)) { 07382 /* Process channels */ 07383 unsigned short callno, trunked_ts, len; 07384 07385 if (metatype == IAX_META_TRUNK_MINI) { 07386 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 07387 ptr += sizeof(*mtm); 07388 res -= sizeof(*mtm); 07389 len = ntohs(mtm->len); 07390 callno = ntohs(mtm->mini.callno); 07391 trunked_ts = ntohs(mtm->mini.ts); 07392 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 07393 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 07394 ptr += sizeof(*mte); 07395 res -= sizeof(*mte); 07396 len = ntohs(mte->len); 07397 callno = ntohs(mte->callno); 07398 trunked_ts = 0; 07399 } else { 07400 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07401 break; 07402 } 07403 /* Stop if we don't have enough data */ 07404 if (len > res) 07405 break; 07406 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0); 07407 if (fr->callno) { 07408 /* If it's a valid call, deliver the contents. If not, we 07409 drop it, since we don't have a scallno to use for an INVAL */ 07410 /* Process as a mini frame */ 07411 memset(&f, 0, sizeof(f)); 07412 f.frametype = AST_FRAME_VOICE; 07413 if (iaxs[fr->callno]) { 07414 if (iaxs[fr->callno]->voiceformat > 0) { 07415 f.subclass = iaxs[fr->callno]->voiceformat; 07416 f.datalen = len; 07417 if (f.datalen >= 0) { 07418 if (f.datalen) 07419 f.data = ptr; 07420 if(trunked_ts) { 07421 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 07422 } else 07423 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 07424 /* Don't pass any packets until we're started */ 07425 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07426 /* Common things */ 07427 f.src = "IAX2"; 07428 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 07429 f.samples = ast_codec_get_samples(&f); 07430 iax_frame_wrap(fr, &f); 07431 duped_fr = iaxfrdup2(fr); 07432 if (duped_fr) { 07433 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts); 07434 } 07435 /* It is possible for the pvt structure to go away after we call schedule_delivery */ 07436 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 07437 iaxs[fr->callno]->last = fr->ts; 07438 #if 1 07439 if (option_debug && iaxdebug) 07440 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07441 #endif 07442 } 07443 } 07444 } else { 07445 ast_log(LOG_WARNING, "Datalen < 0?\n"); 07446 } 07447 } else { 07448 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 07449 iax2_vnak(fr->callno); 07450 } 07451 } 07452 ast_mutex_unlock(&iaxsl[fr->callno]); 07453 } 07454 ptr += len; 07455 res -= len; 07456 } 07457 07458 } 07459 return 1; 07460 } 07461 07462 #ifdef DEBUG_SUPPORT 07463 if (iaxdebug && (res >= sizeof(*fh))) 07464 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 07465 #endif 07466 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07467 if (res < sizeof(*fh)) { 07468 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 07469 return 1; 07470 } 07471 07472 /* Get the destination call number */ 07473 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 07474 /* Retrieve the type and subclass */ 07475 f.frametype = fh->type; 07476 if (f.frametype == AST_FRAME_VIDEO) { 07477 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 07478 } else { 07479 f.subclass = uncompress_subclass(fh->csub); 07480 } 07481 07482 /* Deal with POKE/PONG without allocating a callno */ 07483 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 07484 /* Reply back with a PONG, but don't care about the result. */ 07485 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1); 07486 return 1; 07487 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 07488 /* Ignore */ 07489 return 1; 07490 } 07491 07492 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) || 07493 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) || 07494 (f.subclass == IAX_COMMAND_REGREL))) 07495 new = NEW_ALLOW; 07496 } else { 07497 /* Don't know anything about it yet */ 07498 f.frametype = AST_FRAME_NULL; 07499 f.subclass = 0; 07500 } 07501 07502 if (!fr->callno) { 07503 int check_dcallno = 0; 07504 07505 /* 07506 * We enforce accurate destination call numbers for all full frames except 07507 * LAGRQ and PING commands. This is because older versions of Asterisk 07508 * schedule these commands to get sent very quickly, and they will sometimes 07509 * be sent before they receive the first frame from the other side. When 07510 * that happens, it doesn't contain the destination call number. However, 07511 * not checking it for these frames is safe. 07512 * 07513 * Discussed in the following thread: 07514 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 07515 */ 07516 07517 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07518 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1; 07519 } 07520 07521 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno); 07522 } 07523 07524 if (fr->callno > 0) 07525 ast_mutex_lock(&iaxsl[fr->callno]); 07526 07527 if (!fr->callno || !iaxs[fr->callno]) { 07528 /* A call arrived for a nonexistent destination. Unless it's an "inval" 07529 frame, reply with an inval */ 07530 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07531 /* We can only raw hangup control frames */ 07532 if (((f.subclass != IAX_COMMAND_INVAL) && 07533 (f.subclass != IAX_COMMAND_TXCNT) && 07534 (f.subclass != IAX_COMMAND_TXACC) && 07535 (f.subclass != IAX_COMMAND_FWDOWNL))|| 07536 (f.frametype != AST_FRAME_IAX)) 07537 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 07538 fd); 07539 } 07540 if (fr->callno > 0) 07541 ast_mutex_unlock(&iaxsl[fr->callno]); 07542 return 1; 07543 } 07544 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 07545 if (decrypt_frame(fr->callno, fh, &f, &res)) { 07546 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 07547 ast_mutex_unlock(&iaxsl[fr->callno]); 07548 return 1; 07549 } 07550 #ifdef DEBUG_SUPPORT 07551 else if (iaxdebug) 07552 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 07553 #endif 07554 } 07555 07556 /* count this frame */ 07557 iaxs[fr->callno]->frames_received++; 07558 07559 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 07560 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 07561 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 07562 unsigned short new_peercallno; 07563 07564 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 07565 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 07566 if (iaxs[fr->callno]->peercallno) { 07567 remove_by_peercallno(iaxs[fr->callno]); 07568 } 07569 iaxs[fr->callno]->peercallno = new_peercallno; 07570 store_by_peercallno(iaxs[fr->callno]); 07571 } 07572 } 07573 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 07574 if (option_debug && iaxdebug) 07575 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 07576 /* Check if it's out of order (and not an ACK or INVAL) */ 07577 fr->oseqno = fh->oseqno; 07578 fr->iseqno = fh->iseqno; 07579 fr->ts = ntohl(fh->ts); 07580 #ifdef IAXTESTS 07581 if (test_resync) { 07582 if (option_debug) 07583 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 07584 fr->ts += test_resync; 07585 } 07586 #endif /* IAXTESTS */ 07587 #if 0 07588 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 07589 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 07590 (f.subclass == IAX_COMMAND_NEW || 07591 f.subclass == IAX_COMMAND_AUTHREQ || 07592 f.subclass == IAX_COMMAND_ACCEPT || 07593 f.subclass == IAX_COMMAND_REJECT)) ) ) 07594 #endif 07595 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 07596 updatehistory = 0; 07597 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 07598 (iaxs[fr->callno]->iseqno || 07599 ((f.subclass != IAX_COMMAND_TXCNT) && 07600 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07601 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07602 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07603 (f.subclass != IAX_COMMAND_TXACC)) || 07604 (f.frametype != AST_FRAME_IAX))) { 07605 if ( 07606 ((f.subclass != IAX_COMMAND_ACK) && 07607 (f.subclass != IAX_COMMAND_INVAL) && 07608 (f.subclass != IAX_COMMAND_TXCNT) && 07609 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 07610 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 07611 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 07612 (f.subclass != IAX_COMMAND_TXACC) && 07613 (f.subclass != IAX_COMMAND_VNAK)) || 07614 (f.frametype != AST_FRAME_IAX)) { 07615 /* If it's not an ACK packet, it's out of order. */ 07616 if (option_debug) 07617 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 07618 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 07619 /* Check to see if we need to request retransmission, 07620 * and take sequence number wraparound into account */ 07621 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 07622 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 07623 if ((f.frametype != AST_FRAME_IAX) || 07624 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 07625 if (option_debug) 07626 ast_log(LOG_DEBUG, "Acking anyway\n"); 07627 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 07628 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 07629 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07630 } 07631 } else { 07632 /* Send a VNAK requesting retransmission */ 07633 iax2_vnak(fr->callno); 07634 } 07635 ast_mutex_unlock(&iaxsl[fr->callno]); 07636 return 1; 07637 } 07638 } else { 07639 /* Increment unless it's an ACK or VNAK */ 07640 if (((f.subclass != IAX_COMMAND_ACK) && 07641 (f.subclass != IAX_COMMAND_INVAL) && 07642 (f.subclass != IAX_COMMAND_TXCNT) && 07643 (f.subclass != IAX_COMMAND_TXACC) && 07644 (f.subclass != IAX_COMMAND_VNAK)) || 07645 (f.frametype != AST_FRAME_IAX)) 07646 iaxs[fr->callno]->iseqno++; 07647 } 07648 /* A full frame */ 07649 if (res < sizeof(*fh)) { 07650 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh)); 07651 ast_mutex_unlock(&iaxsl[fr->callno]); 07652 return 1; 07653 } 07654 /* Ensure text frames are NULL-terminated */ 07655 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 07656 if (res < thread->buf_size) 07657 thread->buf[res++] = '\0'; 07658 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 07659 thread->buf[res - 1] = '\0'; 07660 } 07661 f.datalen = res - sizeof(*fh); 07662 07663 /* Handle implicit ACKing unless this is an INVAL, and only if this is 07664 from the real peer, not the transfer peer */ 07665 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07666 ((f.subclass != IAX_COMMAND_INVAL) || 07667 (f.frametype != AST_FRAME_IAX))) { 07668 unsigned char x; 07669 int call_to_destroy; 07670 /* XXX This code is not very efficient. Surely there is a better way which still 07671 properly handles boundary conditions? XXX */ 07672 /* First we have to qualify that the ACKed value is within our window */ 07673 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++) 07674 if (fr->iseqno == x) 07675 break; 07676 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 07677 /* The acknowledgement is within our window. Time to acknowledge everything 07678 that it says to */ 07679 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 07680 /* Ack the packet with the given timestamp */ 07681 if (option_debug && iaxdebug) 07682 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x); 07683 call_to_destroy = 0; 07684 AST_LIST_LOCK(&iaxq.queue); 07685 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07686 /* If it's our call, and our timestamp, mark -1 retries */ 07687 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 07688 cur->retries = -1; 07689 /* Destroy call if this is the end */ 07690 if (cur->final) 07691 call_to_destroy = fr->callno; 07692 } 07693 } 07694 AST_LIST_UNLOCK(&iaxq.queue); 07695 if (call_to_destroy) { 07696 if (iaxdebug && option_debug) 07697 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy); 07698 ast_mutex_lock(&iaxsl[call_to_destroy]); 07699 iax2_destroy(call_to_destroy); 07700 ast_mutex_unlock(&iaxsl[call_to_destroy]); 07701 } 07702 } 07703 /* Note how much we've received acknowledgement for */ 07704 if (iaxs[fr->callno]) 07705 iaxs[fr->callno]->rseqno = fr->iseqno; 07706 else { 07707 /* Stop processing now */ 07708 ast_mutex_unlock(&iaxsl[fr->callno]); 07709 return 1; 07710 } 07711 } else if (option_debug) 07712 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 07713 } 07714 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 07715 ((f.frametype != AST_FRAME_IAX) || 07716 ((f.subclass != IAX_COMMAND_TXACC) && 07717 (f.subclass != IAX_COMMAND_TXCNT)))) { 07718 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 07719 ast_mutex_unlock(&iaxsl[fr->callno]); 07720 return 1; 07721 } 07722 07723 if (f.datalen) { 07724 if (f.frametype == AST_FRAME_IAX) { 07725 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) { 07726 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 07727 ast_mutex_unlock(&iaxsl[fr->callno]); 07728 return 1; 07729 } 07730 f.data = NULL; 07731 f.datalen = 0; 07732 } else 07733 f.data = thread->buf + sizeof(*fh); 07734 } else { 07735 if (f.frametype == AST_FRAME_IAX) 07736 f.data = NULL; 07737 else 07738 f.data = empty; 07739 memset(&ies, 0, sizeof(ies)); 07740 } 07741 07742 /* when we receive the first full frame for a new incoming channel, 07743 it is safe to start the PBX on the channel because we have now 07744 completed a 3-way handshake with the peer */ 07745 if ((f.frametype == AST_FRAME_VOICE) || 07746 (f.frametype == AST_FRAME_VIDEO) || 07747 (f.frametype == AST_FRAME_IAX)) { 07748 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 07749 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 07750 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 07751 ast_mutex_unlock(&iaxsl[fr->callno]); 07752 return 1; 07753 } 07754 } 07755 } 07756 07757 if (f.frametype == AST_FRAME_VOICE) { 07758 if (f.subclass != iaxs[fr->callno]->voiceformat) { 07759 iaxs[fr->callno]->voiceformat = f.subclass; 07760 if (option_debug) 07761 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass); 07762 if (iaxs[fr->callno]->owner) { 07763 int orignative; 07764 retryowner: 07765 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 07766 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 07767 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 07768 } 07769 if (iaxs[fr->callno]) { 07770 if (iaxs[fr->callno]->owner) { 07771 orignative = iaxs[fr->callno]->owner->nativeformats; 07772 iaxs[fr->callno]->owner->nativeformats = f.subclass; 07773 if (iaxs[fr->callno]->owner->readformat) 07774 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 07775 iaxs[fr->callno]->owner->nativeformats = orignative; 07776 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 07777 } 07778 } else { 07779 if (option_debug) 07780 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n"); 07781 ast_mutex_unlock(&iaxsl[fr->callno]); 07782 return 1; 07783 } 07784 } 07785 } 07786 } 07787 if (f.frametype == AST_FRAME_VIDEO) { 07788 if (f.subclass != iaxs[fr->callno]->videoformat) { 07789 if (option_debug) 07790 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 07791 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 07792 } 07793 } 07794 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 07795 if (f.subclass == AST_CONTROL_BUSY) { 07796 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 07797 } else if (f.subclass == AST_CONTROL_CONGESTION) { 07798 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 07799 } 07800 } 07801 if (f.frametype == AST_FRAME_IAX) { 07802 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 07803 /* Handle the IAX pseudo frame itself */ 07804 if (option_debug && iaxdebug) { 07805 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass); 07806 } 07807 07808 /* Update last ts unless the frame's timestamp originated with us. */ 07809 if (iaxs[fr->callno]->last < fr->ts && 07810 f.subclass != IAX_COMMAND_ACK && 07811 f.subclass != IAX_COMMAND_PONG && 07812 f.subclass != IAX_COMMAND_LAGRP) { 07813 iaxs[fr->callno]->last = fr->ts; 07814 if (option_debug && iaxdebug) { 07815 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 07816 } 07817 } 07818 iaxs[fr->callno]->last_iax_message = f.subclass; 07819 if (!iaxs[fr->callno]->first_iax_message) { 07820 iaxs[fr->callno]->first_iax_message = f.subclass; 07821 } 07822 switch(f.subclass) { 07823 case IAX_COMMAND_ACK: 07824 /* Do nothing */ 07825 break; 07826 case IAX_COMMAND_QUELCH: 07827 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07828 /* Generate Manager Hold event, if necessary*/ 07829 if (iaxs[fr->callno]->owner) { 07830 manager_event(EVENT_FLAG_CALL, "Hold", 07831 "Channel: %s\r\n" 07832 "Uniqueid: %s\r\n", 07833 iaxs[fr->callno]->owner->name, 07834 iaxs[fr->callno]->owner->uniqueid); 07835 } 07836 07837 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 07838 if (ies.musiconhold) { 07839 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07840 const char *mohsuggest = iaxs[fr->callno]->mohsuggest; 07841 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 07842 S_OR(mohsuggest, NULL), 07843 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0); 07844 if (!iaxs[fr->callno]) { 07845 ast_mutex_unlock(&iaxsl[fr->callno]); 07846 return 1; 07847 } 07848 } 07849 } 07850 } 07851 break; 07852 case IAX_COMMAND_UNQUELCH: 07853 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 07854 /* Generate Manager Unhold event, if necessary*/ 07855 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 07856 manager_event(EVENT_FLAG_CALL, "Unhold", 07857 "Channel: %s\r\n" 07858 "Uniqueid: %s\r\n", 07859 iaxs[fr->callno]->owner->name, 07860 iaxs[fr->callno]->owner->uniqueid); 07861 } 07862 07863 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 07864 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 07865 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 07866 if (!iaxs[fr->callno]) { 07867 ast_mutex_unlock(&iaxsl[fr->callno]); 07868 return 1; 07869 } 07870 } 07871 } 07872 break; 07873 case IAX_COMMAND_TXACC: 07874 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 07875 /* Ack the packet with the given timestamp */ 07876 AST_LIST_LOCK(&iaxq.queue); 07877 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 07878 /* Cancel any outstanding txcnt's */ 07879 if ((fr->callno == cur->callno) && (cur->transfer)) 07880 cur->retries = -1; 07881 } 07882 AST_LIST_UNLOCK(&iaxq.queue); 07883 memset(&ied1, 0, sizeof(ied1)); 07884 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 07885 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 07886 iaxs[fr->callno]->transferring = TRANSFER_READY; 07887 } 07888 break; 07889 case IAX_COMMAND_NEW: 07890 /* Ignore if it's already up */ 07891 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 07892 break; 07893 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 07894 ast_mutex_unlock(&iaxsl[fr->callno]); 07895 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 07896 ast_mutex_lock(&iaxsl[fr->callno]); 07897 if (!iaxs[fr->callno]) { 07898 ast_mutex_unlock(&iaxsl[fr->callno]); 07899 return 1; 07900 } 07901 } 07902 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 07903 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 07904 int new_callno; 07905 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 07906 fr->callno = new_callno; 07907 } 07908 /* For security, always ack immediately */ 07909 if (delayreject) 07910 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 07911 if (check_access(fr->callno, &sin, &ies)) { 07912 /* They're not allowed on */ 07913 auth_fail(fr->callno, IAX_COMMAND_REJECT); 07914 if (authdebug) 07915 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07916 break; 07917 } 07918 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 07919 const char *context, *exten, *cid_num; 07920 07921 context = ast_strdupa(iaxs[fr->callno]->context); 07922 exten = ast_strdupa(iaxs[fr->callno]->exten); 07923 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 07924 07925 /* This might re-enter the IAX code and need the lock */ 07926 ast_mutex_unlock(&iaxsl[fr->callno]); 07927 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 07928 ast_mutex_lock(&iaxsl[fr->callno]); 07929 07930 if (!iaxs[fr->callno]) { 07931 ast_mutex_unlock(&iaxsl[fr->callno]); 07932 return 1; 07933 } 07934 } else 07935 exists = 0; 07936 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 07937 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 07938 memset(&ied0, 0, sizeof(ied0)); 07939 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 07940 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 07941 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07942 if (!iaxs[fr->callno]) { 07943 ast_mutex_unlock(&iaxsl[fr->callno]); 07944 return 1; 07945 } 07946 if (authdebug) 07947 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 07948 } else { 07949 /* Select an appropriate format */ 07950 07951 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 07952 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 07953 using_prefs = "reqonly"; 07954 } else { 07955 using_prefs = "disabled"; 07956 } 07957 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 07958 memset(&pref, 0, sizeof(pref)); 07959 strcpy(caller_pref_buf, "disabled"); 07960 strcpy(host_pref_buf, "disabled"); 07961 } else { 07962 using_prefs = "mine"; 07963 /* If the information elements are in here... use them */ 07964 if (ies.codec_prefs) 07965 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 07966 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 07967 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 07968 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 07969 pref = iaxs[fr->callno]->rprefs; 07970 using_prefs = "caller"; 07971 } else { 07972 pref = iaxs[fr->callno]->prefs; 07973 } 07974 } else 07975 pref = iaxs[fr->callno]->prefs; 07976 07977 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 07978 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 07979 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 07980 } 07981 if (!format) { 07982 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07983 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 07984 if (!format) { 07985 memset(&ied0, 0, sizeof(ied0)); 07986 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 07987 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 07988 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 07989 if (!iaxs[fr->callno]) { 07990 ast_mutex_unlock(&iaxsl[fr->callno]); 07991 return 1; 07992 } 07993 if (authdebug) { 07994 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 07995 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 07996 else 07997 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 07998 } 07999 } else { 08000 /* Pick one... */ 08001 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08002 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08003 format = 0; 08004 } else { 08005 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08006 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08007 memset(&pref, 0, sizeof(pref)); 08008 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08009 strcpy(caller_pref_buf,"disabled"); 08010 strcpy(host_pref_buf,"disabled"); 08011 } else { 08012 using_prefs = "mine"; 08013 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08014 /* Do the opposite of what we tried above. */ 08015 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08016 pref = iaxs[fr->callno]->prefs; 08017 } else { 08018 pref = iaxs[fr->callno]->rprefs; 08019 using_prefs = "caller"; 08020 } 08021 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08022 08023 } else /* if no codec_prefs IE do it the old way */ 08024 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08025 } 08026 } 08027 08028 if (!format) { 08029 memset(&ied0, 0, sizeof(ied0)); 08030 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08031 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08032 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08033 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08034 if (!iaxs[fr->callno]) { 08035 ast_mutex_unlock(&iaxsl[fr->callno]); 08036 return 1; 08037 } 08038 if (authdebug) 08039 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 08040 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08041 break; 08042 } 08043 } 08044 } 08045 if (format) { 08046 /* No authentication required, let them in */ 08047 memset(&ied1, 0, sizeof(ied1)); 08048 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08049 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08050 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08051 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08052 if (option_verbose > 2) 08053 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n" 08054 "%srequested format = %s,\n" 08055 "%srequested prefs = %s,\n" 08056 "%sactual format = %s,\n" 08057 "%shost prefs = %s,\n" 08058 "%spriority = %s\n", 08059 ast_inet_ntoa(sin.sin_addr), 08060 VERBOSE_PREFIX_4, 08061 ast_getformatname(iaxs[fr->callno]->peerformat), 08062 VERBOSE_PREFIX_4, 08063 caller_pref_buf, 08064 VERBOSE_PREFIX_4, 08065 ast_getformatname(format), 08066 VERBOSE_PREFIX_4, 08067 host_pref_buf, 08068 VERBOSE_PREFIX_4, 08069 using_prefs); 08070 08071 iaxs[fr->callno]->chosenformat = format; 08072 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 08073 } else { 08074 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08075 /* If this is a TBD call, we're ready but now what... */ 08076 if (option_verbose > 2) 08077 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08078 } 08079 } 08080 } 08081 break; 08082 } 08083 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 08084 merge_encryption(iaxs[fr->callno],ies.encmethods); 08085 else 08086 iaxs[fr->callno]->encmethods = 0; 08087 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 08088 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 08089 if (!iaxs[fr->callno]) { 08090 ast_mutex_unlock(&iaxsl[fr->callno]); 08091 return 1; 08092 } 08093 break; 08094 case IAX_COMMAND_DPREQ: 08095 /* Request status in the dialplan */ 08096 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 08097 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 08098 if (iaxcompat) { 08099 /* Spawn a thread for the lookup */ 08100 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 08101 } else { 08102 /* Just look it up */ 08103 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 08104 } 08105 } 08106 break; 08107 case IAX_COMMAND_HANGUP: 08108 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08109 if (option_debug) 08110 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno); 08111 /* Set hangup cause according to remote */ 08112 if (ies.causecode && iaxs[fr->callno]->owner) 08113 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 08114 /* Send ack immediately, before we destroy */ 08115 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08116 iax2_destroy(fr->callno); 08117 break; 08118 case IAX_COMMAND_REJECT: 08119 /* Set hangup cause according to remote */ 08120 if (ies.causecode && iaxs[fr->callno]->owner) 08121 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 08122 08123 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 08124 if (iaxs[fr->callno]->owner && authdebug) 08125 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 08126 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 08127 ies.cause ? ies.cause : "<Unknown>"); 08128 if (option_debug) 08129 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n", 08130 fr->callno); 08131 } 08132 /* Send ack immediately, before we destroy */ 08133 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 08134 fr->ts, NULL, 0, fr->iseqno); 08135 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 08136 iaxs[fr->callno]->error = EPERM; 08137 iax2_destroy(fr->callno); 08138 break; 08139 case IAX_COMMAND_TRANSFER: 08140 { 08141 struct ast_channel *bridged_chan; 08142 08143 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 08144 /* Set BLINDTRANSFER channel variables */ 08145 08146 ast_mutex_unlock(&iaxsl[fr->callno]); 08147 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 08148 ast_mutex_lock(&iaxsl[fr->callno]); 08149 if (!iaxs[fr->callno]) { 08150 ast_mutex_unlock(&iaxsl[fr->callno]); 08151 return 1; 08152 } 08153 08154 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 08155 if (!strcmp(ies.called_number, ast_parking_ext())) { 08156 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 08157 ast_mutex_unlock(&iaxsl[fr->callno]); 08158 if (iax_park(bridged_chan, saved_channel)) { 08159 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 08160 } else { 08161 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name); 08162 } 08163 ast_mutex_lock(&iaxsl[fr->callno]); 08164 } else { 08165 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 08166 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 08167 ies.called_number, iaxs[fr->callno]->context); 08168 else 08169 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 08170 ies.called_number, iaxs[fr->callno]->context); 08171 } 08172 } else 08173 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno); 08174 08175 break; 08176 } 08177 case IAX_COMMAND_ACCEPT: 08178 /* Ignore if call is already up or needs authentication or is a TBD */ 08179 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 08180 break; 08181 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 08182 /* Send ack immediately, before we destroy */ 08183 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08184 iax2_destroy(fr->callno); 08185 break; 08186 } 08187 if (ies.format) { 08188 iaxs[fr->callno]->peerformat = ies.format; 08189 } else { 08190 if (iaxs[fr->callno]->owner) 08191 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 08192 else 08193 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 08194 } 08195 if (option_verbose > 2) 08196 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat)); 08197 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 08198 memset(&ied0, 0, sizeof(ied0)); 08199 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08200 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08201 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08202 if (!iaxs[fr->callno]) { 08203 ast_mutex_unlock(&iaxsl[fr->callno]); 08204 return 1; 08205 } 08206 if (authdebug) 08207 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 08208 } else { 08209 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08210 if (iaxs[fr->callno]->owner) { 08211 /* Switch us to use a compatible format */ 08212 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 08213 if (option_verbose > 2) 08214 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 08215 retryowner2: 08216 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) { 08217 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 08218 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 08219 } 08220 08221 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 08222 /* Setup read/write formats properly. */ 08223 if (iaxs[fr->callno]->owner->writeformat) 08224 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 08225 if (iaxs[fr->callno]->owner->readformat) 08226 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 08227 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock); 08228 } 08229 } 08230 } 08231 if (iaxs[fr->callno]) { 08232 ast_mutex_lock(&dpcache_lock); 08233 dp = iaxs[fr->callno]->dpentries; 08234 while(dp) { 08235 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) { 08236 iax2_dprequest(dp, fr->callno); 08237 } 08238 dp = dp->peer; 08239 } 08240 ast_mutex_unlock(&dpcache_lock); 08241 } 08242 break; 08243 case IAX_COMMAND_POKE: 08244 /* Send back a pong packet with the original timestamp */ 08245 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 08246 if (!iaxs[fr->callno]) { 08247 ast_mutex_unlock(&iaxsl[fr->callno]); 08248 return 1; 08249 } 08250 break; 08251 case IAX_COMMAND_PING: 08252 { 08253 struct iax_ie_data pingied; 08254 construct_rr(iaxs[fr->callno], &pingied); 08255 /* Send back a pong packet with the original timestamp */ 08256 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 08257 } 08258 break; 08259 case IAX_COMMAND_PONG: 08260 /* Calculate ping time */ 08261 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 08262 /* save RR info */ 08263 save_rr(fr, &ies); 08264 08265 if (iaxs[fr->callno]->peerpoke) { 08266 peer = iaxs[fr->callno]->peerpoke; 08267 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 08268 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 08269 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 08270 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08271 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08272 } 08273 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 08274 if (iaxs[fr->callno]->pingtime > peer->maxms) { 08275 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 08276 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 08277 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */ 08278 } 08279 } 08280 peer->lastms = iaxs[fr->callno]->pingtime; 08281 if (peer->smoothing && (peer->lastms > -1)) 08282 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 08283 else if (peer->smoothing && peer->lastms < 0) 08284 peer->historicms = (0 + peer->historicms) / 2; 08285 else 08286 peer->historicms = iaxs[fr->callno]->pingtime; 08287 08288 /* Remove scheduled iax2_poke_noanswer */ 08289 if (peer->pokeexpire > -1) { 08290 if (!ast_sched_del(sched, peer->pokeexpire)) { 08291 peer_unref(peer); 08292 peer->pokeexpire = -1; 08293 } 08294 } 08295 /* Schedule the next cycle */ 08296 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 08297 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 08298 else 08299 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 08300 if (peer->pokeexpire == -1) 08301 peer_unref(peer); 08302 /* and finally send the ack */ 08303 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08304 /* And wrap up the qualify call */ 08305 iax2_destroy(fr->callno); 08306 peer->callno = 0; 08307 if (option_debug) 08308 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 08309 } 08310 break; 08311 case IAX_COMMAND_LAGRQ: 08312 case IAX_COMMAND_LAGRP: 08313 f.src = "LAGRQ"; 08314 f.mallocd = 0; 08315 f.offset = 0; 08316 f.samples = 0; 08317 iax_frame_wrap(fr, &f); 08318 if(f.subclass == IAX_COMMAND_LAGRQ) { 08319 /* Received a LAGRQ - echo back a LAGRP */ 08320 fr->af.subclass = IAX_COMMAND_LAGRP; 08321 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 08322 } else { 08323 /* Received LAGRP in response to our LAGRQ */ 08324 unsigned int ts; 08325 /* This is a reply we've been given, actually measure the difference */ 08326 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 08327 iaxs[fr->callno]->lag = ts - fr->ts; 08328 if (option_debug && iaxdebug) 08329 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n", 08330 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 08331 } 08332 break; 08333 case IAX_COMMAND_AUTHREQ: 08334 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08335 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>"); 08336 break; 08337 } 08338 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 08339 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 08340 .subclass = AST_CONTROL_HANGUP, 08341 }; 08342 ast_log(LOG_WARNING, 08343 "I don't know how to authenticate %s to %s\n", 08344 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 08345 iax2_queue_frame(fr->callno, &hangup_fr); 08346 } 08347 if (!iaxs[fr->callno]) { 08348 ast_mutex_unlock(&iaxsl[fr->callno]); 08349 return 1; 08350 } 08351 break; 08352 case IAX_COMMAND_AUTHREP: 08353 /* For security, always ack immediately */ 08354 if (delayreject) 08355 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08356 /* Ignore once we've started */ 08357 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 08358 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>"); 08359 break; 08360 } 08361 if (authenticate_verify(iaxs[fr->callno], &ies)) { 08362 if (authdebug) 08363 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username); 08364 memset(&ied0, 0, sizeof(ied0)); 08365 auth_fail(fr->callno, IAX_COMMAND_REJECT); 08366 break; 08367 } 08368 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 08369 /* This might re-enter the IAX code and need the lock */ 08370 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 08371 } else 08372 exists = 0; 08373 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 08374 if (authdebug) 08375 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 08376 memset(&ied0, 0, sizeof(ied0)); 08377 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08378 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08379 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08380 if (!iaxs[fr->callno]) { 08381 ast_mutex_unlock(&iaxsl[fr->callno]); 08382 return 1; 08383 } 08384 } else { 08385 /* Select an appropriate format */ 08386 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08387 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08388 using_prefs = "reqonly"; 08389 } else { 08390 using_prefs = "disabled"; 08391 } 08392 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 08393 memset(&pref, 0, sizeof(pref)); 08394 strcpy(caller_pref_buf, "disabled"); 08395 strcpy(host_pref_buf, "disabled"); 08396 } else { 08397 using_prefs = "mine"; 08398 if (ies.codec_prefs) 08399 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 08400 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08401 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08402 pref = iaxs[fr->callno]->rprefs; 08403 using_prefs = "caller"; 08404 } else { 08405 pref = iaxs[fr->callno]->prefs; 08406 } 08407 } else /* if no codec_prefs IE do it the old way */ 08408 pref = iaxs[fr->callno]->prefs; 08409 08410 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 08411 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 08412 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 08413 } 08414 if (!format) { 08415 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08416 if (option_debug) 08417 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); 08418 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 08419 } 08420 if (!format) { 08421 if (authdebug) { 08422 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08423 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 08424 else 08425 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 08426 } 08427 memset(&ied0, 0, sizeof(ied0)); 08428 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08429 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08430 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08431 if (!iaxs[fr->callno]) { 08432 ast_mutex_unlock(&iaxsl[fr->callno]); 08433 return 1; 08434 } 08435 } else { 08436 /* Pick one... */ 08437 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 08438 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 08439 format = 0; 08440 } else { 08441 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 08442 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 08443 memset(&pref, 0, sizeof(pref)); 08444 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 08445 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08446 strcpy(caller_pref_buf,"disabled"); 08447 strcpy(host_pref_buf,"disabled"); 08448 } else { 08449 using_prefs = "mine"; 08450 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 08451 /* Do the opposite of what we tried above. */ 08452 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 08453 pref = iaxs[fr->callno]->prefs; 08454 } else { 08455 pref = iaxs[fr->callno]->rprefs; 08456 using_prefs = "caller"; 08457 } 08458 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 08459 } else /* if no codec_prefs IE do it the old way */ 08460 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08461 } 08462 } 08463 if (!format) { 08464 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 08465 if (authdebug) { 08466 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 08467 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 08468 else 08469 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 08470 } 08471 memset(&ied0, 0, sizeof(ied0)); 08472 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 08473 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 08474 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08475 if (!iaxs[fr->callno]) { 08476 ast_mutex_unlock(&iaxsl[fr->callno]); 08477 return 1; 08478 } 08479 } 08480 } 08481 } 08482 if (format) { 08483 /* Authentication received */ 08484 memset(&ied1, 0, sizeof(ied1)); 08485 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 08486 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 08487 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 08488 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08489 if (option_verbose > 2) 08490 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n" 08491 "%srequested format = %s,\n" 08492 "%srequested prefs = %s,\n" 08493 "%sactual format = %s,\n" 08494 "%shost prefs = %s,\n" 08495 "%spriority = %s\n", 08496 ast_inet_ntoa(sin.sin_addr), 08497 VERBOSE_PREFIX_4, 08498 ast_getformatname(iaxs[fr->callno]->peerformat), 08499 VERBOSE_PREFIX_4, 08500 caller_pref_buf, 08501 VERBOSE_PREFIX_4, 08502 ast_getformatname(format), 08503 VERBOSE_PREFIX_4, 08504 host_pref_buf, 08505 VERBOSE_PREFIX_4, 08506 using_prefs); 08507 08508 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08509 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 08510 iax2_destroy(fr->callno); 08511 } else { 08512 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08513 /* If this is a TBD call, we're ready but now what... */ 08514 if (option_verbose > 2) 08515 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 08516 } 08517 } 08518 } 08519 break; 08520 case IAX_COMMAND_DIAL: 08521 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 08522 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 08523 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 08524 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 08525 if (authdebug) 08526 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context); 08527 memset(&ied0, 0, sizeof(ied0)); 08528 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 08529 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 08530 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08531 if (!iaxs[fr->callno]) { 08532 ast_mutex_unlock(&iaxsl[fr->callno]); 08533 return 1; 08534 } 08535 } else { 08536 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08537 if (option_verbose > 2) 08538 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 08539 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 08540 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 08541 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 08542 iax2_destroy(fr->callno); 08543 } 08544 } 08545 break; 08546 case IAX_COMMAND_INVAL: 08547 iaxs[fr->callno]->error = ENOTCONN; 08548 if (option_debug) 08549 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno); 08550 iax2_destroy(fr->callno); 08551 if (option_debug) 08552 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno); 08553 break; 08554 case IAX_COMMAND_VNAK: 08555 if (option_debug) 08556 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n"); 08557 /* Force retransmission */ 08558 vnak_retransmit(fr->callno, fr->iseqno); 08559 break; 08560 case IAX_COMMAND_REGREQ: 08561 case IAX_COMMAND_REGREL: 08562 /* For security, always ack immediately */ 08563 if (delayreject) 08564 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08565 if (register_verify(fr->callno, &sin, &ies)) { 08566 if (!iaxs[fr->callno]) { 08567 ast_mutex_unlock(&iaxsl[fr->callno]); 08568 return 1; 08569 } 08570 /* Send delayed failure */ 08571 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 08572 break; 08573 } 08574 if (!iaxs[fr->callno]) { 08575 ast_mutex_unlock(&iaxsl[fr->callno]); 08576 return 1; 08577 } 08578 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 08579 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 08580 08581 if (f.subclass == IAX_COMMAND_REGREL) 08582 memset(&sin, 0, sizeof(sin)); 08583 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 08584 ast_log(LOG_WARNING, "Registry error\n"); 08585 if (!iaxs[fr->callno]) { 08586 ast_mutex_unlock(&iaxsl[fr->callno]); 08587 return 1; 08588 } 08589 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 08590 ast_mutex_unlock(&iaxsl[fr->callno]); 08591 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 08592 ast_mutex_lock(&iaxsl[fr->callno]); 08593 if (!iaxs[fr->callno]) { 08594 ast_mutex_unlock(&iaxsl[fr->callno]); 08595 return 1; 08596 } 08597 } 08598 break; 08599 } 08600 registry_authrequest(fr->callno); 08601 if (!iaxs[fr->callno]) { 08602 ast_mutex_unlock(&iaxsl[fr->callno]); 08603 return 1; 08604 } 08605 break; 08606 case IAX_COMMAND_REGACK: 08607 if (iax2_ack_registry(&ies, &sin, fr->callno)) 08608 ast_log(LOG_WARNING, "Registration failure\n"); 08609 /* Send ack immediately, before we destroy */ 08610 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08611 iax2_destroy(fr->callno); 08612 break; 08613 case IAX_COMMAND_REGREJ: 08614 if (iaxs[fr->callno]->reg) { 08615 if (authdebug) { 08616 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr)); 08617 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>"); 08618 } 08619 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 08620 } 08621 /* Send ack immediately, before we destroy */ 08622 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08623 iax2_destroy(fr->callno); 08624 break; 08625 case IAX_COMMAND_REGAUTH: 08626 /* Authentication request */ 08627 if (registry_rerequest(&ies, fr->callno, &sin)) { 08628 memset(&ied0, 0, sizeof(ied0)); 08629 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 08630 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08631 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08632 if (!iaxs[fr->callno]) { 08633 ast_mutex_unlock(&iaxsl[fr->callno]); 08634 return 1; 08635 } 08636 } 08637 break; 08638 case IAX_COMMAND_TXREJ: 08639 iaxs[fr->callno]->transferring = 0; 08640 if (option_verbose > 2) 08641 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08642 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 08643 if (iaxs[fr->callno]->bridgecallno) { 08644 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 08645 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 08646 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 08647 } 08648 } 08649 break; 08650 case IAX_COMMAND_TXREADY: 08651 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 08652 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 08653 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 08654 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 08655 else 08656 iaxs[fr->callno]->transferring = TRANSFER_READY; 08657 if (option_verbose > 2) 08658 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 08659 if (iaxs[fr->callno]->bridgecallno) { 08660 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 08661 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 08662 /* They're both ready, now release them. */ 08663 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 08664 if (option_verbose > 2) 08665 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08666 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08667 08668 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 08669 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 08670 08671 memset(&ied0, 0, sizeof(ied0)); 08672 memset(&ied1, 0, sizeof(ied1)); 08673 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08674 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08675 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 08676 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 08677 } else { 08678 if (option_verbose > 2) 08679 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 08680 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 08681 08682 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 08683 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 08684 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 08685 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 08686 08687 /* Stop doing lag & ping requests */ 08688 stop_stuff(fr->callno); 08689 stop_stuff(iaxs[fr->callno]->bridgecallno); 08690 08691 memset(&ied0, 0, sizeof(ied0)); 08692 memset(&ied1, 0, sizeof(ied1)); 08693 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 08694 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 08695 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 08696 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 08697 } 08698 08699 } 08700 } 08701 } 08702 break; 08703 case IAX_COMMAND_TXREQ: 08704 try_transfer(iaxs[fr->callno], &ies); 08705 break; 08706 case IAX_COMMAND_TXCNT: 08707 if (iaxs[fr->callno]->transferring) 08708 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 08709 break; 08710 case IAX_COMMAND_TXREL: 08711 /* Send ack immediately, rather than waiting until we've changed addresses */ 08712 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08713 complete_transfer(fr->callno, &ies); 08714 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 08715 break; 08716 case IAX_COMMAND_TXMEDIA: 08717 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 08718 AST_LIST_LOCK(&iaxq.queue); 08719 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) { 08720 /* Cancel any outstanding frames and start anew */ 08721 if ((fr->callno == cur->callno) && (cur->transfer)) { 08722 cur->retries = -1; 08723 } 08724 } 08725 AST_LIST_UNLOCK(&iaxq.queue); 08726 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 08727 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 08728 } 08729 break; 08730 case IAX_COMMAND_DPREP: 08731 complete_dpreply(iaxs[fr->callno], &ies); 08732 break; 08733 case IAX_COMMAND_UNSUPPORT: 08734 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 08735 break; 08736 case IAX_COMMAND_FWDOWNL: 08737 /* Firmware download */ 08738 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 08739 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 08740 break; 08741 } 08742 memset(&ied0, 0, sizeof(ied0)); 08743 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 08744 if (res < 0) 08745 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 08746 else if (res > 0) 08747 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08748 else 08749 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 08750 if (!iaxs[fr->callno]) { 08751 ast_mutex_unlock(&iaxsl[fr->callno]); 08752 return 1; 08753 } 08754 break; 08755 default: 08756 if (option_debug) 08757 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 08758 memset(&ied0, 0, sizeof(ied0)); 08759 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 08760 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 08761 } 08762 /* Don't actually pass these frames along */ 08763 if ((f.subclass != IAX_COMMAND_ACK) && 08764 (f.subclass != IAX_COMMAND_TXCNT) && 08765 (f.subclass != IAX_COMMAND_TXACC) && 08766 (f.subclass != IAX_COMMAND_INVAL) && 08767 (f.subclass != IAX_COMMAND_VNAK)) { 08768 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08769 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08770 } 08771 ast_mutex_unlock(&iaxsl[fr->callno]); 08772 return 1; 08773 } 08774 /* Unless this is an ACK or INVAL frame, ack it */ 08775 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 08776 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 08777 } else if (minivid) { 08778 f.frametype = AST_FRAME_VIDEO; 08779 if (iaxs[fr->callno]->videoformat > 0) 08780 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 08781 else { 08782 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 08783 iax2_vnak(fr->callno); 08784 ast_mutex_unlock(&iaxsl[fr->callno]); 08785 return 1; 08786 } 08787 f.datalen = res - sizeof(*vh); 08788 if (f.datalen) 08789 f.data = thread->buf + sizeof(*vh); 08790 else 08791 f.data = NULL; 08792 #ifdef IAXTESTS 08793 if (test_resync) { 08794 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 08795 } else 08796 #endif /* IAXTESTS */ 08797 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 08798 } else { 08799 /* A mini frame */ 08800 f.frametype = AST_FRAME_VOICE; 08801 if (iaxs[fr->callno]->voiceformat > 0) 08802 f.subclass = iaxs[fr->callno]->voiceformat; 08803 else { 08804 if (option_debug) 08805 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n"); 08806 iax2_vnak(fr->callno); 08807 ast_mutex_unlock(&iaxsl[fr->callno]); 08808 return 1; 08809 } 08810 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 08811 if (f.datalen < 0) { 08812 ast_log(LOG_WARNING, "Datalen < 0?\n"); 08813 ast_mutex_unlock(&iaxsl[fr->callno]); 08814 return 1; 08815 } 08816 if (f.datalen) 08817 f.data = thread->buf + sizeof(*mh); 08818 else 08819 f.data = NULL; 08820 #ifdef IAXTESTS 08821 if (test_resync) { 08822 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 08823 } else 08824 #endif /* IAXTESTS */ 08825 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 08826 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 08827 } 08828 /* Don't pass any packets until we're started */ 08829 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 08830 ast_mutex_unlock(&iaxsl[fr->callno]); 08831 return 1; 08832 } 08833 /* Common things */ 08834 f.src = "IAX2"; 08835 f.mallocd = 0; 08836 f.offset = 0; 08837 f.len = 0; 08838 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 08839 f.samples = ast_codec_get_samples(&f); 08840 /* We need to byteswap incoming slinear samples from network byte order */ 08841 if (f.subclass == AST_FORMAT_SLINEAR) 08842 ast_frame_byteswap_be(&f); 08843 } else 08844 f.samples = 0; 08845 iax_frame_wrap(fr, &f); 08846 08847 /* If this is our most recent packet, use it as our basis for timestamping */ 08848 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08849 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 08850 fr->outoforder = 0; 08851 } else { 08852 if (option_debug && iaxdebug && iaxs[fr->callno]) 08853 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); 08854 fr->outoforder = -1; 08855 } 08856 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 08857 duped_fr = iaxfrdup2(fr); 08858 if (duped_fr) { 08859 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 08860 } 08861 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 08862 iaxs[fr->callno]->last = fr->ts; 08863 #if 1 08864 if (option_debug && iaxdebug) 08865 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts); 08866 #endif 08867 } 08868 08869 /* Always run again */ 08870 ast_mutex_unlock(&iaxsl[fr->callno]); 08871 return 1; 08872 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 7212 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::callno, ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::list, LOG_WARNING, option_debug, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, t, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
07213 { 07214 struct iax2_thread *thread; 07215 socklen_t len; 07216 time_t t; 07217 static time_t last_errtime = 0; 07218 struct ast_iax2_full_hdr *fh; 07219 07220 if (!(thread = find_idle_thread())) { 07221 time(&t); 07222 if (t != last_errtime && option_debug) 07223 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n"); 07224 last_errtime = t; 07225 usleep(1); 07226 return 1; 07227 } 07228 07229 len = sizeof(thread->iosin); 07230 thread->iofd = fd; 07231 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 07232 thread->buf_size = sizeof(thread->readbuf); 07233 thread->buf = thread->readbuf; 07234 if (thread->buf_len < 0) { 07235 if (errno != ECONNREFUSED && errno != EAGAIN) 07236 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 07237 handle_error(); 07238 thread->iostate = IAX_IOSTATE_IDLE; 07239 signal_condition(&thread->lock, &thread->cond); 07240 return 1; 07241 } 07242 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 07243 thread->iostate = IAX_IOSTATE_IDLE; 07244 signal_condition(&thread->lock, &thread->cond); 07245 return 1; 07246 } 07247 07248 /* Determine if this frame is a full frame; if so, and any thread is currently 07249 processing a full frame for the same callno from this peer, then drop this 07250 frame (and the peer will retransmit it) */ 07251 fh = (struct ast_iax2_full_hdr *) thread->buf; 07252 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 07253 struct iax2_thread *cur = NULL; 07254 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 07255 07256 AST_LIST_LOCK(&active_list); 07257 AST_LIST_TRAVERSE(&active_list, cur, list) { 07258 if ((cur->ffinfo.callno == callno) && 07259 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 07260 break; 07261 } 07262 if (cur) { 07263 /* we found another thread processing a full frame for this call, 07264 so queue it up for processing later. */ 07265 defer_full_frame(thread, cur); 07266 AST_LIST_UNLOCK(&active_list); 07267 thread->iostate = IAX_IOSTATE_IDLE; 07268 signal_condition(&thread->lock, &thread->cond); 07269 return 1; 07270 } else { 07271 /* this thread is going to process this frame, so mark it */ 07272 thread->ffinfo.callno = callno; 07273 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 07274 thread->ffinfo.type = fh->type; 07275 thread->ffinfo.csub = fh->csub; 07276 } 07277 AST_LIST_UNLOCK(&active_list); 07278 } 07279 07280 /* Mark as ready and send on its way */ 07281 thread->iostate = IAX_IOSTATE_READY; 07282 #ifdef DEBUG_SCHED_MULTITHREAD 07283 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 07284 #endif 07285 signal_condition(&thread->lock, &thread->cond); 07286 07287 return 1; 07288 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 6999 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
07000 { 07001 pthread_t newthread; 07002 struct dpreq_data *dpr; 07003 pthread_attr_t attr; 07004 07005 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 07006 return; 07007 07008 pthread_attr_init(&attr); 07009 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 07010 07011 dpr->callno = callno; 07012 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 07013 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 07014 if (callerid) 07015 dpr->callerid = ast_strdup(callerid); 07016 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) { 07017 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 07018 } 07019 07020 pthread_attr_destroy(&attr); 07021 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 9482 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create, ast_pthread_create_background, ast_verbose(), free, iax2_process_thread(), IAX_TYPE_POOL, iaxthreadcount, iax_frame::list, LOG_WARNING, network_thread(), option_verbose, sched_thread(), thread, and VERBOSE_PREFIX_2.
Referenced by load_module().
09483 { 09484 pthread_attr_t attr; 09485 int threadcount = 0; 09486 int x; 09487 for (x = 0; x < iaxthreadcount; x++) { 09488 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread)); 09489 if (thread) { 09490 thread->type = IAX_TYPE_POOL; 09491 thread->threadnum = ++threadcount; 09492 ast_mutex_init(&thread->lock); 09493 ast_cond_init(&thread->cond, NULL); 09494 pthread_attr_init(&attr); 09495 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 09496 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) { 09497 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 09498 free(thread); 09499 thread = NULL; 09500 } 09501 AST_LIST_LOCK(&idle_list); 09502 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 09503 AST_LIST_UNLOCK(&idle_list); 09504 } 09505 } 09506 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 09507 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 09508 if (option_verbose > 1) 09509 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount); 09510 return 0; 09511 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 6681 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
06682 { 06683 iax2_destroy_helper(iaxs[callno]); 06684 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1299 of file chan_iax2.c.
References ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01300 { 01301 if (!pvt->peercallno) { 01302 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01303 return; 01304 } 01305 01306 ao2_link(iax_peercallno_pvts, pvt); 01307 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1280 of file chan_iax2.c.
References ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01281 { 01282 if (!pvt->transfercallno) { 01283 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01284 return; 01285 } 01286 01287 ao2_link(iax_transfercallno_pvts, pvt); 01288 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 6868 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_inet_ntoa(), AST_IO_PRI, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), free, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_WARNING, MAX_TRUNKDATA, iax2_trunk_peer::next, option_debug, send_trunk(), totalcalls, tpeerlock, tpeers, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
06869 { 06870 char buf[1024]; 06871 int res; 06872 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL; 06873 int processed = 0; 06874 int totalcalls = 0; 06875 #ifdef DAHDI_TIMERACK 06876 int x = 1; 06877 #endif 06878 struct timeval now; 06879 if (iaxtrunkdebug) 06880 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA); 06881 gettimeofday(&now, NULL); 06882 if (events & AST_IO_PRI) { 06883 #ifdef DAHDI_TIMERACK 06884 /* Great, this is a timing interface, just call the ioctl */ 06885 if (ioctl(fd, DAHDI_TIMERACK, &x)) { 06886 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n"); 06887 usleep(1); 06888 return -1; 06889 } 06890 #endif 06891 } else { 06892 /* Read and ignore from the pseudo channel for timing */ 06893 res = read(fd, buf, sizeof(buf)); 06894 if (res < 1) { 06895 ast_log(LOG_WARNING, "Unable to read from timing fd\n"); 06896 return 1; 06897 } 06898 } 06899 /* For each peer that supports trunking... */ 06900 ast_mutex_lock(&tpeerlock); 06901 tpeer = tpeers; 06902 while(tpeer) { 06903 processed++; 06904 res = 0; 06905 ast_mutex_lock(&tpeer->lock); 06906 /* We can drop a single tpeer per pass. That makes all this logic 06907 substantially easier */ 06908 if (!drop && iax2_trunk_expired(tpeer, &now)) { 06909 /* Take it out of the list, but don't free it yet, because it 06910 could be in use */ 06911 if (prev) 06912 prev->next = tpeer->next; 06913 else 06914 tpeers = tpeer->next; 06915 drop = tpeer; 06916 } else { 06917 res = send_trunk(tpeer, &now); 06918 if (iaxtrunkdebug) 06919 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 06920 } 06921 totalcalls += res; 06922 res = 0; 06923 ast_mutex_unlock(&tpeer->lock); 06924 prev = tpeer; 06925 tpeer = tpeer->next; 06926 } 06927 ast_mutex_unlock(&tpeerlock); 06928 if (drop) { 06929 ast_mutex_lock(&drop->lock); 06930 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 06931 because by the time they could get tpeerlock, we've already grabbed it */ 06932 if (option_debug) 06933 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 06934 if (drop->trunkdata) { 06935 free(drop->trunkdata); 06936 drop->trunkdata = NULL; 06937 } 06938 ast_mutex_unlock(&drop->lock); 06939 ast_mutex_destroy(&drop->lock); 06940 free(drop); 06941 06942 } 06943 if (iaxtrunkdebug) 06944 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 06945 iaxtrunkdebug =0; 06946 return 1; 06947 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11457 of file chan_iax2.c.
References chan_iax2_pvt::frames_received, and match().
Referenced by load_module().
11458 { 11459 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 11460 11461 /* The frames_received field is used to hold whether we're matching 11462 * against a full frame or not ... */ 11463 11464 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 11465 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 11466 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 11450 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_module().
11451 { 11452 const struct chan_iax2_pvt *pvt = obj; 11453 11454 return pvt->transfercallno; 11455 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 2205 of file chan_iax2.c.
References ast_log(), errno, f, handle_error(), LOG_DEBUG, and option_debug.
Referenced by send_trunk().
02206 { 02207 int res; 02208 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 02209 sizeof(*sin)); 02210 if (res < 0) { 02211 if (option_debug) 02212 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno)); 02213 handle_error(); 02214 } else 02215 res = 0; 02216 return res; 02217 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 1893 of file chan_iax2.c.
References ast_calloc, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, iax_firmware::next, ast_iax2_firmware_header::version, ast_firmware_list::wares, and waresl.
Referenced by reload_firmware().
01894 { 01895 struct stat stbuf; 01896 struct iax_firmware *cur; 01897 int ifd; 01898 int fd; 01899 int res; 01900 01901 struct ast_iax2_firmware_header *fwh, fwh2; 01902 struct MD5Context md5; 01903 unsigned char sum[16]; 01904 unsigned char buf[1024]; 01905 int len, chunk; 01906 char *s2; 01907 char *last; 01908 s2 = alloca(strlen(s) + 100); 01909 if (!s2) { 01910 ast_log(LOG_WARNING, "Alloca failed!\n"); 01911 return -1; 01912 } 01913 last = strrchr(s, '/'); 01914 if (last) 01915 last++; 01916 else 01917 last = s; 01918 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 01919 res = stat(s, &stbuf); 01920 if (res < 0) { 01921 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 01922 return -1; 01923 } 01924 /* Make sure it's not a directory */ 01925 if (S_ISDIR(stbuf.st_mode)) 01926 return -1; 01927 ifd = open(s, O_RDONLY); 01928 if (ifd < 0) { 01929 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 01930 return -1; 01931 } 01932 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600); 01933 if (fd < 0) { 01934 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 01935 close(ifd); 01936 return -1; 01937 } 01938 /* Unlink our newly created file */ 01939 unlink(s2); 01940 01941 /* Now copy the firmware into it */ 01942 len = stbuf.st_size; 01943 while(len) { 01944 chunk = len; 01945 if (chunk > sizeof(buf)) 01946 chunk = sizeof(buf); 01947 res = read(ifd, buf, chunk); 01948 if (res != chunk) { 01949 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01950 close(ifd); 01951 close(fd); 01952 return -1; 01953 } 01954 res = write(fd, buf, chunk); 01955 if (res != chunk) { 01956 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 01957 close(ifd); 01958 close(fd); 01959 return -1; 01960 } 01961 len -= chunk; 01962 } 01963 close(ifd); 01964 /* Return to the beginning */ 01965 lseek(fd, 0, SEEK_SET); 01966 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 01967 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 01968 close(fd); 01969 return -1; 01970 } 01971 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 01972 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 01973 close(fd); 01974 return -1; 01975 } 01976 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 01977 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 01978 close(fd); 01979 return -1; 01980 } 01981 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 01982 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 01983 close(fd); 01984 return -1; 01985 } 01986 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 01987 if (fwh == MAP_FAILED) { 01988 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 01989 close(fd); 01990 return -1; 01991 } 01992 MD5Init(&md5); 01993 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 01994 MD5Final(sum, &md5); 01995 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 01996 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 01997 munmap((void*)fwh, stbuf.st_size); 01998 close(fd); 01999 return -1; 02000 } 02001 cur = waresl.wares; 02002 while(cur) { 02003 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02004 /* Found a candidate */ 02005 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02006 /* The version we have on loaded is older, load this one instead */ 02007 break; 02008 /* This version is no newer than what we have. Don't worry about it. 02009 We'll consider it a proper load anyhow though */ 02010 munmap((void*)fwh, stbuf.st_size); 02011 close(fd); 02012 return 0; 02013 } 02014 cur = cur->next; 02015 } 02016 if (!cur) { 02017 /* Allocate a new one and link it */ 02018 if ((cur = ast_calloc(1, sizeof(*cur)))) { 02019 cur->fd = -1; 02020 cur->next = waresl.wares; 02021 waresl.wares = cur; 02022 } 02023 } 02024 if (cur) { 02025 if (cur->fwh) { 02026 munmap((void*)cur->fwh, cur->mmaplen); 02027 } 02028 if (cur->fd > -1) 02029 close(cur->fd); 02030 cur->fwh = fwh; 02031 cur->fd = fd; 02032 cur->mmaplen = stbuf.st_size; 02033 cur->dead = 0; 02034 } 02035 return 0; 02036 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 6068 of file chan_iax2.c.
References AST_FRAME_IAX, ast_log(), IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, ies, LOG_WARNING, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
06069 { 06070 int newcall = 0; 06071 char newip[256]; 06072 struct iax_ie_data ied; 06073 struct sockaddr_in new; 06074 06075 06076 memset(&ied, 0, sizeof(ied)); 06077 if (ies->apparent_addr) 06078 bcopy(ies->apparent_addr, &new, sizeof(new)); 06079 if (ies->callno) 06080 newcall = ies->callno; 06081 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 06082 ast_log(LOG_WARNING, "Invalid transfer request\n"); 06083 return -1; 06084 } 06085 pvt->transfercallno = newcall; 06086 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 06087 inet_aton(newip, &pvt->transfer.sin_addr); 06088 pvt->transfer.sin_family = AF_INET; 06089 pvt->transferring = TRANSFER_BEGIN; 06090 pvt->transferid = ies->transferid; 06091 store_by_transfercallno(pvt); 06092 if (ies->transferid) 06093 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 06094 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 06095 return 0; 06096 }
static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1116 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), and socket_process().
01117 { 01118 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01119 if (csub & IAX_FLAG_SC_LOG) { 01120 /* special case for 'compressed' -1 */ 01121 if (csub == 0xff) 01122 return -1; 01123 else 01124 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01125 } 01126 else 01127 return csub; 01128 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 6346 of file chan_iax2.c.
References ao2_unlink(), ast_sched_del(), iax2_peer::expire, peer_unref(), iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
06347 { 06348 if (peer->expire > -1) { 06349 if (!ast_sched_del(sched, peer->expire)) { 06350 peer->expire = -1; 06351 peer_unref(peer); 06352 } 06353 } 06354 06355 if (peer->pokeexpire > -1) { 06356 if (!ast_sched_del(sched, peer->pokeexpire)) { 06357 peer->pokeexpire = -1; 06358 peer_unref(peer); 06359 } 06360 } 06361 06362 ao2_unlink(peers, peer); 06363 }
static int unload_module | ( | void | ) | [static] |
Definition at line 11416 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), and iaxpeer_function.
11417 { 11418 ast_custom_function_unregister(&iaxpeer_function); 11419 return __unload_module(); 11420 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 3699 of file chan_iax2.c.
References ast_mutex_unlock(), and iaxsl.
Referenced by iax2_bridge().
03700 { 03701 ast_mutex_unlock(&iaxsl[callno1]); 03702 ast_mutex_unlock(&iaxsl[callno0]); 03703 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 2672 of file chan_iax2.c.
References iax_frame::af, AST_FRAME_VIDEO, ast_log(), iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, LOG_DEBUG, option_debug, and iax_frame::ts.
Referenced by schedule_delivery().
02673 { 02674 /* Video mini frames only encode the lower 15 bits of the session 02675 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 02676 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 02677 const int lower_mask = (1 << ts_shift) - 1; 02678 const int upper_mask = ~lower_mask; 02679 const int last_upper = iaxs[fr->callno]->last & upper_mask; 02680 02681 if ( (fr->ts & upper_mask) == last_upper ) { 02682 const int x = fr->ts - iaxs[fr->callno]->last; 02683 const int threshold = (ts_shift == 15) ? 25000 : 50000; 02684 02685 if (x < -threshold) { 02686 /* Sudden big jump backwards in timestamp: 02687 What likely happened here is that miniframe timestamp has circled but we haven't 02688 gotten the update from the main packet. We'll just pretend that we did, and 02689 update the timestamp appropriately. */ 02690 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 02691 if (option_debug && iaxdebug) 02692 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n"); 02693 } else if (x > threshold) { 02694 /* Sudden apparent big jump forwards in timestamp: 02695 What's likely happened is this is an old miniframe belonging to the previous 02696 top 15 or 16-bit timestamp that has turned up out of order. 02697 Adjust the timestamp appropriately. */ 02698 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 02699 if (option_debug && iaxdebug) 02700 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n"); 02701 } 02702 } 02703 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2707 of file chan_iax2.c.
References AST_SCHED_DEL, ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_add(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
02708 { 02709 int when; 02710 02711 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 02712 02713 when = jb_next(pvt->jb) - when; 02714 02715 AST_SCHED_DEL(sched, pvt->jbid); 02716 02717 if(when <= 0) { 02718 /* XXX should really just empty until when > 0.. */ 02719 when = 1; 02720 } 02721 02722 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno)); 02723 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1542 of file chan_iax2.c.
References ast_log(), LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01543 { 01544 int max = 1; 01545 int x; 01546 /* XXX Prolly don't need locks here XXX */ 01547 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01548 if (iaxs[x]) 01549 max = x + 1; 01550 } 01551 maxnontrunkcall = max; 01552 if (option_debug && iaxdebug) 01553 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max); 01554 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1319 of file chan_iax2.c.
References ARRAY_LEN, ast_log(), LOG_DEBUG, option_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01320 { 01321 int max = TRUNK_CALL_START; 01322 int x; 01323 01324 /* XXX Prolly don't need locks here XXX */ 01325 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01326 if (iaxs[x]) { 01327 max = x + 1; 01328 } 01329 } 01330 01331 maxtrunkcall = max; 01332 if (option_debug && iaxdebug) 01333 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max); 01334 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 2276 of file chan_iax2.c.
References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
02277 { 02278 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 02279 struct ast_iax2_full_hdr *fh = f->data; 02280 struct ast_frame af; 02281 02282 /* if frame is encrypted. decrypt before updating it. */ 02283 if (f->encmethods) { 02284 decode_frame(&f->mydcx, fh, &af, &f->datalen); 02285 } 02286 /* Mark this as a retransmission */ 02287 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 02288 /* Update iseqno */ 02289 f->iseqno = iaxs[f->callno]->iseqno; 02290 fh->iseqno = f->iseqno; 02291 02292 /* Now re-encrypt the frame */ 02293 if (f->encmethods) { 02294 /* since this is a retransmit frame, create a new random padding 02295 * before re-encrypting. */ 02296 build_rand_pad(f->semirand, sizeof(f->semirand)); 02297 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 02298 } 02299 return 0; 02300 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 6457 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), ast_device_state_changed(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verbose(), iax2_peer::cid_name, iax2_peer::cid_num, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax2_peer::mailbox, manager_event(), iax2_peer::name, option_verbose, peer_ref(), peer_unref(), realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, VERBOSE_PREFIX_3, and iax2_peer::zonetag.
Referenced by socket_process().
06458 { 06459 /* Called from IAX thread only, with proper iaxsl lock */ 06460 struct iax_ie_data ied; 06461 struct iax2_peer *p; 06462 int msgcount; 06463 char data[80]; 06464 int version; 06465 const char *peer_name; 06466 int res = -1; 06467 06468 memset(&ied, 0, sizeof(ied)); 06469 06470 peer_name = ast_strdupa(iaxs[callno]->peer); 06471 06472 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 06473 ast_mutex_unlock(&iaxsl[callno]); 06474 if (!(p = find_peer(peer_name, 1))) { 06475 ast_mutex_lock(&iaxsl[callno]); 06476 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 06477 return -1; 06478 } 06479 ast_mutex_lock(&iaxsl[callno]); 06480 if (!iaxs[callno]) 06481 goto return_unref; 06482 06483 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 06484 if (sin->sin_addr.s_addr) { 06485 time_t nowtime; 06486 time(&nowtime); 06487 realtime_update_peer(peer_name, sin, nowtime); 06488 } else { 06489 realtime_update_peer(peer_name, sin, 0); 06490 } 06491 } 06492 if (inaddrcmp(&p->addr, sin)) { 06493 if (iax2_regfunk) 06494 iax2_regfunk(p->name, 1); 06495 /* Stash the IP address from which they registered */ 06496 memcpy(&p->addr, sin, sizeof(p->addr)); 06497 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 06498 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 06499 ast_db_put("IAX/Registry", p->name, data); 06500 if (option_verbose > 2) 06501 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 06502 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 06503 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 06504 register_peer_exten(p, 1); 06505 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06506 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 06507 if (option_verbose > 2) 06508 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 06509 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 06510 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 06511 register_peer_exten(p, 0); 06512 ast_db_del("IAX/Registry", p->name); 06513 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */ 06514 } 06515 /* Update the host */ 06516 /* Verify that the host is really there */ 06517 iax2_poke_peer(p, callno); 06518 } 06519 06520 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 06521 if (!iaxs[callno]) { 06522 res = -1; 06523 goto return_unref; 06524 } 06525 06526 /* Store socket fd */ 06527 p->sockfd = fd; 06528 /* Setup the expiry */ 06529 if (p->expire > -1) { 06530 if (!ast_sched_del(sched, p->expire)) { 06531 p->expire = -1; 06532 peer_unref(p); 06533 } 06534 } 06535 /* treat an unspecified refresh interval as the minimum */ 06536 if (!refresh) 06537 refresh = min_reg_expire; 06538 if (refresh > max_reg_expire) { 06539 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06540 p->name, max_reg_expire, refresh); 06541 p->expiry = max_reg_expire; 06542 } else if (refresh < min_reg_expire) { 06543 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 06544 p->name, min_reg_expire, refresh); 06545 p->expiry = min_reg_expire; 06546 } else { 06547 p->expiry = refresh; 06548 } 06549 if (p->expiry && sin->sin_addr.s_addr) { 06550 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 06551 if (p->expire == -1) 06552 peer_unref(p); 06553 } 06554 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 06555 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 06556 if (sin->sin_addr.s_addr) { 06557 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 06558 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 06559 if (!ast_strlen_zero(p->mailbox)) { 06560 int new, old; 06561 ast_app_inboxcount(p->mailbox, &new, &old); 06562 if (new > 255) 06563 new = 255; 06564 if (old > 255) 06565 old = 255; 06566 msgcount = (old << 8) | new; 06567 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 06568 } 06569 if (ast_test_flag(p, IAX_HASCALLERID)) { 06570 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 06571 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 06572 } 06573 } 06574 version = iax_check_version(devtype); 06575 if (version) 06576 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 06577 06578 res = 0; 06579 06580 return_unref: 06581 peer_unref(p); 06582 06583 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 06584 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1163 of file chan_iax2.c.
References iax2_user::name.
Referenced by load_module().
01164 { 01165 struct iax2_user *user = obj, *user2 = arg; 01166 01167 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01168 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 10119 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
10120 { 10121 struct iax2_user *user = obj; 10122 10123 ast_set_flag(user, IAX_DELME); 10124 10125 return 0; 10126 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 9880 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
09881 { 09882 struct iax2_user *user = obj; 09883 09884 ast_free_ha(user->ha); 09885 free_context(user->contexts); 09886 if(user->vars) { 09887 ast_variables_destroy(user->vars); 09888 user->vars = NULL; 09889 } 09890 ast_string_field_free_memory(user); 09891 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1153 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_module().
01154 { 01155 const struct iax2_user *user = obj; 01156 01157 return ast_str_hash(user->name); 01158 }
Definition at line 1211 of file chan_iax2.c.
References ao2_ref().
01212 { 01213 ao2_ref(user, +1); 01214 return user; 01215 }
Definition at line 1217 of file chan_iax2.c.
References ao2_ref().
Referenced by authenticate_request(), authenticate_verify(), build_user(), check_access(), iax2_destroy_helper(), iax2_prune_realtime(), iax2_show_users(), prune_users(), and set_config().
01218 { 01219 ao2_ref(user, -1); 01220 return NULL; 01221 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 6782 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, f, iaxq, iaxs, iax_frame::list, ast_iax2_queue::queue, and send_packet().
Referenced by socket_process().
06783 { 06784 struct iax_frame *f; 06785 06786 AST_LIST_LOCK(&iaxq.queue); 06787 AST_LIST_TRAVERSE(&iaxq.queue, f, list) { 06788 /* Send a copy immediately */ 06789 if ((f->callno == callno) && iaxs[f->callno] && 06790 ((unsigned char ) (f->oseqno - last) < 128) && 06791 (f->retries >= 0)) { 06792 send_packet(f); 06793 } 06794 } 06795 AST_LIST_UNLOCK(&iaxq.queue); 06796 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3597 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
03598 { 03599 unsigned short callno = pvt->callno; 03600 03601 if (!pvt->peercallno) { 03602 /* We don't know the remote side's call number, yet. :( */ 03603 int count = 10; 03604 while (count-- && pvt && !pvt->peercallno) { 03605 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03606 pvt = iaxs[callno]; 03607 } 03608 if (!pvt->peercallno) { 03609 return -1; 03610 } 03611 } 03612 03613 return 0; 03614 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 11592 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 216 of file chan_iax2.c.
Referenced by __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial(), build_device(), build_gateway(), check_user_full(), dahdi_new(), disa_exec(), features_call(), gtalk_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
int amaflags = 0 [static] |
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 11592 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 155 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 156 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
struct ast_cli_entry cli_iax2_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "jb", "debug", NULL }, iax2_do_jb_debug, NULL, NULL }
Definition at line 11211 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "debug", NULL }, iax2_no_debug, NULL, NULL }
Definition at line 11216 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_jb_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "jb", "debug", NULL }, iax2_no_jb_debug, NULL, NULL }
Definition at line 11226 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated [static] |
Initial value:
{ { "iax2", "no", "trunk", "debug", NULL }, iax2_no_trunk_debug, NULL, NULL }
Definition at line 11221 of file chan_iax2.c.
struct ast_cli_entry cli_iax2_trunk_debug_deprecated [static] |
Initial value:
{ { "iax2", "trunk", "debug", NULL }, iax2_do_trunk_debug, NULL, NULL }
Definition at line 11206 of file chan_iax2.c.
char context[80] = "default" [static] |
Definition at line 142 of file chan_iax2.c.
char debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb\n" " Enables jitterbuffer debugging information\n"
Definition at line 11180 of file chan_iax2.c.
char debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 set debug trunk\n" " Requests current status of IAX trunking\n"
Definition at line 11172 of file chan_iax2.c.
char debug_usage[] [static] |
Initial value:
"Usage: iax2 set debug\n" " Enables dumping of IAX packets for debugging purposes\n"
Definition at line 11164 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 173 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 221 of file chan_iax2.c.
struct iax2_dpcache * dpcache [static] |
Referenced by find_cache(), and iax2_show_cache().
ast_mutex_t dpcache_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 697 of file chan_iax2.c.
Referenced by complete_dpreply(), find_cache(), iax2_canmatch(), iax2_exec(), iax2_exists(), iax2_matchmore(), iax2_show_cache(), and socket_process().
int global_rtautoclear = 120 [static] |
Definition at line 274 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 224 of file chan_iax2.c.
Referenced by __expire_registry(), __find_callno(), aji_create_client(), aji_load_config(), build_peer(), build_user(), find_or_create(), find_user(), find_user_realtime(), forward_message(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), notify_new_message(), populate_defaults(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 202 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 222 of file chan_iax2.c.
enum { ... } iax2_flags |
int(*) iax2_regfunk(const char *username, int onoff) = NULL |
Definition at line 175 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
char iax2_reload_usage[] [static] |
Initial value:
"Usage: iax2 reload\n" " Reloads IAX configuration from iax.conf\n"
Definition at line 11122 of file chan_iax2.c.
enum { ... } iax2_state |
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 886 of file chan_iax2.c.
Referenced by __unload_module(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
char iax2_test_losspct_usage[] [static] |
Initial value:
"Usage: iax2 test losspct <percentage>\n" " For testing, throws away <percentage> percent of incoming packets\n"
Definition at line 11188 of file chan_iax2.c.
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 833 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_peercallno(), and store_by_peercallno().
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
*
Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 840 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_module(), remove_by_transfercallno(), and store_by_transfercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 454 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 157 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 204 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 160 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 162 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 452 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_iax2_queue iaxq [static] |
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
Definition at line 820 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __get_from_jb(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), iax2_ack_registry(), iax2_bridge(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_start_transfer(), iax2_vnak(), iax2_write(), iax_frame_subclass2str(), iax_showframe(), load_module(), network_thread(), register_verify(), registry_authrequest(), registry_rerequest(), save_rr(), schedule_delivery(), send_command_final(), send_command_locked(), send_packet(), socket_process(), stop_stuff(), unwrap_timestamp(), update_packet(), update_registry(), vnak_retransmit(), and wait_for_peercallno().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
Definition at line 821 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __get_from_jb(), __iax2_poke_noanswer(), __unload_module(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), iax2_bridge(), iax2_call(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_poke_peer(), iax2_provision(), iax2_request(), iax2_setoption(), iax2_show_channels(), iax2_write(), load_module(), lock_both(), network_thread(), peer_destructor(), register_verify(), registry_authrequest(), send_command_locked(), socket_process(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 450 of file chan_iax2.c.
Referenced by iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 206 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 199 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 150 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 144 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 158 of file chan_iax2.c.
Definition at line 822 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 167 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 148 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 147 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 151 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 153 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 847 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 846 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 166 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 217 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 218 of file chan_iax2.c.
Referenced by build_device(), check_user_full(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 171 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 226 of file chan_iax2.c.
char no_debug_jb_usage[] [static] |
Initial value:
"Usage: iax2 set debug jb off\n" " Disables jitterbuffer debugging information\n"
Definition at line 11184 of file chan_iax2.c.
char no_debug_trunk_usage[] [static] |
Initial value:
"Usage: iax2 set debug trunk off\n" " Requests current status of IAX trunking\n"
Definition at line 11176 of file chan_iax2.c.
char no_debug_usage[] [static] |
Initial value:
"Usage: iax2 set debug off\n" " Disables dumping of IAX packets for debugging purposes\n"
Definition at line 11168 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 172 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
Definition at line 9122 of file chan_iax2.c.
char* pdescrip [static] |
Initial value:
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 9124 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 658 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 149 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 138 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codec_setpref(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
char prune_realtime_usage[] [static] |
Initial value:
"Usage: iax2 prune realtime [<peername>|all]\n" " Prunes object(s) from the cache\n"
Definition at line 11118 of file chan_iax2.c.
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 9123 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 145 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 152 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 200 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 229 of file chan_iax2.c.
ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
Definition at line 228 of file chan_iax2.c.
Referenced by __unload_module(), iax2_sched_add(), iax2_transmit(), and sched_thread().
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 227 of file chan_iax2.c.
char show_cache_usage[] [static] |
Initial value:
"Usage: iax2 show cache\n" " Display currently cached IAX Dialplan results.\n"
Definition at line 11110 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 11138 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 11156 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 11142 of file chan_iax2.c.
char show_peer_usage[] [static] |
Initial value:
"Usage: iax2 show peer <name>\n" " Display details on specific IAX peer\n"
Definition at line 11114 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 11150 of file chan_iax2.c.
char show_prov_usage[] [static] |
Definition at line 11126 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 11160 of file chan_iax2.c.
char show_stats_usage[] [static] |
Initial value:
"Usage: iax2 show stats\n" " Display statistics on IAX channel driver.\n"
Definition at line 11106 of file chan_iax2.c.
char show_threads_usage[] [static] |
Initial value:
"Usage: iax2 show threads\n" " Lists status of IAX helper threads\n"
Definition at line 11146 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 11133 of file chan_iax2.c.
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 140 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 208 of file chan_iax2.c.
int timingfd = -1 [static] |
Definition at line 169 of file chan_iax2.c.
unsigned int tos = 0 [static] |
Definition at line 164 of file chan_iax2.c.
ast_mutex_t tpeerlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
struct iax2_trunk_peer * tpeers [static] |
Referenced by find_tpeer(), and timing_read().
int trunkfreq = 20 [static] |
Definition at line 154 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 661 of file chan_iax2.c.
struct ast_firmware_list waresl [static] |
Referenced by __unload_module(), iax2_show_firmware(), iax_check_version(), iax_firmware_append(), load_module(), reload_firmware(), and try_firmware().