2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Implementation of Inter-Asterisk eXchange Version 2
23 * \author Mark Spencer <markster@digium.com>
26 * \arg \ref Config_iax
28 * \ingroup channel_drivers
37 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
41 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/ip.h>
50 #include <sys/signal.h>
62 #include <sys/ioctl.h>
63 #include <zaptel/zaptel.h>
66 #include "asterisk/lock.h"
67 #include "asterisk/frame.h"
68 #include "asterisk/channel.h"
69 #include "asterisk/logger.h"
70 #include "asterisk/module.h"
71 #include "asterisk/pbx.h"
72 #include "asterisk/sched.h"
73 #include "asterisk/io.h"
74 #include "asterisk/config.h"
75 #include "asterisk/options.h"
76 #include "asterisk/cli.h"
77 #include "asterisk/translate.h"
78 #include "asterisk/md5.h"
79 #include "asterisk/cdr.h"
80 #include "asterisk/crypto.h"
81 #include "asterisk/acl.h"
82 #include "asterisk/manager.h"
83 #include "asterisk/callerid.h"
84 #include "asterisk/app.h"
85 #include "asterisk/astdb.h"
86 #include "asterisk/musiconhold.h"
87 #include "asterisk/features.h"
88 #include "asterisk/utils.h"
89 #include "asterisk/causes.h"
90 #include "asterisk/localtime.h"
91 #include "asterisk/aes.h"
92 #include "asterisk/dnsmgr.h"
93 #include "asterisk/devicestate.h"
94 #include "asterisk/netsock.h"
95 #include "asterisk/stringfields.h"
96 #include "asterisk/linkedlists.h"
99 #include "iax2-parser.h"
100 #include "iax2-provision.h"
101 #include "jitterbuf.h"
103 /* Define SCHED_MULTITHREADED to run the scheduler in a special
104 multithreaded mode. */
105 #define SCHED_MULTITHREADED
107 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
108 thread is actually doing. */
109 #define DEBUG_SCHED_MULTITHREAD
111 #ifndef IPTOS_MINCOST
112 #define IPTOS_MINCOST 0x02
116 static int nochecksums
= 0;
120 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
121 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
123 #define DEFAULT_THREAD_COUNT 10
124 #define DEFAULT_MAX_THREAD_COUNT 100
125 #define DEFAULT_RETRY_TIME 1000
126 #define MEMORY_SIZE 100
127 #define DEFAULT_DROP 3
128 /* Flag to use with trunk calls, keeping these calls high up. It halves our effective use
129 but keeps the division between trunked and non-trunked better. */
130 #define TRUNK_CALL_START 0x4000
132 #define DEBUG_SUPPORT
134 #define MIN_REUSE_TIME 60 /* Don't reuse a call number within 60 seconds */
136 /* Sample over last 100 units to determine historic jitter */
139 static struct ast_codec_pref prefs
;
141 static const char tdesc
[] = "Inter Asterisk eXchange Driver (Ver 2)";
143 static char context
[80] = "default";
145 static char language
[MAX_LANGUAGE
] = "";
146 static char regcontext
[AST_MAX_CONTEXT
] = "";
148 static int maxauthreq
= 3;
149 static int max_retries
= 4;
150 static int ping_time
= 20;
151 static int lagrq_time
= 10;
152 static int maxtrunkcall
= TRUNK_CALL_START
;
153 static int maxnontrunkcall
= 1;
154 static int maxjitterbuffer
=1000;
155 static int resyncthreshold
=1000;
156 static int maxjitterinterps
=10;
157 static int trunkfreq
= 20;
158 static int authdebug
= 1;
159 static int autokill
= 0;
160 static int iaxcompat
= 0;
162 static int iaxdefaultdpcache
=10 * 60; /* Cache dialplan entries for 10 minutes by default */
164 static int iaxdefaulttimeout
= 5; /* Default to wait no more than 5 seconds for a reply to come back */
166 static unsigned int tos
= 0;
168 static int min_reg_expire
;
169 static int max_reg_expire
;
171 static int timingfd
= -1; /* Timing file descriptor */
173 static struct ast_netsock_list
*netsock
;
174 static int defaultsockfd
= -1;
176 static int usecnt
= 0;
178 int (*iax2_regfunk
)(const char *username
, int onoff
) = NULL
;
181 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
183 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
184 ~AST_FORMAT_SLINEAR & \
188 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
190 ~AST_FORMAT_G726_AAL2 & \
193 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
197 #define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
198 #define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */
199 #define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */
201 static struct io_context
*io
;
202 static struct sched_context
*sched
;
204 static int iax2_capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
206 static int iaxdebug
= 0;
208 static int iaxtrunkdebug
= 0;
210 static int test_losspct
= 0;
212 static int test_late
= 0;
213 static int test_resync
= 0;
214 static int test_jit
= 0;
215 static int test_jitpct
= 0;
216 #endif /* IAXTESTS */
218 static char accountcode
[AST_MAX_ACCOUNT_CODE
];
219 static char mohinterpret
[MAX_MUSICCLASS
];
220 static char mohsuggest
[MAX_MUSICCLASS
];
221 static int amaflags
= 0;
223 static int delayreject
= 0;
224 static int iax2_encryption
= 0;
226 static struct ast_flags globalflags
= { 0 };
228 static pthread_t netthreadid
= AST_PTHREADT_NULL
;
229 static pthread_t schedthreadid
= AST_PTHREADT_NULL
;
230 AST_MUTEX_DEFINE_STATIC(sched_lock
);
231 static int sched_halt
= 0;
232 static ast_cond_t sched_cond
;
235 IAX_STATE_STARTED
= (1 << 0),
236 IAX_STATE_AUTHENTICATED
= (1 << 1),
237 IAX_STATE_TBD
= (1 << 2),
238 IAX_STATE_UNCHANGED
= (1 << 3),
241 struct iax2_context
{
242 char context
[AST_MAX_CONTEXT
];
243 struct iax2_context
*next
;
247 IAX_HASCALLERID
= (1 << 0), /*!< CallerID has been specified */
248 IAX_DELME
= (1 << 1), /*!< Needs to be deleted */
249 IAX_TEMPONLY
= (1 << 2), /*!< Temporary (realtime) */
250 IAX_TRUNK
= (1 << 3), /*!< Treat as a trunk */
251 IAX_NOTRANSFER
= (1 << 4), /*!< Don't native bridge */
252 IAX_USEJITTERBUF
= (1 << 5), /*!< Use jitter buffer */
253 IAX_DYNAMIC
= (1 << 6), /*!< dynamic peer */
254 IAX_SENDANI
= (1 << 7), /*!< Send ANI along with CallerID */
255 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
256 IAX_ALREADYGONE
= (1 << 9), /*!< Already disconnected */
257 IAX_PROVISION
= (1 << 10), /*!< This is a provisioning request */
258 IAX_QUELCH
= (1 << 11), /*!< Whether or not we quelch audio */
259 IAX_ENCRYPTED
= (1 << 12), /*!< Whether we should assume encrypted tx/rx */
260 IAX_KEYPOPULATED
= (1 << 13), /*!< Whether we have a key populated */
261 IAX_CODEC_USER_FIRST
= (1 << 14), /*!< are we willing to let the other guy choose the codec? */
262 IAX_CODEC_NOPREFS
= (1 << 15), /*!< Force old behaviour by turning off prefs */
263 IAX_CODEC_NOCAP
= (1 << 16), /*!< only consider requested format and ignore capabilities*/
264 IAX_RTCACHEFRIENDS
= (1 << 17), /*!< let realtime stay till your reload */
265 IAX_RTUPDATE
= (1 << 18), /*!< Send a realtime update */
266 IAX_RTAUTOCLEAR
= (1 << 19), /*!< erase me on expire */
267 IAX_FORCEJITTERBUF
= (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
268 IAX_RTIGNOREREGEXPIRE
= (1 << 21), /*!< When using realtime, ignore registration expiration */
269 IAX_TRUNKTIMESTAMPS
= (1 << 22), /*!< Send trunk timestamps */
270 IAX_TRANSFERMEDIA
= (1 << 23), /*!< When doing IAX2 transfers, transfer media only */
271 IAX_MAXAUTHREQ
= (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */
274 static int global_rtautoclear
= 120;
276 static int reload_config(void);
277 static int iax2_reload(int fd
, int argc
, char *argv
[]);
281 AST_DECLARE_STRING_FIELDS(
282 AST_STRING_FIELD(name
);
283 AST_STRING_FIELD(secret
);
284 AST_STRING_FIELD(dbsecret
);
285 AST_STRING_FIELD(accountcode
);
286 AST_STRING_FIELD(mohinterpret
);
287 AST_STRING_FIELD(mohsuggest
);
288 AST_STRING_FIELD(inkeys
); /*!< Key(s) this user can use to authenticate to us */
289 AST_STRING_FIELD(language
);
290 AST_STRING_FIELD(cid_num
);
291 AST_STRING_FIELD(cid_name
);
300 int maxauthreq
; /*!< Maximum allowed outstanding AUTHREQs */
301 int curauthreq
; /*!< Current number of outstanding AUTHREQs */
302 struct ast_codec_pref prefs
;
304 struct iax2_context
*contexts
;
305 struct ast_variable
*vars
;
306 AST_LIST_ENTRY(iax2_user
) entry
;
310 AST_DECLARE_STRING_FIELDS(
311 AST_STRING_FIELD(name
);
312 AST_STRING_FIELD(username
);
313 AST_STRING_FIELD(secret
);
314 AST_STRING_FIELD(dbsecret
);
315 AST_STRING_FIELD(outkey
); /*!< What key we use to talk to this peer */
317 AST_STRING_FIELD(regexten
); /*!< Extension to register (if regcontext is used) */
318 AST_STRING_FIELD(context
); /*!< For transfers only */
319 AST_STRING_FIELD(peercontext
); /*!< Context to pass to peer */
320 AST_STRING_FIELD(mailbox
); /*!< Mailbox */
321 AST_STRING_FIELD(mohinterpret
);
322 AST_STRING_FIELD(mohsuggest
);
323 AST_STRING_FIELD(inkeys
); /*!< Key(s) this peer can use to authenticate to us */
324 /* Suggested caller id if registering */
325 AST_STRING_FIELD(cid_num
); /*!< Default context (for transfer really) */
326 AST_STRING_FIELD(cid_name
); /*!< Default context (for transfer really) */
327 AST_STRING_FIELD(zonetag
); /*!< Time Zone */
329 struct ast_codec_pref prefs
;
330 struct ast_dnsmgr_entry
*dnsmgr
; /*!< DNS refresh manager */
331 struct sockaddr_in addr
;
333 int sockfd
; /*!< Socket to use for transmission */
338 /* Dynamic Registration fields */
339 struct sockaddr_in defaddr
; /*!< Default address if there is one */
340 int authmethods
; /*!< Authentication methods (IAX_AUTH_*) */
341 int encmethods
; /*!< Encryption methods (IAX_ENCRYPT_*) */
343 int expire
; /*!< Schedule entry for expiry */
344 int expiry
; /*!< How soon to expire */
345 int capability
; /*!< Capability */
348 int callno
; /*!< Call number of POKE request */
349 int pokeexpire
; /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
350 int lastms
; /*!< How long last response took (in ms), or -1 for no response */
351 int maxms
; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
353 int pokefreqok
; /*!< How often to check if the host is up */
354 int pokefreqnotok
; /*!< How often to check when the host has been determined to be down */
355 int historicms
; /*!< How long recent average responses took */
356 int smoothing
; /*!< Sample over how many units to determine historic ms */
359 AST_LIST_ENTRY(iax2_peer
) entry
;
362 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
364 static struct iax2_trunk_peer
{
367 struct sockaddr_in addr
;
368 struct timeval txtrunktime
; /*!< Transmit trunktime */
369 struct timeval rxtrunktime
; /*!< Receive trunktime */
370 struct timeval lasttxtime
; /*!< Last transmitted trunktime */
371 struct timeval trunkact
; /*!< Last trunk activity */
372 unsigned int lastsent
; /*!< Last sent time */
373 /* Trunk data and length */
374 unsigned char *trunkdata
;
375 unsigned int trunkdatalen
;
376 unsigned int trunkdataalloc
;
377 struct iax2_trunk_peer
*next
;
382 AST_MUTEX_DEFINE_STATIC(tpeerlock
);
384 struct iax_firmware
{
385 struct iax_firmware
*next
;
389 struct ast_iax2_firmware_header
*fwh
;
394 REG_STATE_UNREGISTERED
= 0,
397 REG_STATE_REGISTERED
,
403 enum iax_transfer_state
{
408 TRANSFER_PASSTHROUGH
,
412 TRANSFER_MPASSTHROUGH
,
417 struct iax2_registry
{
418 struct sockaddr_in addr
; /*!< Who we connect to for registration purposes */
420 char secret
[80]; /*!< Password or key name in []'s */
422 int expire
; /*!< Sched ID of expiration */
423 int refresh
; /*!< How often to refresh */
424 enum iax_reg_state regstate
;
425 int messages
; /*!< Message count, low 8 bits = new, high 8 bits = old */
426 int callno
; /*!< Associated call number if applicable */
427 struct sockaddr_in us
; /*!< Who the server thinks we are */
428 struct iax2_registry
*next
;
429 struct ast_dnsmgr_entry
*dnsmgr
; /*!< DNS refresh manager */
432 static struct iax2_registry
*registrations
;
434 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
435 #define MIN_RETRY_TIME 100
436 #define MAX_RETRY_TIME 10000
438 #define MAX_JITTER_BUFFER 50
439 #define MIN_JITTER_BUFFER 10
441 #define DEFAULT_TRUNKDATA 640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
442 #define MAX_TRUNKDATA 640 * 200 /*!< 40ms, uncompressed linear * 200 channels */
444 #define MAX_TIMESTAMP_SKEW 160 /*!< maximum difference between actual and predicted ts for sending */
446 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
447 #define TS_GAP_FOR_JB_RESYNC 5000
449 static int iaxthreadcount
= DEFAULT_THREAD_COUNT
;
450 static int iaxmaxthreadcount
= DEFAULT_MAX_THREAD_COUNT
;
451 static int iaxdynamicthreadcount
= 0;
463 struct chan_iax2_pvt
{
464 /*! Socket to send/receive on for this call */
466 /*! Last received voice format */
468 /*! Last received video format */
470 /*! Last sent voice format */
472 /*! Last sent video format */
474 /*! What we are capable of sending */
476 /*! Last received timestamp */
478 /*! Last sent timestamp - never send the same timestamp twice in a single call */
479 unsigned int lastsent
;
480 /*! Next outgoing timestamp if everything is good */
481 unsigned int nextpred
;
482 /*! True if the last voice we transmitted was not silence/CNG */
485 unsigned int pingtime
;
486 /*! Max time for initial response */
489 struct sockaddr_in addr
;
490 /*! Actual used codec preferences */
491 struct ast_codec_pref prefs
;
492 /*! Requested codec preferences */
493 struct ast_codec_pref rprefs
;
494 /*! Our call number */
495 unsigned short callno
;
497 unsigned short peercallno
;
498 /*! Peer selected format */
500 /*! Peer capability */
502 /*! timeval that we base our transmission on */
503 struct timeval offset
;
504 /*! timeval that we base our delivery on */
505 struct timeval rxcore
;
506 /*! The jitterbuffer */
508 /*! active jb read scheduler id */
512 /*! Error, as discovered by the manager */
514 /*! Owner if we have one */
515 struct ast_channel
*owner
;
516 /*! What's our state? */
517 struct ast_flags state
;
518 /*! Expiry (optional) */
520 /*! Next outgoing sequence number */
521 unsigned char oseqno
;
522 /*! Next sequence number they have not yet acknowledged */
523 unsigned char rseqno
;
524 /*! Next incoming sequence number */
525 unsigned char iseqno
;
526 /*! Last incoming sequence number we have acknowledged */
527 unsigned char aseqno
;
529 AST_DECLARE_STRING_FIELDS(
531 AST_STRING_FIELD(peer
);
532 /*! Default Context */
533 AST_STRING_FIELD(context
);
534 /*! Caller ID if available */
535 AST_STRING_FIELD(cid_num
);
536 AST_STRING_FIELD(cid_name
);
537 /*! Hidden Caller ID (i.e. ANI) if appropriate */
538 AST_STRING_FIELD(ani
);
540 AST_STRING_FIELD(dnid
);
542 AST_STRING_FIELD(rdnis
);
543 /*! Requested Extension */
544 AST_STRING_FIELD(exten
);
545 /*! Expected Username */
546 AST_STRING_FIELD(username
);
547 /*! Expected Secret */
548 AST_STRING_FIELD(secret
);
550 AST_STRING_FIELD(challenge
);
551 /*! Public keys permitted keys for incoming authentication */
552 AST_STRING_FIELD(inkeys
);
553 /*! Private key for outgoing authentication */
554 AST_STRING_FIELD(outkey
);
555 /*! Preferred language */
556 AST_STRING_FIELD(language
);
557 /*! Hostname/peername for naming purposes */
558 AST_STRING_FIELD(host
);
560 AST_STRING_FIELD(dproot
);
561 AST_STRING_FIELD(accountcode
);
562 AST_STRING_FIELD(mohinterpret
);
563 AST_STRING_FIELD(mohsuggest
);
566 /*! permitted authentication methods */
568 /*! permitted encryption methods */
570 /*! Encryption AES-128 Key */
572 /*! Decryption AES-128 Key */
574 /*! 32 bytes of semi-random data */
575 unsigned char semirand
[32];
576 /*! Associated registry */
577 struct iax2_registry
*reg
;
578 /*! Associated peer for poking */
579 struct iax2_peer
*peerpoke
;
584 /*! Transferring status */
585 enum iax_transfer_state transferring
;
586 /*! Transfer identifier */
588 /*! Who we are IAX transfering to */
589 struct sockaddr_in transfer
;
590 /*! What's the new call number for the transfer */
591 unsigned short transfercallno
;
592 /*! Transfer decrypt AES-128 Key */
593 aes_encrypt_ctx tdcx
;
595 /*! Status of knowledge of peer ADSI capability */
598 /*! Who we are bridged to */
599 unsigned short bridgecallno
;
601 int pingid
; /*!< Transmit PING request */
602 int lagid
; /*!< Retransmit lag request */
603 int autoid
; /*!< Auto hangup for Dialplan requestor */
604 int authid
; /*!< Authentication rejection ID */
605 int authfail
; /*!< Reason to report failure */
606 int initid
; /*!< Initial peer auto-congest ID (based on qualified peers) */
611 struct iax2_dpcache
*dpentries
;
612 struct ast_variable
*vars
;
613 /*! last received remote rr */
614 struct iax_rr remote_rr
;
615 /*! Current base time: (just for stats) */
617 /*! Dropped frame count: (just for stats) */
619 /*! received frame count: (just for stats) */
623 static struct ast_iax2_queue
{
624 AST_LIST_HEAD(, iax_frame
) queue
;
627 .queue
= AST_LIST_HEAD_INIT_VALUE
630 static AST_LIST_HEAD_STATIC(users
, iax2_user
);
632 static AST_LIST_HEAD_STATIC(peers
, iax2_peer
);
634 static struct ast_firmware_list
{
635 struct iax_firmware
*wares
;
639 /*! Extension exists */
640 #define CACHE_FLAG_EXISTS (1 << 0)
641 /*! Extension is nonexistent */
642 #define CACHE_FLAG_NONEXISTENT (1 << 1)
643 /*! Extension can exist */
644 #define CACHE_FLAG_CANEXIST (1 << 2)
645 /*! Waiting to hear back response */
646 #define CACHE_FLAG_PENDING (1 << 3)
648 #define CACHE_FLAG_TIMEOUT (1 << 4)
649 /*! Request transmitted */
650 #define CACHE_FLAG_TRANSMITTED (1 << 5)
652 #define CACHE_FLAG_UNKNOWN (1 << 6)
654 #define CACHE_FLAG_MATCHMORE (1 << 7)
656 static struct iax2_dpcache
{
657 char peercontext
[AST_MAX_CONTEXT
];
658 char exten
[AST_MAX_EXTENSION
];
660 struct timeval expiry
;
662 unsigned short callno
;
664 struct iax2_dpcache
*next
;
665 struct iax2_dpcache
*peer
; /*!< For linking in peers */
668 AST_MUTEX_DEFINE_STATIC(dpcache_lock
);
670 static void reg_source_db(struct iax2_peer
*p
);
671 static struct iax2_peer
*realtime_peer(const char *peername
, struct sockaddr_in
*sin
);
673 static void destroy_peer(struct iax2_peer
*peer
);
674 static int ast_cli_netstats(struct mansession
*s
, int fd
, int limit_fmt
);
676 #define IAX_IOSTATE_IDLE 0
677 #define IAX_IOSTATE_READY 1
678 #define IAX_IOSTATE_PROCESSING 2
679 #define IAX_IOSTATE_SCHEDREADY 3
681 #define IAX_TYPE_POOL 1
682 #define IAX_TYPE_DYNAMIC 2
685 AST_LIST_ENTRY(iax2_thread
) list
;
688 #ifdef SCHED_MULTITHREADED
689 void (*schedfunc
)(void *);
692 #ifdef DEBUG_SCHED_MULTITHREAD
699 struct sockaddr_in iosin
;
700 unsigned char buf
[4096];
709 static AST_LIST_HEAD_STATIC(idle_list
, iax2_thread
);
710 static AST_LIST_HEAD_STATIC(active_list
, iax2_thread
);
711 static AST_LIST_HEAD_STATIC(dynamic_list
, iax2_thread
);
713 static void *iax2_process_thread(void *data
);
715 static void signal_condition(ast_mutex_t
*lock
, ast_cond_t
*cond
)
717 ast_mutex_lock(lock
);
718 ast_cond_signal(cond
);
719 ast_mutex_unlock(lock
);
722 static void iax_debug_output(const char *data
)
725 ast_verbose("%s", data
);
728 static void iax_error_output(const char *data
)
730 ast_log(LOG_WARNING
, "%s", data
);
733 static void jb_error_output(const char *fmt
, ...)
739 vsnprintf(buf
, 1024, fmt
, args
);
742 ast_log(LOG_ERROR
, buf
);
745 static void jb_warning_output(const char *fmt
, ...)
751 vsnprintf(buf
, 1024, fmt
, args
);
754 ast_log(LOG_WARNING
, buf
);
757 static void jb_debug_output(const char *fmt
, ...)
763 vsnprintf(buf
, 1024, fmt
, args
);
769 /* XXX We probably should use a mutex when working with this XXX */
770 static struct chan_iax2_pvt
*iaxs
[IAX_MAX_CALLS
];
771 static ast_mutex_t iaxsl
[IAX_MAX_CALLS
];
772 static struct timeval lastused
[IAX_MAX_CALLS
];
774 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
);
775 static int expire_registry(void *data
);
776 static int iax2_answer(struct ast_channel
*c
);
777 static int iax2_call(struct ast_channel
*c
, char *dest
, int timeout
);
778 static int iax2_devicestate(void *data
);
779 static int iax2_digit_begin(struct ast_channel
*c
, char digit
);
780 static int iax2_digit_end(struct ast_channel
*c
, char digit
);
781 static int iax2_do_register(struct iax2_registry
*reg
);
782 static int iax2_fixup(struct ast_channel
*oldchannel
, struct ast_channel
*newchan
);
783 static int iax2_hangup(struct ast_channel
*c
);
784 static int iax2_indicate(struct ast_channel
*c
, int condition
, const void *data
, size_t datalen
);
785 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
);
786 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
);
787 static int iax2_send(struct chan_iax2_pvt
*pvt
, struct ast_frame
*f
, unsigned int ts
, int seqno
, int now
, int transfer
, int final
);
788 static int iax2_sendhtml(struct ast_channel
*c
, int subclass
, const char *data
, int datalen
);
789 static int iax2_sendimage(struct ast_channel
*c
, struct ast_frame
*img
);
790 static int iax2_sendtext(struct ast_channel
*c
, const char *text
);
791 static int iax2_setoption(struct ast_channel
*c
, int option
, void *data
, int datalen
);
792 static int iax2_transfer(struct ast_channel
*c
, const char *dest
);
793 static int iax2_write(struct ast_channel
*c
, struct ast_frame
*f
);
794 static int send_command(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int, int);
795 static int send_command_final(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int, int);
796 static int send_command_immediate(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int, int);
797 static int send_command_locked(unsigned short callno
, char, int, unsigned int, const unsigned char *, int, int);
798 static int send_command_transfer(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int);
799 static struct ast_channel
*iax2_request(const char *type
, int format
, void *data
, int *cause
);
800 static struct ast_frame
*iax2_read(struct ast_channel
*c
);
801 static struct iax2_peer
*build_peer(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
);
802 static struct iax2_user
*build_user(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
);
803 static void realtime_update_peer(const char *peername
, struct sockaddr_in
*sin
, time_t regtime
);
804 static void destroy_user(struct iax2_user
*user
);
805 static void prune_peers(void);
807 static const struct ast_channel_tech iax2_tech
= {
809 .description
= tdesc
,
810 .capabilities
= IAX_CAPABILITY_FULLBANDWIDTH
,
811 .properties
= AST_CHAN_TP_WANTSJITTER
,
812 .requester
= iax2_request
,
813 .devicestate
= iax2_devicestate
,
814 .send_digit_begin
= iax2_digit_begin
,
815 .send_digit_end
= iax2_digit_end
,
816 .send_text
= iax2_sendtext
,
817 .send_image
= iax2_sendimage
,
818 .send_html
= iax2_sendhtml
,
820 .hangup
= iax2_hangup
,
821 .answer
= iax2_answer
,
824 .write_video
= iax2_write
,
825 .indicate
= iax2_indicate
,
826 .setoption
= iax2_setoption
,
827 .bridge
= iax2_bridge
,
828 .transfer
= iax2_transfer
,
832 static struct iax2_thread
*find_idle_thread(void)
834 struct iax2_thread
*thread
= NULL
;
836 /* Pop the head of the list off */
837 AST_LIST_LOCK(&idle_list
);
838 thread
= AST_LIST_REMOVE_HEAD(&idle_list
, list
);
839 AST_LIST_UNLOCK(&idle_list
);
841 /* If no idle thread is available from the regular list, try dynamic */
842 if (thread
== NULL
) {
843 AST_LIST_LOCK(&dynamic_list
);
844 thread
= AST_LIST_FIRST(&dynamic_list
);
845 if (thread
!= NULL
) {
846 AST_LIST_REMOVE(&dynamic_list
, thread
, list
);
848 /* Make sure we absolutely have a thread... if not, try to make one if allowed */
849 if (thread
== NULL
&& iaxmaxthreadcount
> iaxdynamicthreadcount
) {
850 /* We need to MAKE a thread! */
851 thread
= ast_calloc(1, sizeof(*thread
));
852 if (thread
!= NULL
) {
853 thread
->threadnum
= iaxdynamicthreadcount
;
854 thread
->type
= IAX_TYPE_DYNAMIC
;
855 ast_mutex_init(&thread
->lock
);
856 ast_cond_init(&thread
->cond
, NULL
);
857 if (ast_pthread_create(&thread
->threadid
, NULL
, iax2_process_thread
, thread
)) {
861 /* All went well and the thread is up, so increment our count */
862 iaxdynamicthreadcount
++;
866 AST_LIST_UNLOCK(&dynamic_list
);
872 #ifdef SCHED_MULTITHREADED
873 static int __schedule_action(void (*func
)(void *data
), void *data
, const char *funcname
)
875 struct iax2_thread
*thread
= NULL
;
876 static time_t lasterror
;
879 thread
= find_idle_thread();
881 if (thread
!= NULL
) {
882 thread
->schedfunc
= func
;
883 thread
->scheddata
= data
;
884 thread
->iostate
= IAX_IOSTATE_SCHEDREADY
;
885 #ifdef DEBUG_SCHED_MULTITHREAD
886 ast_copy_string(thread
->curfunc
, funcname
, sizeof(thread
->curfunc
));
888 signal_condition(&thread
->lock
, &thread
->cond
);
893 ast_log(LOG_NOTICE
, "Out of idle IAX2 threads for scheduling!\n");
898 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
901 static void __send_ping(void *data
)
903 int callno
= (long)data
;
904 send_command_locked(callno
, AST_FRAME_IAX
, IAX_COMMAND_PING
, 0, NULL
, 0, -1);
907 static int send_ping(void *data
)
909 int callno
= (long)data
;
911 #ifdef SCHED_MULTITHREADED
912 if (schedule_action(__send_ping
, data
))
921 static int get_encrypt_methods(const char *s
)
924 if (!strcasecmp(s
, "aes128"))
925 e
= IAX_ENCRYPT_AES128
;
926 else if (ast_true(s
))
927 e
= IAX_ENCRYPT_AES128
;
933 static void __send_lagrq(void *data
)
935 int callno
= (long)data
;
936 /* Ping only if it's real not if it's bridged */
937 send_command_locked(callno
, AST_FRAME_IAX
, IAX_COMMAND_LAGRQ
, 0, NULL
, 0, -1);
940 static int send_lagrq(void *data
)
942 int callno
= (long)data
;
944 #ifdef SCHED_MULTITHREADED
945 if (schedule_action(__send_lagrq
, data
))
954 static unsigned char compress_subclass(int subclass
)
958 /* If it's 128 or smaller, just return it */
959 if (subclass
< IAX_FLAG_SC_LOG
)
961 /* Otherwise find its power */
962 for (x
= 0; x
< IAX_MAX_SHIFT
; x
++) {
963 if (subclass
& (1 << x
)) {
965 ast_log(LOG_WARNING
, "Can't compress subclass %d\n", subclass
);
971 return power
| IAX_FLAG_SC_LOG
;
974 static int uncompress_subclass(unsigned char csub
)
976 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
977 if (csub
& IAX_FLAG_SC_LOG
) {
978 /* special case for 'compressed' -1 */
982 return 1 << (csub
& ~IAX_FLAG_SC_LOG
& IAX_MAX_SHIFT
);
988 static struct iax2_peer
*find_peer(const char *name
, int realtime
)
990 struct iax2_peer
*peer
= NULL
;
992 /* Grab peer from linked list */
993 AST_LIST_LOCK(&peers
);
994 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
995 if (!strcasecmp(peer
->name
, name
)) {
999 AST_LIST_UNLOCK(&peers
);
1001 /* Now go for realtime if applicable */
1002 if(!peer
&& realtime
)
1003 peer
= realtime_peer(name
, NULL
);
1007 static int iax2_getpeername(struct sockaddr_in sin
, char *host
, int len
, int lockpeer
)
1009 struct iax2_peer
*peer
= NULL
;
1013 AST_LIST_LOCK(&peers
);
1014 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
1015 if ((peer
->addr
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
) &&
1016 (peer
->addr
.sin_port
== sin
.sin_port
)) {
1017 ast_copy_string(host
, peer
->name
, len
);
1023 AST_LIST_UNLOCK(&peers
);
1025 peer
= realtime_peer(NULL
, &sin
);
1027 ast_copy_string(host
, peer
->name
, len
);
1028 if (ast_test_flag(peer
, IAX_TEMPONLY
))
1037 static struct chan_iax2_pvt
*new_iax(struct sockaddr_in
*sin
, int lockpeer
, const char *host
)
1039 struct chan_iax2_pvt
*tmp
;
1042 if (!(tmp
= ast_calloc(1, sizeof(*tmp
))))
1045 if (ast_string_field_init(tmp
, 32)) {
1053 tmp
->peercallno
= 0;
1054 tmp
->transfercallno
= 0;
1055 tmp
->bridgecallno
= 0;
1062 ast_string_field_set(tmp
,exten
, "s");
1063 ast_string_field_set(tmp
,host
, host
);
1067 jbconf
.max_jitterbuf
= maxjitterbuffer
;
1068 jbconf
.resync_threshold
= resyncthreshold
;
1069 jbconf
.max_contig_interp
= maxjitterinterps
;
1070 jb_setconf(tmp
->jb
,&jbconf
);
1075 static struct iax_frame
*iaxfrdup2(struct iax_frame
*fr
)
1077 struct iax_frame
*new = iax_frame_new(DIRECTION_INGRESS
, fr
->af
.datalen
);
1079 size_t mallocd_datalen
= new->mallocd_datalen
;
1080 memcpy(new, fr
, sizeof(*new));
1081 iax_frame_wrap(new, &fr
->af
);
1082 new->mallocd_datalen
= mallocd_datalen
;
1085 new->direction
= DIRECTION_INGRESS
;
1091 #define NEW_PREVENT 0
1095 static int match(struct sockaddr_in
*sin
, unsigned short callno
, unsigned short dcallno
, struct chan_iax2_pvt
*cur
)
1097 if ((cur
->addr
.sin_addr
.s_addr
== sin
->sin_addr
.s_addr
) &&
1098 (cur
->addr
.sin_port
== sin
->sin_port
)) {
1099 /* This is the main host */
1100 if ((cur
->peercallno
== callno
) ||
1101 ((dcallno
== cur
->callno
) && !cur
->peercallno
)) {
1102 /* That's us. Be sure we keep track of the peer call number */
1106 if ((cur
->transfer
.sin_addr
.s_addr
== sin
->sin_addr
.s_addr
) &&
1107 (cur
->transfer
.sin_port
== sin
->sin_port
) && (cur
->transferring
)) {
1108 /* We're transferring */
1109 if (dcallno
== cur
->callno
)
1115 static void update_max_trunk(void)
1117 int max
= TRUNK_CALL_START
;
1119 /* XXX Prolly don't need locks here XXX */
1120 for (x
=TRUNK_CALL_START
;x
<IAX_MAX_CALLS
- 1; x
++) {
1125 if (option_debug
&& iaxdebug
)
1126 ast_log(LOG_DEBUG
, "New max trunk callno is %d\n", max
);
1129 static void update_max_nontrunk(void)
1133 /* XXX Prolly don't need locks here XXX */
1134 for (x
=1;x
<TRUNK_CALL_START
- 1; x
++) {
1138 maxnontrunkcall
= max
;
1139 if (option_debug
&& iaxdebug
)
1140 ast_log(LOG_DEBUG
, "New max nontrunk callno is %d\n", max
);
1143 static int make_trunk(unsigned short callno
, int locked
)
1148 if (iaxs
[callno
]->oseqno
) {
1149 ast_log(LOG_WARNING
, "Can't make trunk once a call has started!\n");
1152 if (callno
& TRUNK_CALL_START
) {
1153 ast_log(LOG_WARNING
, "Call %d is already a trunk\n", callno
);
1156 gettimeofday(&now
, NULL
);
1157 for (x
=TRUNK_CALL_START
;x
<IAX_MAX_CALLS
- 1; x
++) {
1158 ast_mutex_lock(&iaxsl
[x
]);
1159 if (!iaxs
[x
] && ((now
.tv_sec
- lastused
[x
].tv_sec
) > MIN_REUSE_TIME
)) {
1160 iaxs
[x
] = iaxs
[callno
];
1161 iaxs
[x
]->callno
= x
;
1162 iaxs
[callno
] = NULL
;
1163 /* Update the two timers that should have been started */
1164 if (iaxs
[x
]->pingid
> -1)
1165 ast_sched_del(sched
, iaxs
[x
]->pingid
);
1166 if (iaxs
[x
]->lagid
> -1)
1167 ast_sched_del(sched
, iaxs
[x
]->lagid
);
1168 iaxs
[x
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, (void *)(long)x
);
1169 iaxs
[x
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, (void *)(long)x
);
1171 ast_mutex_unlock(&iaxsl
[callno
]);
1174 ast_mutex_unlock(&iaxsl
[x
]);
1177 ast_mutex_unlock(&iaxsl
[x
]);
1179 if (x
>= IAX_MAX_CALLS
- 1) {
1180 ast_log(LOG_WARNING
, "Unable to trunk call: Insufficient space\n");
1183 ast_log(LOG_DEBUG
, "Made call %d into trunk call %d\n", callno
, x
);
1184 /* We move this call from a non-trunked to a trunked call */
1186 update_max_nontrunk();
1190 static int find_callno(unsigned short callno
, unsigned short dcallno
, struct sockaddr_in
*sin
, int new, int lockpeer
, int sockfd
)
1196 if (new <= NEW_ALLOW
) {
1197 /* Look for an existing connection first */
1198 for (x
=1;(res
< 1) && (x
<maxnontrunkcall
);x
++) {
1199 ast_mutex_lock(&iaxsl
[x
]);
1201 /* Look for an exact match */
1202 if (match(sin
, callno
, dcallno
, iaxs
[x
])) {
1206 ast_mutex_unlock(&iaxsl
[x
]);
1208 for (x
=TRUNK_CALL_START
;(res
< 1) && (x
<maxtrunkcall
);x
++) {
1209 ast_mutex_lock(&iaxsl
[x
]);
1211 /* Look for an exact match */
1212 if (match(sin
, callno
, dcallno
, iaxs
[x
])) {
1216 ast_mutex_unlock(&iaxsl
[x
]);
1219 if ((res
< 1) && (new >= NEW_ALLOW
)) {
1220 if (!iax2_getpeername(*sin
, host
, sizeof(host
), lockpeer
))
1221 snprintf(host
, sizeof(host
), "%s:%d", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
1222 gettimeofday(&now
, NULL
);
1223 for (x
=1;x
<TRUNK_CALL_START
;x
++) {
1224 /* Find first unused call number that hasn't been used in a while */
1225 ast_mutex_lock(&iaxsl
[x
]);
1226 if (!iaxs
[x
] && ((now
.tv_sec
- lastused
[x
].tv_sec
) > MIN_REUSE_TIME
)) break;
1227 ast_mutex_unlock(&iaxsl
[x
]);
1229 /* We've still got lock held if we found a spot */
1230 if (x
>= TRUNK_CALL_START
) {
1231 ast_log(LOG_WARNING
, "No more space\n");
1234 iaxs
[x
] = new_iax(sin
, lockpeer
, host
);
1235 update_max_nontrunk();
1237 if (option_debug
&& iaxdebug
)
1238 ast_log(LOG_DEBUG
, "Creating new call structure %d\n", x
);
1239 iaxs
[x
]->sockfd
= sockfd
;
1240 iaxs
[x
]->addr
.sin_port
= sin
->sin_port
;
1241 iaxs
[x
]->addr
.sin_family
= sin
->sin_family
;
1242 iaxs
[x
]->addr
.sin_addr
.s_addr
= sin
->sin_addr
.s_addr
;
1243 iaxs
[x
]->peercallno
= callno
;
1244 iaxs
[x
]->callno
= x
;
1245 iaxs
[x
]->pingtime
= DEFAULT_RETRY_TIME
;
1246 iaxs
[x
]->expiry
= min_reg_expire
;
1247 iaxs
[x
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, (void *)(long)x
);
1248 iaxs
[x
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, (void *)(long)x
);
1249 iaxs
[x
]->amaflags
= amaflags
;
1250 ast_copy_flags(iaxs
[x
], (&globalflags
), IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
1252 ast_string_field_set(iaxs
[x
], accountcode
, accountcode
);
1253 ast_string_field_set(iaxs
[x
], mohinterpret
, mohinterpret
);
1254 ast_string_field_set(iaxs
[x
], mohsuggest
, mohsuggest
);
1256 ast_log(LOG_WARNING
, "Out of resources\n");
1257 ast_mutex_unlock(&iaxsl
[x
]);
1260 ast_mutex_unlock(&iaxsl
[x
]);
1266 static void iax2_frame_free(struct iax_frame
*fr
)
1268 if (fr
->retrans
> -1)
1269 ast_sched_del(sched
, fr
->retrans
);
1273 static int iax2_queue_frame(int callno
, struct ast_frame
*f
)
1275 /* Assumes lock for callno is already held... */
1277 if (iaxs
[callno
] && iaxs
[callno
]->owner
) {
1278 if (ast_mutex_trylock(&iaxs
[callno
]->owner
->lock
)) {
1279 /* Avoid deadlock by pausing and trying again */
1280 ast_mutex_unlock(&iaxsl
[callno
]);
1282 ast_mutex_lock(&iaxsl
[callno
]);
1284 ast_queue_frame(iaxs
[callno
]->owner
, f
);
1285 ast_mutex_unlock(&iaxs
[callno
]->owner
->lock
);
1294 static void destroy_firmware(struct iax_firmware
*cur
)
1296 /* Close firmware */
1298 munmap(cur
->fwh
, ntohl(cur
->fwh
->datalen
) + sizeof(*(cur
->fwh
)));
1304 static int try_firmware(char *s
)
1307 struct iax_firmware
*cur
;
1312 struct ast_iax2_firmware_header
*fwh
, fwh2
;
1313 struct MD5Context md5
;
1314 unsigned char sum
[16];
1315 unsigned char buf
[1024];
1319 s2
= alloca(strlen(s
) + 100);
1321 ast_log(LOG_WARNING
, "Alloca failed!\n");
1324 last
= strrchr(s
, '/');
1329 snprintf(s2
, strlen(s
) + 100, "/var/tmp/%s-%ld", last
, (unsigned long)ast_random());
1330 res
= stat(s
, &stbuf
);
1332 ast_log(LOG_WARNING
, "Failed to stat '%s': %s\n", s
, strerror(errno
));
1335 /* Make sure it's not a directory */
1336 if (S_ISDIR(stbuf
.st_mode
))
1338 ifd
= open(s
, O_RDONLY
);
1340 ast_log(LOG_WARNING
, "Cannot open '%s': %s\n", s
, strerror(errno
));
1343 fd
= open(s2
, O_RDWR
| O_CREAT
| O_EXCL
);
1345 ast_log(LOG_WARNING
, "Cannot open '%s' for writing: %s\n", s2
, strerror(errno
));
1349 /* Unlink our newly created file */
1352 /* Now copy the firmware into it */
1353 len
= stbuf
.st_size
;
1356 if (chunk
> sizeof(buf
))
1357 chunk
= sizeof(buf
);
1358 res
= read(ifd
, buf
, chunk
);
1360 ast_log(LOG_WARNING
, "Only read %d of %d bytes of data :(: %s\n", res
, chunk
, strerror(errno
));
1365 res
= write(fd
, buf
, chunk
);
1367 ast_log(LOG_WARNING
, "Only write %d of %d bytes of data :(: %s\n", res
, chunk
, strerror(errno
));
1375 /* Return to the beginning */
1376 lseek(fd
, 0, SEEK_SET
);
1377 if ((res
= read(fd
, &fwh2
, sizeof(fwh2
))) != sizeof(fwh2
)) {
1378 ast_log(LOG_WARNING
, "Unable to read firmware header in '%s'\n", s
);
1382 if (ntohl(fwh2
.magic
) != IAX_FIRMWARE_MAGIC
) {
1383 ast_log(LOG_WARNING
, "'%s' is not a valid firmware file\n", s
);
1387 if (ntohl(fwh2
.datalen
) != (stbuf
.st_size
- sizeof(fwh2
))) {
1388 ast_log(LOG_WARNING
, "Invalid data length in firmware '%s'\n", s
);
1392 if (fwh2
.devname
[sizeof(fwh2
.devname
) - 1] || ast_strlen_zero((char *)fwh2
.devname
)) {
1393 ast_log(LOG_WARNING
, "No or invalid device type specified for '%s'\n", s
);
1397 fwh
= mmap(NULL
, stbuf
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
1399 ast_log(LOG_WARNING
, "mmap failed: %s\n", strerror(errno
));
1404 MD5Update(&md5
, fwh
->data
, ntohl(fwh
->datalen
));
1405 MD5Final(sum
, &md5
);
1406 if (memcmp(sum
, fwh
->chksum
, sizeof(sum
))) {
1407 ast_log(LOG_WARNING
, "Firmware file '%s' fails checksum\n", s
);
1408 munmap(fwh
, stbuf
.st_size
);
1414 if (!strcmp((char *)cur
->fwh
->devname
, (char *)fwh
->devname
)) {
1415 /* Found a candidate */
1416 if (cur
->dead
|| (ntohs(cur
->fwh
->version
) < ntohs(fwh
->version
)))
1417 /* The version we have on loaded is older, load this one instead */
1419 /* This version is no newer than what we have. Don't worry about it.
1420 We'll consider it a proper load anyhow though */
1421 munmap(fwh
, stbuf
.st_size
);
1428 /* Allocate a new one and link it */
1429 if ((cur
= ast_calloc(1, sizeof(*cur
)))) {
1431 cur
->next
= waresl
.wares
;
1437 munmap(cur
->fwh
, cur
->mmaplen
);
1443 cur
->mmaplen
= stbuf
.st_size
;
1449 static int iax_check_version(char *dev
)
1452 struct iax_firmware
*cur
;
1453 if (!ast_strlen_zero(dev
)) {
1454 ast_mutex_lock(&waresl
.lock
);
1457 if (!strcmp(dev
, (char *)cur
->fwh
->devname
)) {
1458 res
= ntohs(cur
->fwh
->version
);
1463 ast_mutex_unlock(&waresl
.lock
);
1468 static int iax_firmware_append(struct iax_ie_data
*ied
, const unsigned char *dev
, unsigned int desc
)
1471 unsigned int bs
= desc
& 0xff;
1472 unsigned int start
= (desc
>> 8) & 0xffffff;
1474 struct iax_firmware
*cur
;
1475 if (!ast_strlen_zero((char *)dev
) && bs
) {
1477 ast_mutex_lock(&waresl
.lock
);
1480 if (!strcmp((char *)dev
, (char *)cur
->fwh
->devname
)) {
1481 iax_ie_append_int(ied
, IAX_IE_FWBLOCKDESC
, desc
);
1482 if (start
< ntohl(cur
->fwh
->datalen
)) {
1483 bytes
= ntohl(cur
->fwh
->datalen
) - start
;
1486 iax_ie_append_raw(ied
, IAX_IE_FWBLOCKDATA
, cur
->fwh
->data
+ start
, bytes
);
1489 iax_ie_append(ied
, IAX_IE_FWBLOCKDATA
);
1499 ast_mutex_unlock(&waresl
.lock
);
1505 static void reload_firmware(void)
1507 struct iax_firmware
*cur
, *curl
, *curp
;
1512 /* Mark all as dead */
1513 ast_mutex_lock(&waresl
.lock
);
1519 /* Now that we've freed them, load the new ones */
1520 snprintf(dir
, sizeof(dir
), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR
);
1523 while((de
= readdir(fwd
))) {
1524 if (de
->d_name
[0] != '.') {
1525 snprintf(fn
, sizeof(fn
), "%s/%s", dir
, de
->d_name
);
1526 if (!try_firmware(fn
)) {
1527 if (option_verbose
> 1)
1528 ast_verbose(VERBOSE_PREFIX_2
"Loaded firmware '%s'\n", de
->d_name
);
1534 ast_log(LOG_WARNING
, "Error opening firmware directory '%s': %s\n", dir
, strerror(errno
));
1536 /* Clean up leftovers */
1548 destroy_firmware(curl
);
1553 ast_mutex_unlock(&waresl
.lock
);
1556 static int __do_deliver(void *data
)
1558 /* Just deliver the packet by using queueing. This is called by
1559 the IAX thread with the iaxsl lock held. */
1560 struct iax_frame
*fr
= data
;
1562 fr
->af
.has_timing_info
= 0;
1563 if (iaxs
[fr
->callno
] && !ast_test_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
))
1564 iax2_queue_frame(fr
->callno
, &fr
->af
);
1565 /* Free our iax frame */
1566 iax2_frame_free(fr
);
1567 /* And don't run again */
1571 static int handle_error(void)
1573 /* XXX Ideally we should figure out why an error occured and then abort those
1574 rather than continuing to try. Unfortunately, the published interface does
1575 not seem to work XXX */
1577 struct sockaddr_in
*sin
;
1580 struct sock_extended_err e
;
1585 m
.msg_controllen
= sizeof(e
);
1587 res
= recvmsg(netsocket
, &m
, MSG_ERRQUEUE
);
1589 ast_log(LOG_WARNING
, "Error detected, but unable to read error: %s\n", strerror(errno
));
1591 if (m
.msg_controllen
) {
1592 sin
= (struct sockaddr_in
*)SO_EE_OFFENDER(&e
);
1594 ast_log(LOG_WARNING
, "Receive error from %s\n", ast_inet_ntoa(sin
->sin_addr
));
1596 ast_log(LOG_WARNING
, "No address detected??\n");
1598 ast_log(LOG_WARNING
, "Local error: %s\n", strerror(e
.ee_errno
));
1605 static int transmit_trunk(struct iax_frame
*f
, struct sockaddr_in
*sin
, int sockfd
)
1608 res
= sendto(sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)sin
,
1612 ast_log(LOG_DEBUG
, "Received error: %s\n", strerror(errno
));
1619 static int send_packet(struct iax_frame
*f
)
1622 int callno
= f
->callno
;
1624 /* Don't send if there was an error, but return error instead */
1625 if (!callno
|| !iaxs
[callno
] || iaxs
[callno
]->error
)
1628 /* Called with iaxsl held */
1629 if (option_debug
> 2 && iaxdebug
)
1630 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
));
1633 iax_showframe(f
, NULL
, 0, &iaxs
[callno
]->transfer
, f
->datalen
- sizeof(struct ast_iax2_full_hdr
));
1634 res
= sendto(iaxs
[callno
]->sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)&iaxs
[callno
]->transfer
,
1635 sizeof(iaxs
[callno
]->transfer
));
1638 iax_showframe(f
, NULL
, 0, &iaxs
[callno
]->addr
, f
->datalen
- sizeof(struct ast_iax2_full_hdr
));
1639 res
= sendto(iaxs
[callno
]->sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)&iaxs
[callno
]->addr
,
1640 sizeof(iaxs
[callno
]->addr
));
1643 if (option_debug
&& iaxdebug
)
1644 ast_log(LOG_DEBUG
, "Received error: %s\n", strerror(errno
));
1651 static void iax2_destroy_helper(struct chan_iax2_pvt
*pvt
)
1653 struct iax2_user
*user
= NULL
;
1655 /* Decrement AUTHREQ count if needed */
1656 if (ast_test_flag(pvt
, IAX_MAXAUTHREQ
)) {
1657 AST_LIST_LOCK(&users
);
1658 AST_LIST_TRAVERSE(&users
, user
, entry
) {
1659 if (!strcmp(user
->name
, pvt
->username
)) {
1664 AST_LIST_UNLOCK(&users
);
1665 ast_clear_flag(pvt
, IAX_MAXAUTHREQ
);
1667 /* No more pings or lagrq's */
1668 if (pvt
->pingid
> -1)
1669 ast_sched_del(sched
, pvt
->pingid
);
1671 if (pvt
->lagid
> -1)
1672 ast_sched_del(sched
, pvt
->lagid
);
1674 if (pvt
->autoid
> -1)
1675 ast_sched_del(sched
, pvt
->autoid
);
1677 if (pvt
->authid
> -1)
1678 ast_sched_del(sched
, pvt
->authid
);
1680 if (pvt
->initid
> -1)
1681 ast_sched_del(sched
, pvt
->initid
);
1684 ast_sched_del(sched
, pvt
->jbid
);
1688 static int iax2_predestroy(int callno
)
1690 struct ast_channel
*c
;
1691 struct chan_iax2_pvt
*pvt
;
1692 ast_mutex_lock(&iaxsl
[callno
]);
1695 ast_mutex_unlock(&iaxsl
[callno
]);
1698 if (!ast_test_flag(pvt
, IAX_ALREADYGONE
)) {
1699 iax2_destroy_helper(pvt
);
1700 ast_set_flag(pvt
, IAX_ALREADYGONE
);
1704 c
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1706 ast_queue_hangup(c
);
1708 ast_atomic_fetchadd_int(&usecnt
, -1);
1709 ast_update_use_count();
1711 ast_mutex_unlock(&iaxsl
[callno
]);
1715 static int iax2_predestroy_nolock(int callno
)
1718 ast_mutex_unlock(&iaxsl
[callno
]);
1719 res
= iax2_predestroy(callno
);
1720 ast_mutex_lock(&iaxsl
[callno
]);
1724 static void iax2_destroy(int callno
)
1726 struct chan_iax2_pvt
*pvt
;
1727 struct iax_frame
*cur
;
1728 struct ast_channel
*owner
;
1731 ast_mutex_lock(&iaxsl
[callno
]);
1733 gettimeofday(&lastused
[callno
], NULL
);
1735 owner
= pvt
? pvt
->owner
: NULL
;
1738 if (ast_mutex_trylock(&owner
->lock
)) {
1739 ast_log(LOG_NOTICE
, "Avoiding IAX destroy deadlock\n");
1740 ast_mutex_unlock(&iaxsl
[callno
]);
1746 iaxs
[callno
] = NULL
;
1750 iax2_destroy_helper(pvt
);
1753 ast_set_flag(pvt
, IAX_ALREADYGONE
);
1756 /* If there's an owner, prod it to give up */
1757 owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1758 ast_queue_hangup(owner
);
1761 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
1762 /* Cancel any pending transmissions */
1763 if (cur
->callno
== pvt
->callno
)
1767 pvt
->reg
->callno
= 0;
1771 ast_variables_destroy(pvt
->vars
);
1775 while (jb_getall(pvt
->jb
, &frame
) == JB_OK
)
1776 iax2_frame_free(frame
.data
);
1777 jb_destroy(pvt
->jb
);
1778 /* gotta free up the stringfields */
1779 ast_string_field_free_all(pvt
);
1784 ast_mutex_unlock(&owner
->lock
);
1786 ast_mutex_unlock(&iaxsl
[callno
]);
1787 if (callno
& 0x4000)
1790 static void iax2_destroy_nolock(int callno
)
1792 /* Actually it's easier to unlock, kill it, and relock */
1793 ast_mutex_unlock(&iaxsl
[callno
]);
1794 iax2_destroy(callno
);
1795 ast_mutex_lock(&iaxsl
[callno
]);
1798 static int update_packet(struct iax_frame
*f
)
1800 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
1801 struct ast_iax2_full_hdr
*fh
= f
->data
;
1802 /* Mark this as a retransmission */
1803 fh
->dcallno
= ntohs(IAX_FLAG_RETRANS
| f
->dcallno
);
1805 f
->iseqno
= iaxs
[f
->callno
]->iseqno
;
1806 fh
->iseqno
= f
->iseqno
;
1810 static int attempt_transmit(void *data
);
1811 static void __attempt_transmit(void *data
)
1813 /* Attempt to transmit the frame to the remote peer...
1814 Called without iaxsl held. */
1815 struct iax_frame
*f
= data
;
1817 int callno
= f
->callno
;
1818 /* Make sure this call is still active */
1820 ast_mutex_lock(&iaxsl
[callno
]);
1821 if (callno
&& iaxs
[callno
]) {
1822 if ((f
->retries
< 0) /* Already ACK'd */ ||
1823 (f
->retries
>= max_retries
) /* Too many attempts */) {
1824 /* Record an error if we've transmitted too many times */
1825 if (f
->retries
>= max_retries
) {
1827 /* Transfer timeout */
1828 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREJ
, 0, NULL
, 0, -1);
1829 } else if (f
->final
) {
1831 iax2_destroy_nolock(callno
);
1833 if (iaxs
[callno
]->owner
)
1834 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
);
1835 iaxs
[callno
]->error
= ETIMEDOUT
;
1836 if (iaxs
[callno
]->owner
) {
1837 struct ast_frame fr
= { 0, };
1839 fr
.frametype
= AST_FRAME_CONTROL
;
1840 fr
.subclass
= AST_CONTROL_HANGUP
;
1841 iax2_queue_frame(callno
, &fr
);
1842 /* Remember, owner could disappear */
1843 if (iaxs
[callno
]->owner
)
1844 iaxs
[callno
]->owner
->hangupcause
= AST_CAUSE_DESTINATION_OUT_OF_ORDER
;
1846 if (iaxs
[callno
]->reg
) {
1847 memset(&iaxs
[callno
]->reg
->us
, 0, sizeof(iaxs
[callno
]->reg
->us
));
1848 iaxs
[callno
]->reg
->regstate
= REG_STATE_TIMEOUT
;
1849 iaxs
[callno
]->reg
->refresh
= IAX_DEFAULT_REG_EXPIRE
;
1851 iax2_destroy_nolock(callno
);
1858 /* Update it if it needs it */
1860 /* Attempt transmission */
1863 /* Try again later after 10 times as long */
1865 if (f
->retrytime
> MAX_RETRY_TIME
)
1866 f
->retrytime
= MAX_RETRY_TIME
;
1867 /* Transfer messages max out at one second */
1868 if (f
->transfer
&& (f
->retrytime
> 1000))
1869 f
->retrytime
= 1000;
1870 f
->retrans
= ast_sched_add(sched
, f
->retrytime
, attempt_transmit
, f
);
1873 /* Make sure it gets freed */
1878 ast_mutex_unlock(&iaxsl
[callno
]);
1879 /* Do not try again */
1881 /* Don't attempt delivery, just remove it from the queue */
1882 AST_LIST_LOCK(&iaxq
.queue
);
1883 AST_LIST_REMOVE(&iaxq
.queue
, f
, list
);
1885 AST_LIST_UNLOCK(&iaxq
.queue
);
1887 /* Free the IAX frame */
1892 static int attempt_transmit(void *data
)
1894 #ifdef SCHED_MULTITHREADED
1895 if (schedule_action(__attempt_transmit
, data
))
1897 __attempt_transmit(data
);
1901 static int iax2_prune_realtime(int fd
, int argc
, char *argv
[])
1903 struct iax2_peer
*peer
;
1906 return RESULT_SHOWUSAGE
;
1907 if (!strcmp(argv
[3],"all")) {
1909 ast_cli(fd
, "OK cache is flushed.\n");
1910 } else if ((peer
= find_peer(argv
[3], 0))) {
1911 if(ast_test_flag(peer
, IAX_RTCACHEFRIENDS
)) {
1912 ast_set_flag(peer
, IAX_RTAUTOCLEAR
);
1913 expire_registry((void*)peer
->name
);
1914 ast_cli(fd
, "OK peer %s was removed from the cache.\n", argv
[3]);
1916 ast_cli(fd
, "SORRY peer %s is not eligible for this operation.\n", argv
[3]);
1919 ast_cli(fd
, "SORRY peer %s was not found in the cache.\n", argv
[3]);
1922 return RESULT_SUCCESS
;
1925 static int iax2_test_losspct(int fd
, int argc
, char *argv
[])
1928 return RESULT_SHOWUSAGE
;
1930 test_losspct
= atoi(argv
[3]);
1932 return RESULT_SUCCESS
;
1936 static int iax2_test_late(int fd
, int argc
, char *argv
[])
1939 return RESULT_SHOWUSAGE
;
1941 test_late
= atoi(argv
[3]);
1943 return RESULT_SUCCESS
;
1946 static int iax2_test_resync(int fd
, int argc
, char *argv
[])
1949 return RESULT_SHOWUSAGE
;
1951 test_resync
= atoi(argv
[3]);
1953 return RESULT_SUCCESS
;
1956 static int iax2_test_jitter(int fd
, int argc
, char *argv
[])
1958 if (argc
< 4 || argc
> 5)
1959 return RESULT_SHOWUSAGE
;
1961 test_jit
= atoi(argv
[3]);
1963 test_jitpct
= atoi(argv
[4]);
1965 return RESULT_SUCCESS
;
1967 #endif /* IAXTESTS */
1969 /*! \brief peer_status: Report Peer status in character string */
1970 /* returns 1 if peer is online, -1 if unmonitored */
1971 static int peer_status(struct iax2_peer
*peer
, char *status
, int statuslen
)
1975 if (peer
->lastms
< 0) {
1976 ast_copy_string(status
, "UNREACHABLE", statuslen
);
1977 } else if (peer
->lastms
> peer
->maxms
) {
1978 snprintf(status
, statuslen
, "LAGGED (%d ms)", peer
->lastms
);
1980 } else if (peer
->lastms
) {
1981 snprintf(status
, statuslen
, "OK (%d ms)", peer
->lastms
);
1984 ast_copy_string(status
, "UNKNOWN", statuslen
);
1987 ast_copy_string(status
, "Unmonitored", statuslen
);
1993 /*! \brief Show one peer in detail */
1994 static int iax2_show_peer(int fd
, int argc
, char *argv
[])
1998 struct iax2_peer
*peer
;
1999 char codec_buf
[512];
2000 int x
= 0, codec
= 0, load_realtime
= 0;
2003 return RESULT_SHOWUSAGE
;
2005 load_realtime
= (argc
== 5 && !strcmp(argv
[4], "load")) ? 1 : 0;
2007 peer
= find_peer(argv
[3], load_realtime
);
2010 ast_cli(fd
, " * Name : %s\n", peer
->name
);
2011 ast_cli(fd
, " Secret : %s\n", ast_strlen_zero(peer
->secret
)?"<Not set>":"<Set>");
2012 ast_cli(fd
, " Context : %s\n", peer
->context
);
2013 ast_cli(fd
, " Mailbox : %s\n", peer
->mailbox
);
2014 ast_cli(fd
, " Dynamic : %s\n", ast_test_flag(peer
, IAX_DYNAMIC
) ? "Yes":"No");
2015 ast_cli(fd
, " Callerid : %s\n", ast_callerid_merge(cbuf
, sizeof(cbuf
), peer
->cid_name
, peer
->cid_num
, "<unspecified>"));
2016 ast_cli(fd
, " Expire : %d\n", peer
->expire
);
2017 ast_cli(fd
, " ACL : %s\n", (peer
->ha
?"Yes":"No"));
2018 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
));
2019 ast_cli(fd
, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer
->defaddr
.sin_addr
), ntohs(peer
->defaddr
.sin_port
));
2020 ast_cli(fd
, " Username : %s\n", peer
->username
);
2021 ast_cli(fd
, " Codecs : ");
2022 ast_getformatname_multiple(codec_buf
, sizeof(codec_buf
) -1, peer
->capability
);
2023 ast_cli(fd
, "%s\n", codec_buf
);
2025 ast_cli(fd
, " Codec Order : (");
2026 for(x
= 0; x
< 32 ; x
++) {
2027 codec
= ast_codec_pref_index(&peer
->prefs
,x
);
2030 ast_cli(fd
, "%s", ast_getformatname(codec
));
2031 if(x
< 31 && ast_codec_pref_index(&peer
->prefs
,x
+1))
2036 ast_cli(fd
, "none");
2039 ast_cli(fd
, " Status : ");
2040 peer_status(peer
, status
, sizeof(status
));
2041 ast_cli(fd
, "%s\n",status
);
2042 ast_cli(fd
, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer
->pokefreqok
, peer
->pokefreqnotok
, peer
->smoothing
? "On" : "Off");
2044 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2047 ast_cli(fd
,"Peer %s not found.\n", argv
[3]);
2051 return RESULT_SUCCESS
;
2054 static char *complete_iax2_show_peer(const char *line
, const char *word
, int pos
, int state
)
2057 struct iax2_peer
*p
= NULL
;
2059 int wordlen
= strlen(word
);
2061 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
2063 AST_LIST_LOCK(&peers
);
2064 AST_LIST_TRAVERSE(&peers
, p
, entry
) {
2065 if (!strncasecmp(p
->name
, word
, wordlen
) && ++which
> state
) {
2066 res
= ast_strdup(p
->name
);
2070 AST_LIST_UNLOCK(&peers
);
2076 static int iax2_show_stats(int fd
, int argc
, char *argv
[])
2078 struct iax_frame
*cur
;
2079 int cnt
= 0, dead
=0, final
=0;
2081 return RESULT_SHOWUSAGE
;
2082 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
2083 if (cur
->retries
< 0)
2089 ast_cli(fd
, " IAX Statistics\n");
2090 ast_cli(fd
, "---------------------\n");
2091 ast_cli(fd
, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
2092 ast_cli(fd
, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead
, final
, cnt
);
2094 return RESULT_SUCCESS
;
2097 static int iax2_show_cache(int fd
, int argc
, char *argv
[])
2099 struct iax2_dpcache
*dp
;
2100 char tmp
[1024], *pc
;
2104 gettimeofday(&tv
, NULL
);
2105 ast_mutex_lock(&dpcache_lock
);
2107 ast_cli(fd
, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
2109 s
= dp
->expiry
.tv_sec
- tv
.tv_sec
;
2111 if (dp
->flags
& CACHE_FLAG_EXISTS
)
2112 strncat(tmp
, "EXISTS|", sizeof(tmp
) - strlen(tmp
) - 1);
2113 if (dp
->flags
& CACHE_FLAG_NONEXISTENT
)
2114 strncat(tmp
, "NONEXISTENT|", sizeof(tmp
) - strlen(tmp
) - 1);
2115 if (dp
->flags
& CACHE_FLAG_CANEXIST
)
2116 strncat(tmp
, "CANEXIST|", sizeof(tmp
) - strlen(tmp
) - 1);
2117 if (dp
->flags
& CACHE_FLAG_PENDING
)
2118 strncat(tmp
, "PENDING|", sizeof(tmp
) - strlen(tmp
) - 1);
2119 if (dp
->flags
& CACHE_FLAG_TIMEOUT
)
2120 strncat(tmp
, "TIMEOUT|", sizeof(tmp
) - strlen(tmp
) - 1);
2121 if (dp
->flags
& CACHE_FLAG_TRANSMITTED
)
2122 strncat(tmp
, "TRANSMITTED|", sizeof(tmp
) - strlen(tmp
) - 1);
2123 if (dp
->flags
& CACHE_FLAG_MATCHMORE
)
2124 strncat(tmp
, "MATCHMORE|", sizeof(tmp
) - strlen(tmp
) - 1);
2125 if (dp
->flags
& CACHE_FLAG_UNKNOWN
)
2126 strncat(tmp
, "UNKNOWN|", sizeof(tmp
) - strlen(tmp
) - 1);
2127 /* Trim trailing pipe */
2128 if (!ast_strlen_zero(tmp
))
2129 tmp
[strlen(tmp
) - 1] = '\0';
2131 ast_copy_string(tmp
, "(none)", sizeof(tmp
));
2133 pc
= strchr(dp
->peercontext
, '@');
2135 pc
= dp
->peercontext
;
2138 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
2139 if (dp
->waiters
[x
] > -1)
2142 ast_cli(fd
, "%-20.20s %-12.12s %-9d %-8d %s\n", pc
, dp
->exten
, s
, y
, tmp
);
2144 ast_cli(fd
, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc
, dp
->exten
, "(expired)", y
, tmp
);
2147 ast_mutex_unlock(&dpcache_lock
);
2148 return RESULT_SUCCESS
;
2151 static unsigned int calc_rxstamp(struct chan_iax2_pvt
*p
, unsigned int offset
);
2153 static void unwrap_timestamp(struct iax_frame
*fr
)
2157 if ( (fr
->ts
& 0xFFFF0000) == (iaxs
[fr
->callno
]->last
& 0xFFFF0000) ) {
2158 x
= fr
->ts
- iaxs
[fr
->callno
]->last
;
2160 /* Sudden big jump backwards in timestamp:
2161 What likely happened here is that miniframe timestamp has circled but we haven't
2162 gotten the update from the main packet. We'll just pretend that we did, and
2163 update the timestamp appropriately. */
2164 fr
->ts
= ( (iaxs
[fr
->callno
]->last
& 0xFFFF0000) + 0x10000) | (fr
->ts
& 0xFFFF);
2165 if (option_debug
&& iaxdebug
)
2166 ast_log(LOG_DEBUG
, "schedule_delivery: pushed forward timestamp\n");
2169 /* Sudden apparent big jump forwards in timestamp:
2170 What's likely happened is this is an old miniframe belonging to the previous
2171 top-16-bit timestamp that has turned up out of order.
2172 Adjust the timestamp appropriately. */
2173 fr
->ts
= ( (iaxs
[fr
->callno
]->last
& 0xFFFF0000) - 0x10000) | (fr
->ts
& 0xFFFF);
2174 if (option_debug
&& iaxdebug
)
2175 ast_log(LOG_DEBUG
, "schedule_delivery: pushed back timestamp\n");
2180 static int get_from_jb(void *p
);
2182 static void update_jbsched(struct chan_iax2_pvt
*pvt
)
2186 when
= ast_tvdiff_ms(ast_tvnow(), pvt
->rxcore
);
2188 when
= jb_next(pvt
->jb
) - when
;
2190 if(pvt
->jbid
> -1) ast_sched_del(sched
, pvt
->jbid
);
2193 /* XXX should really just empty until when > 0.. */
2197 pvt
->jbid
= ast_sched_add(sched
, when
, get_from_jb
, CALLNO_TO_PTR(pvt
->callno
));
2199 /* Signal scheduler thread */
2200 signal_condition(&sched_lock
, &sched_cond
);
2203 static void __get_from_jb(void *p
)
2205 int callno
= PTR_TO_CALLNO(p
);
2206 struct chan_iax2_pvt
*pvt
= NULL
;
2207 struct iax_frame
*fr
;
2214 /* Make sure we have a valid private structure before going on */
2215 ast_mutex_lock(&iaxsl
[callno
]);
2219 ast_mutex_unlock(&iaxsl
[callno
]);
2225 gettimeofday(&tv
,NULL
);
2226 /* round up a millisecond since ast_sched_runq does; */
2227 /* prevents us from spinning while waiting for our now */
2228 /* to catch up with runq's now */
2231 now
= ast_tvdiff_ms(tv
, pvt
->rxcore
);
2233 if(now
>= (next
= jb_next(pvt
->jb
))) {
2234 ret
= jb_get(pvt
->jb
,&frame
,now
,ast_codec_interp_len(pvt
->voiceformat
));
2242 struct ast_frame af
;
2244 /* create an interpolation frame */
2245 af
.frametype
= AST_FRAME_VOICE
;
2246 af
.subclass
= pvt
->voiceformat
;
2248 af
.samples
= frame
.ms
* 8;
2250 af
.src
= "IAX2 JB interpolation";
2252 af
.delivery
= ast_tvadd(pvt
->rxcore
, ast_samp2tv(next
, 1000));
2253 af
.offset
=AST_FRIENDLY_OFFSET
;
2255 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
2256 * which we'd need to malloc, and then it would free it. That seems like a drag */
2257 if (!ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
))
2258 iax2_queue_frame(callno
, &af
);
2262 iax2_frame_free(frame
.data
);
2269 /* shouldn't happen */
2273 update_jbsched(pvt
);
2274 ast_mutex_unlock(&iaxsl
[callno
]);
2277 static int get_from_jb(void *data
)
2279 #ifdef SCHED_MULTITHREADED
2280 if (schedule_action(__get_from_jb
, data
))
2282 __get_from_jb(data
);
2286 static int schedule_delivery(struct iax_frame
*fr
, int updatehistory
, int fromtrunk
, unsigned int *tsout
)
2292 /* Attempt to recover wrapped timestamps */
2293 unwrap_timestamp(fr
);
2296 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
2297 if ( !fromtrunk
&& !ast_tvzero(iaxs
[fr
->callno
]->rxcore
))
2298 fr
->af
.delivery
= ast_tvadd(iaxs
[fr
->callno
]->rxcore
, ast_samp2tv(fr
->ts
, 1000));
2301 ast_log(LOG_DEBUG
, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
2303 fr
->af
.delivery
= ast_tv(0,0);
2306 type
= JB_TYPE_CONTROL
;
2309 if(fr
->af
.frametype
== AST_FRAME_VOICE
) {
2310 type
= JB_TYPE_VOICE
;
2311 len
= ast_codec_get_samples(&fr
->af
) / 8;
2312 } else if(fr
->af
.frametype
== AST_FRAME_CNG
) {
2313 type
= JB_TYPE_SILENCE
;
2316 if ( (!ast_test_flag(iaxs
[fr
->callno
], IAX_USEJITTERBUF
)) ) {
2323 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
2324 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
2325 if( (!ast_test_flag(iaxs
[fr
->callno
], IAX_FORCEJITTERBUF
)) &&
2326 iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
) &&
2327 (ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->tech
->properties
& AST_CHAN_TP_WANTSJITTER
)) {
2330 /* deliver any frames in the jb */
2331 while(jb_getall(iaxs
[fr
->callno
]->jb
,&frame
) == JB_OK
)
2332 __do_deliver(frame
.data
);
2334 jb_reset(iaxs
[fr
->callno
]->jb
);
2336 if (iaxs
[fr
->callno
]->jbid
> -1)
2337 ast_sched_del(sched
, iaxs
[fr
->callno
]->jbid
);
2339 iaxs
[fr
->callno
]->jbid
= -1;
2341 /* deliver this frame now */
2348 /* insert into jitterbuffer */
2349 /* TODO: Perhaps we could act immediately if it's not droppable and late */
2350 ret
= jb_put(iaxs
[fr
->callno
]->jb
, fr
, type
, len
, fr
->ts
,
2351 calc_rxstamp(iaxs
[fr
->callno
],fr
->ts
));
2352 if (ret
== JB_DROP
) {
2354 } else if (ret
== JB_SCHED
) {
2355 update_jbsched(iaxs
[fr
->callno
]);
2360 /* Free our iax frame */
2361 iax2_frame_free(fr
);
2367 static int iax2_transmit(struct iax_frame
*fr
)
2369 /* Lock the queue and place this packet at the end */
2370 /* By setting this to 0, the network thread will send it for us, and
2371 queue retransmission if necessary */
2373 AST_LIST_LOCK(&iaxq
.queue
);
2374 AST_LIST_INSERT_TAIL(&iaxq
.queue
, fr
, list
);
2376 AST_LIST_UNLOCK(&iaxq
.queue
);
2377 /* Wake up the network and scheduler thread */
2378 pthread_kill(netthreadid
, SIGURG
);
2379 signal_condition(&sched_lock
, &sched_cond
);
2385 static int iax2_digit_begin(struct ast_channel
*c
, char digit
)
2387 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_DTMF_BEGIN
, digit
, 0, NULL
, 0, -1);
2390 static int iax2_digit_end(struct ast_channel
*c
, char digit
)
2392 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_DTMF_END
, digit
, 0, NULL
, 0, -1);
2395 static int iax2_sendtext(struct ast_channel
*c
, const char *text
)
2398 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_TEXT
,
2399 0, 0, (unsigned char *)text
, strlen(text
) + 1, -1);
2402 static int iax2_sendimage(struct ast_channel
*c
, struct ast_frame
*img
)
2404 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_IMAGE
, img
->subclass
, 0, img
->data
, img
->datalen
, -1);
2407 static int iax2_sendhtml(struct ast_channel
*c
, int subclass
, const char *data
, int datalen
)
2409 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_HTML
, subclass
, 0, (unsigned char *)data
, datalen
, -1);
2412 static int iax2_fixup(struct ast_channel
*oldchannel
, struct ast_channel
*newchan
)
2414 unsigned short callno
= PTR_TO_CALLNO(newchan
->tech_pvt
);
2415 ast_mutex_lock(&iaxsl
[callno
]);
2417 iaxs
[callno
]->owner
= newchan
;
2419 ast_log(LOG_WARNING
, "Uh, this isn't a good sign...\n");
2420 ast_mutex_unlock(&iaxsl
[callno
]);
2424 static struct iax2_peer
*realtime_peer(const char *peername
, struct sockaddr_in
*sin
)
2426 struct ast_variable
*var
;
2427 struct ast_variable
*tmp
;
2428 struct iax2_peer
*peer
=NULL
;
2429 time_t regseconds
= 0, nowtime
;
2433 var
= ast_load_realtime("iaxpeers", "name", peername
, NULL
);
2436 sprintf(porta
, "%d", ntohs(sin
->sin_port
));
2437 var
= ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin
->sin_addr
), "port", porta
, NULL
);
2439 /* We'll need the peer name in order to build the structure! */
2440 for (tmp
= var
; tmp
; tmp
= tmp
->next
) {
2441 if (!strcasecmp(tmp
->name
, "name"))
2442 peername
= tmp
->value
;
2449 peer
= build_peer(peername
, var
, NULL
, ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
) ? 0 : 1);
2454 for (tmp
= var
; tmp
; tmp
= tmp
->next
) {
2455 /* Make sure it's not a user only... */
2456 if (!strcasecmp(tmp
->name
, "type")) {
2457 if (strcasecmp(tmp
->value
, "friend") &&
2458 strcasecmp(tmp
->value
, "peer")) {
2459 /* Whoops, we weren't supposed to exist! */
2464 } else if (!strcasecmp(tmp
->name
, "regseconds")) {
2465 ast_get_time_t(tmp
->value
, ®seconds
, 0, NULL
);
2466 } else if (!strcasecmp(tmp
->name
, "ipaddr")) {
2467 inet_aton(tmp
->value
, &(peer
->addr
.sin_addr
));
2468 } else if (!strcasecmp(tmp
->name
, "port")) {
2469 peer
->addr
.sin_port
= htons(atoi(tmp
->value
));
2470 } else if (!strcasecmp(tmp
->name
, "host")) {
2471 if (!strcasecmp(tmp
->value
, "dynamic"))
2478 ast_variables_destroy(var
);
2480 if (ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
)) {
2481 ast_copy_flags(peer
, &globalflags
, IAX_RTAUTOCLEAR
|IAX_RTCACHEFRIENDS
);
2482 if (ast_test_flag(peer
, IAX_RTAUTOCLEAR
)) {
2483 if (peer
->expire
> -1)
2484 ast_sched_del(sched
, peer
->expire
);
2485 peer
->expire
= ast_sched_add(sched
, (global_rtautoclear
) * 1000, expire_registry
, (void*)peer
->name
);
2487 AST_LIST_LOCK(&peers
);
2488 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
2489 AST_LIST_UNLOCK(&peers
);
2490 if (ast_test_flag(peer
, IAX_DYNAMIC
))
2491 reg_source_db(peer
);
2493 ast_set_flag(peer
, IAX_TEMPONLY
);
2496 if (!ast_test_flag(&globalflags
, IAX_RTIGNOREREGEXPIRE
) && dynamic
) {
2498 if ((nowtime
- regseconds
) > IAX_DEFAULT_REG_EXPIRE
) {
2499 memset(&peer
->addr
, 0, sizeof(peer
->addr
));
2500 realtime_update_peer(peer
->name
, &peer
->addr
, 0);
2502 ast_log(LOG_DEBUG
, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
2503 peername
, (int)(nowtime
- regseconds
), (int)regseconds
, (int)nowtime
);
2507 ast_log(LOG_DEBUG
, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
2508 peername
, (int)(nowtime
- regseconds
), (int)regseconds
, (int)nowtime
);
2515 static struct iax2_user
*realtime_user(const char *username
)
2517 struct ast_variable
*var
;
2518 struct ast_variable
*tmp
;
2519 struct iax2_user
*user
=NULL
;
2521 var
= ast_load_realtime("iaxusers", "name", username
, NULL
);
2527 /* Make sure it's not a peer only... */
2528 if (!strcasecmp(tmp
->name
, "type")) {
2529 if (strcasecmp(tmp
->value
, "friend") &&
2530 strcasecmp(tmp
->value
, "user")) {
2537 user
= build_user(username
, var
, NULL
, !ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
));
2541 ast_variables_destroy(var
);
2543 if (ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
)) {
2544 ast_set_flag(user
, IAX_RTCACHEFRIENDS
);
2545 AST_LIST_LOCK(&users
);
2546 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
2547 AST_LIST_UNLOCK(&users
);
2549 ast_set_flag(user
, IAX_TEMPONLY
);
2555 static void realtime_update_peer(const char *peername
, struct sockaddr_in
*sin
, time_t regtime
)
2558 char regseconds
[20];
2560 snprintf(regseconds
, sizeof(regseconds
), "%d", (int)regtime
);
2561 snprintf(port
, sizeof(port
), "%d", ntohs(sin
->sin_port
));
2562 ast_update_realtime("iaxpeers", "name", peername
,
2563 "ipaddr", ast_inet_ntoa(sin
->sin_addr
), "port", port
,
2564 "regseconds", regseconds
, NULL
);
2567 struct create_addr_info
{
2580 char context
[AST_MAX_CONTEXT
];
2581 char peercontext
[AST_MAX_CONTEXT
];
2582 char mohinterpret
[MAX_MUSICCLASS
];
2583 char mohsuggest
[MAX_MUSICCLASS
];
2586 static int create_addr(const char *peername
, struct sockaddr_in
*sin
, struct create_addr_info
*cai
)
2588 struct ast_hostent ahp
;
2590 struct iax2_peer
*peer
;
2592 ast_clear_flag(cai
, IAX_SENDANI
| IAX_TRUNK
);
2593 cai
->sockfd
= defaultsockfd
;
2595 sin
->sin_family
= AF_INET
;
2597 if (!(peer
= find_peer(peername
, 1))) {
2600 hp
= ast_gethostbyname(peername
, &ahp
);
2602 memcpy(&sin
->sin_addr
, hp
->h_addr
, sizeof(sin
->sin_addr
));
2603 sin
->sin_port
= htons(IAX_DEFAULT_PORTNO
);
2604 /* use global iax prefs for unknown peer/user */
2605 ast_codec_pref_convert(&prefs
, cai
->prefs
, sizeof(cai
->prefs
), 1);
2608 ast_log(LOG_WARNING
, "No such host: %s\n", peername
);
2615 /* if the peer has no address (current or default), return failure */
2616 if (!(peer
->addr
.sin_addr
.s_addr
|| peer
->defaddr
.sin_addr
.s_addr
)) {
2617 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2622 /* if the peer is being monitored and is currently unreachable, return failure */
2623 if (peer
->maxms
&& ((peer
->lastms
> peer
->maxms
) || (peer
->lastms
< 0))) {
2624 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2629 ast_copy_flags(cai
, peer
, IAX_SENDANI
| IAX_TRUNK
| IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
2630 cai
->maxtime
= peer
->maxms
;
2631 cai
->capability
= peer
->capability
;
2632 cai
->encmethods
= peer
->encmethods
;
2633 cai
->sockfd
= peer
->sockfd
;
2634 cai
->adsi
= peer
->adsi
;
2635 ast_codec_pref_convert(&peer
->prefs
, cai
->prefs
, sizeof(cai
->prefs
), 1);
2636 ast_copy_string(cai
->context
, peer
->context
, sizeof(cai
->context
));
2637 ast_copy_string(cai
->peercontext
, peer
->peercontext
, sizeof(cai
->peercontext
));
2638 ast_copy_string(cai
->username
, peer
->username
, sizeof(cai
->username
));
2639 ast_copy_string(cai
->timezone
, peer
->zonetag
, sizeof(cai
->timezone
));
2640 ast_copy_string(cai
->outkey
, peer
->outkey
, sizeof(cai
->outkey
));
2641 ast_copy_string(cai
->mohinterpret
, peer
->mohinterpret
, sizeof(cai
->mohinterpret
));
2642 ast_copy_string(cai
->mohsuggest
, peer
->mohsuggest
, sizeof(cai
->mohsuggest
));
2643 if (ast_strlen_zero(peer
->dbsecret
)) {
2644 ast_copy_string(cai
->secret
, peer
->secret
, sizeof(cai
->secret
));
2649 family
= ast_strdupa(peer
->dbsecret
);
2650 key
= strchr(family
, '/');
2653 if (!key
|| ast_db_get(family
, key
, cai
->secret
, sizeof(cai
->secret
))) {
2654 ast_log(LOG_WARNING
, "Unable to retrieve database password for family/key '%s'!\n", peer
->dbsecret
);
2655 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2661 if (peer
->addr
.sin_addr
.s_addr
) {
2662 sin
->sin_addr
= peer
->addr
.sin_addr
;
2663 sin
->sin_port
= peer
->addr
.sin_port
;
2665 sin
->sin_addr
= peer
->defaddr
.sin_addr
;
2666 sin
->sin_port
= peer
->defaddr
.sin_port
;
2669 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2675 static void __auto_congest(void *nothing
)
2677 int callno
= PTR_TO_CALLNO(nothing
);
2678 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_CONGESTION
};
2679 ast_mutex_lock(&iaxsl
[callno
]);
2681 iaxs
[callno
]->initid
= -1;
2682 iax2_queue_frame(callno
, &f
);
2683 ast_log(LOG_NOTICE
, "Auto-congesting call due to slow response\n");
2685 ast_mutex_unlock(&iaxsl
[callno
]);
2688 static int auto_congest(void *data
)
2690 #ifdef SCHED_MULTITHREADED
2691 if (schedule_action(__auto_congest
, data
))
2693 __auto_congest(data
);
2697 static unsigned int iax2_datetime(const char *tz
)
2703 localtime_r(&t
, &tm
);
2704 if (!ast_strlen_zero(tz
))
2705 ast_localtime(&t
, &tm
, tz
);
2706 tmp
= (tm
.tm_sec
>> 1) & 0x1f; /* 5 bits of seconds */
2707 tmp
|= (tm
.tm_min
& 0x3f) << 5; /* 6 bits of minutes */
2708 tmp
|= (tm
.tm_hour
& 0x1f) << 11; /* 5 bits of hours */
2709 tmp
|= (tm
.tm_mday
& 0x1f) << 16; /* 5 bits of day of month */
2710 tmp
|= ((tm
.tm_mon
+ 1) & 0xf) << 21; /* 4 bits of month */
2711 tmp
|= ((tm
.tm_year
- 100) & 0x7f) << 25; /* 7 bits of year */
2715 struct parsed_dial_string
{
2727 * \brief Parses an IAX dial string into its component parts.
2728 * \param data the string to be parsed
2729 * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
2732 * This function parses the string and fills the structure
2733 * with pointers to its component parts. The input string
2736 * \note This function supports both plaintext passwords and RSA
2737 * key names; if the password string is formatted as '[keyname]',
2738 * then the keyname will be placed into the key field, and the
2739 * password field will be set to NULL.
2741 * \note The dial string format is:
2742 * [username[:password]@]peer[:port][/exten[@@context]][/options]
2744 static void parse_dial_string(char *data
, struct parsed_dial_string
*pds
)
2746 if (ast_strlen_zero(data
))
2749 pds
->peer
= strsep(&data
, "/");
2750 pds
->exten
= strsep(&data
, "/");
2751 pds
->options
= data
;
2755 pds
->exten
= strsep(&data
, "@");
2756 pds
->context
= data
;
2759 if (strchr(pds
->peer
, '@')) {
2761 pds
->username
= strsep(&data
, "@");
2765 if (pds
->username
) {
2766 data
= pds
->username
;
2767 pds
->username
= strsep(&data
, ":");
2768 pds
->password
= data
;
2772 pds
->peer
= strsep(&data
, ":");
2775 /* check for a key name wrapped in [] in the secret position, if found,
2776 move it to the key field instead
2778 if (pds
->password
&& (pds
->password
[0] == '[')) {
2779 pds
->key
= ast_strip_quoted(pds
->password
, "[", "]");
2780 pds
->password
= NULL
;
2784 static int iax2_call(struct ast_channel
*c
, char *dest
, int timeout
)
2786 struct sockaddr_in sin
;
2787 char *l
=NULL
, *n
=NULL
, *tmpstr
;
2788 struct iax_ie_data ied
;
2789 char *defaultrdest
= "s";
2790 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
2791 struct parsed_dial_string pds
;
2792 struct create_addr_info cai
;
2794 if ((c
->_state
!= AST_STATE_DOWN
) && (c
->_state
!= AST_STATE_RESERVED
)) {
2795 ast_log(LOG_WARNING
, "Channel is already in use (%s)?\n", c
->name
);
2799 memset(&cai
, 0, sizeof(cai
));
2800 cai
.encmethods
= iax2_encryption
;
2802 memset(&pds
, 0, sizeof(pds
));
2803 tmpstr
= ast_strdupa(dest
);
2804 parse_dial_string(tmpstr
, &pds
);
2807 pds
.exten
= defaultrdest
;
2809 if (create_addr(pds
.peer
, &sin
, &cai
)) {
2810 ast_log(LOG_WARNING
, "No address associated with '%s'\n", pds
.peer
);
2814 if (!pds
.username
&& !ast_strlen_zero(cai
.username
))
2815 pds
.username
= cai
.username
;
2816 if (!pds
.password
&& !ast_strlen_zero(cai
.secret
))
2817 pds
.password
= cai
.secret
;
2818 if (!pds
.key
&& !ast_strlen_zero(cai
.outkey
))
2819 pds
.key
= cai
.outkey
;
2820 if (!pds
.context
&& !ast_strlen_zero(cai
.peercontext
))
2821 pds
.context
= cai
.peercontext
;
2823 /* Keep track of the context for outgoing calls too */
2824 ast_copy_string(c
->context
, cai
.context
, sizeof(c
->context
));
2827 sin
.sin_port
= htons(atoi(pds
.port
));
2830 n
= c
->cid
.cid_name
;
2832 /* Now build request */
2833 memset(&ied
, 0, sizeof(ied
));
2835 /* On new call, first IE MUST be IAX version of caller */
2836 iax_ie_append_short(&ied
, IAX_IE_VERSION
, IAX_PROTO_VERSION
);
2837 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, pds
.exten
);
2838 if (pds
.options
&& strchr(pds
.options
, 'a')) {
2839 /* Request auto answer */
2840 iax_ie_append(&ied
, IAX_IE_AUTOANSWER
);
2843 iax_ie_append_str(&ied
, IAX_IE_CODEC_PREFS
, cai
.prefs
);
2846 iax_ie_append_str(&ied
, IAX_IE_CALLING_NUMBER
, l
);
2847 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, c
->cid
.cid_pres
);
2850 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, c
->cid
.cid_pres
);
2852 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, AST_PRES_NUMBER_NOT_AVAILABLE
);
2855 iax_ie_append_byte(&ied
, IAX_IE_CALLINGTON
, c
->cid
.cid_ton
);
2856 iax_ie_append_short(&ied
, IAX_IE_CALLINGTNS
, c
->cid
.cid_tns
);
2859 iax_ie_append_str(&ied
, IAX_IE_CALLING_NAME
, n
);
2860 if (ast_test_flag(iaxs
[callno
], IAX_SENDANI
) && c
->cid
.cid_ani
)
2861 iax_ie_append_str(&ied
, IAX_IE_CALLING_ANI
, c
->cid
.cid_ani
);
2863 if (!ast_strlen_zero(c
->language
))
2864 iax_ie_append_str(&ied
, IAX_IE_LANGUAGE
, c
->language
);
2865 if (!ast_strlen_zero(c
->cid
.cid_dnid
))
2866 iax_ie_append_str(&ied
, IAX_IE_DNID
, c
->cid
.cid_dnid
);
2867 if (!ast_strlen_zero(c
->cid
.cid_rdnis
))
2868 iax_ie_append_str(&ied
, IAX_IE_RDNIS
, c
->cid
.cid_rdnis
);
2871 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, pds
.context
);
2874 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, pds
.username
);
2877 iax_ie_append_short(&ied
, IAX_IE_ENCRYPTION
, cai
.encmethods
);
2879 ast_mutex_lock(&iaxsl
[callno
]);
2881 if (!ast_strlen_zero(c
->context
))
2882 ast_string_field_set(iaxs
[callno
], context
, c
->context
);
2885 ast_string_field_set(iaxs
[callno
], username
, pds
.username
);
2887 iaxs
[callno
]->encmethods
= cai
.encmethods
;
2889 iaxs
[callno
]->adsi
= cai
.adsi
;
2891 ast_string_field_set(iaxs
[callno
], mohinterpret
, cai
.mohinterpret
);
2892 ast_string_field_set(iaxs
[callno
], mohsuggest
, cai
.mohsuggest
);
2895 ast_string_field_set(iaxs
[callno
], outkey
, pds
.key
);
2897 ast_string_field_set(iaxs
[callno
], secret
, pds
.password
);
2899 iax_ie_append_int(&ied
, IAX_IE_FORMAT
, c
->nativeformats
);
2900 iax_ie_append_int(&ied
, IAX_IE_CAPABILITY
, iaxs
[callno
]->capability
);
2901 iax_ie_append_short(&ied
, IAX_IE_ADSICPE
, c
->adsicpe
);
2902 iax_ie_append_int(&ied
, IAX_IE_DATETIME
, iax2_datetime(cai
.timezone
));
2904 if (iaxs
[callno
]->maxtime
) {
2905 /* Initialize pingtime and auto-congest time */
2906 iaxs
[callno
]->pingtime
= iaxs
[callno
]->maxtime
/ 2;
2907 iaxs
[callno
]->initid
= ast_sched_add(sched
, iaxs
[callno
]->maxtime
* 2, auto_congest
, CALLNO_TO_PTR(callno
));
2908 } else if (autokill
) {
2909 iaxs
[callno
]->pingtime
= autokill
/ 2;
2910 iaxs
[callno
]->initid
= ast_sched_add(sched
, autokill
* 2, auto_congest
, CALLNO_TO_PTR(callno
));
2913 /* Transmit the string in a "NEW" request */
2914 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_NEW
, 0, ied
.buf
, ied
.pos
, -1);
2916 ast_mutex_unlock(&iaxsl
[callno
]);
2917 ast_setstate(c
, AST_STATE_RINGING
);
2922 static int iax2_hangup(struct ast_channel
*c
)
2924 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
2926 struct iax_ie_data ied
;
2927 memset(&ied
, 0, sizeof(ied
));
2928 ast_mutex_lock(&iaxsl
[callno
]);
2929 if (callno
&& iaxs
[callno
]) {
2930 ast_log(LOG_DEBUG
, "We're hanging up %s now...\n", c
->name
);
2931 alreadygone
= ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
);
2932 /* Send the hangup unless we have had a transmission error or are already gone */
2933 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, (unsigned char)c
->hangupcause
);
2934 if (!iaxs
[callno
]->error
&& !alreadygone
)
2935 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_HANGUP
, 0, ied
.buf
, ied
.pos
, -1);
2936 /* Explicitly predestroy it */
2937 iax2_predestroy_nolock(callno
);
2938 /* If we were already gone to begin with, destroy us now */
2940 ast_log(LOG_DEBUG
, "Really destroying %s now...\n", c
->name
);
2941 iax2_destroy_nolock(callno
);
2944 ast_mutex_unlock(&iaxsl
[callno
]);
2945 if (option_verbose
> 2)
2946 ast_verbose(VERBOSE_PREFIX_3
"Hungup '%s'\n", c
->name
);
2950 static int iax2_setoption(struct ast_channel
*c
, int option
, void *data
, int datalen
)
2952 struct ast_option_header
*h
;
2956 case AST_OPTION_TXGAIN
:
2957 case AST_OPTION_RXGAIN
:
2958 /* these two cannot be sent, because they require a result */
2962 if (!(h
= ast_malloc(datalen
+ sizeof(*h
))))
2965 h
->flag
= AST_OPTION_FLAG_REQUEST
;
2966 h
->option
= htons(option
);
2967 memcpy(h
->data
, data
, datalen
);
2968 res
= send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_CONTROL
,
2969 AST_CONTROL_OPTION
, 0, (unsigned char *) h
,
2970 datalen
+ sizeof(*h
), -1);
2976 static struct ast_frame
*iax2_read(struct ast_channel
*c
)
2978 ast_log(LOG_NOTICE
, "I should never be called!\n");
2979 return &ast_null_frame
;
2982 static int iax2_start_transfer(unsigned short callno0
, unsigned short callno1
, int mediaonly
)
2985 struct iax_ie_data ied0
;
2986 struct iax_ie_data ied1
;
2987 unsigned int transferid
= (unsigned int)ast_random();
2988 memset(&ied0
, 0, sizeof(ied0
));
2989 iax_ie_append_addr(&ied0
, IAX_IE_APPARENT_ADDR
, &iaxs
[callno1
]->addr
);
2990 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[callno1
]->peercallno
);
2991 iax_ie_append_int(&ied0
, IAX_IE_TRANSFERID
, transferid
);
2993 memset(&ied1
, 0, sizeof(ied1
));
2994 iax_ie_append_addr(&ied1
, IAX_IE_APPARENT_ADDR
, &iaxs
[callno0
]->addr
);
2995 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[callno0
]->peercallno
);
2996 iax_ie_append_int(&ied1
, IAX_IE_TRANSFERID
, transferid
);
2998 res
= send_command(iaxs
[callno0
], AST_FRAME_IAX
, IAX_COMMAND_TXREQ
, 0, ied0
.buf
, ied0
.pos
, -1);
3001 res
= send_command(iaxs
[callno1
], AST_FRAME_IAX
, IAX_COMMAND_TXREQ
, 0, ied1
.buf
, ied1
.pos
, -1);
3004 iaxs
[callno0
]->transferring
= mediaonly
? TRANSFER_MBEGIN
: TRANSFER_BEGIN
;
3005 iaxs
[callno1
]->transferring
= mediaonly
? TRANSFER_MBEGIN
: TRANSFER_BEGIN
;
3009 static void lock_both(unsigned short callno0
, unsigned short callno1
)
3011 ast_mutex_lock(&iaxsl
[callno0
]);
3012 while (ast_mutex_trylock(&iaxsl
[callno1
])) {
3013 ast_mutex_unlock(&iaxsl
[callno0
]);
3015 ast_mutex_lock(&iaxsl
[callno0
]);
3019 static void unlock_both(unsigned short callno0
, unsigned short callno1
)
3021 ast_mutex_unlock(&iaxsl
[callno1
]);
3022 ast_mutex_unlock(&iaxsl
[callno0
]);
3025 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
)
3027 struct ast_channel
*cs
[3];
3028 struct ast_channel
*who
, *other
;
3031 int transferstarted
=0;
3032 struct ast_frame
*f
;
3033 unsigned short callno0
= PTR_TO_CALLNO(c0
->tech_pvt
);
3034 unsigned short callno1
= PTR_TO_CALLNO(c1
->tech_pvt
);
3035 struct timeval waittimer
= {0, 0}, tv
;
3037 lock_both(callno0
, callno1
);
3038 /* Put them in native bridge mode */
3039 if (!flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
)) {
3040 iaxs
[callno0
]->bridgecallno
= callno1
;
3041 iaxs
[callno1
]->bridgecallno
= callno0
;
3043 unlock_both(callno0
, callno1
);
3045 /* If not, try to bridge until we can execute a transfer, if we can */
3048 for (/* ever */;;) {
3049 /* Check in case we got masqueraded into */
3050 if ((c0
->tech
!= &iax2_tech
) || (c1
->tech
!= &iax2_tech
)) {
3051 if (option_verbose
> 2)
3052 ast_verbose(VERBOSE_PREFIX_3
"Can't masquerade, we're different...\n");
3053 /* Remove from native mode */
3054 if (c0
->tech
== &iax2_tech
) {
3055 ast_mutex_lock(&iaxsl
[callno0
]);
3056 iaxs
[callno0
]->bridgecallno
= 0;
3057 ast_mutex_unlock(&iaxsl
[callno0
]);
3059 if (c1
->tech
== &iax2_tech
) {
3060 ast_mutex_lock(&iaxsl
[callno1
]);
3061 iaxs
[callno1
]->bridgecallno
= 0;
3062 ast_mutex_unlock(&iaxsl
[callno1
]);
3064 return AST_BRIDGE_FAILED_NOWARN
;
3066 if (c0
->nativeformats
!= c1
->nativeformats
) {
3067 if (option_verbose
> 2) {
3070 ast_getformatname_multiple(buf0
, sizeof(buf0
) -1, c0
->nativeformats
);
3071 ast_getformatname_multiple(buf1
, sizeof(buf1
) -1, c1
->nativeformats
);
3072 ast_verbose(VERBOSE_PREFIX_3
"Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0
->nativeformats
, buf0
, c1
->nativeformats
, buf1
);
3074 /* Remove from native mode */
3075 lock_both(callno0
, callno1
);
3076 iaxs
[callno0
]->bridgecallno
= 0;
3077 iaxs
[callno1
]->bridgecallno
= 0;
3078 unlock_both(callno0
, callno1
);
3079 return AST_BRIDGE_FAILED_NOWARN
;
3081 /* check if transfered and if we really want native bridging */
3082 if (!transferstarted
&& !ast_test_flag(iaxs
[callno0
], IAX_NOTRANSFER
) && !ast_test_flag(iaxs
[callno1
], IAX_NOTRANSFER
)) {
3083 /* Try the transfer */
3084 if (iax2_start_transfer(callno0
, callno1
, (flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
)) ||
3085 ast_test_flag(iaxs
[callno0
], IAX_TRANSFERMEDIA
) | ast_test_flag(iaxs
[callno1
], IAX_TRANSFERMEDIA
)))
3086 ast_log(LOG_WARNING
, "Unable to start the transfer\n");
3087 transferstarted
= 1;
3089 if ((iaxs
[callno0
]->transferring
== TRANSFER_RELEASED
) && (iaxs
[callno1
]->transferring
== TRANSFER_RELEASED
)) {
3090 /* Call has been transferred. We're no longer involved */
3091 gettimeofday(&tv
, NULL
);
3092 if (ast_tvzero(waittimer
)) {
3094 } else if (tv
.tv_sec
- waittimer
.tv_sec
> IAX_LINGER_TIMEOUT
) {
3095 c0
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3096 c1
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3099 res
= AST_BRIDGE_COMPLETE
;
3104 who
= ast_waitfor_n(cs
, 2, &to
);
3105 if (timeoutms
> -1) {
3106 timeoutms
-= (1000 - to
);
3112 res
= AST_BRIDGE_RETRY
;
3115 if (ast_check_hangup(c0
) || ast_check_hangup(c1
)) {
3116 res
= AST_BRIDGE_FAILED
;
3125 res
= AST_BRIDGE_COMPLETE
;
3128 if ((f
->frametype
== AST_FRAME_CONTROL
) && !(flags
& AST_BRIDGE_IGNORE_SIGS
)) {
3131 res
= AST_BRIDGE_COMPLETE
;
3134 other
= (who
== c0
) ? c1
: c0
; /* the 'other' channel */
3135 if ((f
->frametype
== AST_FRAME_VOICE
) ||
3136 (f
->frametype
== AST_FRAME_TEXT
) ||
3137 (f
->frametype
== AST_FRAME_VIDEO
) ||
3138 (f
->frametype
== AST_FRAME_IMAGE
) ||
3139 (f
->frametype
== AST_FRAME_DTMF
)) {
3140 /* monitored dtmf take out of the bridge.
3141 * check if we monitor the specific source.
3143 int monitored_source
= (who
== c0
) ? AST_BRIDGE_DTMF_CHANNEL_0
: AST_BRIDGE_DTMF_CHANNEL_1
;
3144 if (f
->frametype
== AST_FRAME_DTMF
&& (flags
& monitored_source
)) {
3147 res
= AST_BRIDGE_COMPLETE
;
3148 /* Remove from native mode */
3151 /* everything else goes to the other side */
3152 ast_write(other
, f
);
3155 /* Swap who gets priority */
3160 lock_both(callno0
, callno1
);
3162 iaxs
[callno0
]->bridgecallno
= 0;
3164 iaxs
[callno1
]->bridgecallno
= 0;
3165 unlock_both(callno0
, callno1
);
3169 static int iax2_answer(struct ast_channel
*c
)
3171 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3173 ast_log(LOG_DEBUG
, "Answering IAX2 call\n");
3174 return send_command_locked(callno
, AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
, 0, NULL
, 0, -1);
3177 static int iax2_indicate(struct ast_channel
*c
, int condition
, const void *data
, size_t datalen
)
3179 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3181 if (option_debug
&& iaxdebug
)
3182 ast_log(LOG_DEBUG
, "Indicating condition %d\n", condition
);
3184 if (!strcasecmp(iaxs
[callno
]->mohinterpret
, "passthrough"))
3185 return send_command_locked(callno
, AST_FRAME_CONTROL
, condition
, 0, data
, datalen
, -1);
3187 switch (condition
) {
3188 case AST_CONTROL_HOLD
:
3189 ast_moh_start(c
, data
, iaxs
[callno
]->mohinterpret
);
3191 case AST_CONTROL_UNHOLD
:
3195 return send_command_locked(callno
, AST_FRAME_CONTROL
, condition
, 0, data
, datalen
, -1);
3199 static int iax2_transfer(struct ast_channel
*c
, const char *dest
)
3201 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3202 struct iax_ie_data ied
;
3203 char tmp
[256], *context
;
3204 ast_copy_string(tmp
, dest
, sizeof(tmp
));
3205 context
= strchr(tmp
, '@');
3210 memset(&ied
, 0, sizeof(ied
));
3211 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, tmp
);
3213 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, context
);
3215 ast_log(LOG_DEBUG
, "Transferring '%s' to '%s'\n", c
->name
, dest
);
3216 return send_command_locked(callno
, AST_FRAME_IAX
, IAX_COMMAND_TRANSFER
, 0, ied
.buf
, ied
.pos
, -1);
3219 static int iax2_getpeertrunk(struct sockaddr_in sin
)
3221 struct iax2_peer
*peer
= NULL
;
3224 AST_LIST_LOCK(&peers
);
3225 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
3226 if ((peer
->addr
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
) &&
3227 (peer
->addr
.sin_port
== sin
.sin_port
)) {
3228 res
= ast_test_flag(peer
, IAX_TRUNK
);
3232 AST_LIST_UNLOCK(&peers
);
3237 /*! \brief Create new call, interface with the PBX core */
3238 static struct ast_channel
*ast_iax2_new(int callno
, int state
, int capability
)
3240 struct ast_channel
*tmp
;
3241 struct chan_iax2_pvt
*i
;
3242 struct ast_variable
*v
= NULL
;
3244 if (!(i
= iaxs
[callno
])) {
3245 ast_log(LOG_WARNING
, "No IAX2 pvt found for callno '%d' !\n", callno
);
3249 /* Don't hold call lock */
3250 ast_mutex_unlock(&iaxsl
[callno
]);
3251 tmp
= ast_channel_alloc(1);
3252 ast_mutex_lock(&iaxsl
[callno
]);
3255 tmp
->tech
= &iax2_tech
;
3256 ast_string_field_build(tmp
, name
, "IAX2/%s-%d", i
->host
, i
->callno
);
3257 /* We can support any format by default, until we get restricted */
3258 tmp
->nativeformats
= capability
;
3259 tmp
->readformat
= ast_best_codec(capability
);
3260 tmp
->writeformat
= ast_best_codec(capability
);
3261 tmp
->tech_pvt
= CALLNO_TO_PTR(i
->callno
);
3263 /* Don't use ast_set_callerid() here because it will
3264 * generate a NewCallerID event before the NewChannel event */
3265 tmp
->cid
.cid_num
= ast_strdup(i
->cid_num
);
3266 tmp
->cid
.cid_name
= ast_strdup(i
->cid_name
);
3267 if (!ast_strlen_zero(i
->ani
))
3268 tmp
->cid
.cid_ani
= ast_strdup(i
->ani
);
3270 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_num
);
3271 tmp
->cid
.cid_dnid
= ast_strdup(i
->dnid
);
3272 tmp
->cid
.cid_rdnis
= ast_strdup(i
->rdnis
);
3273 tmp
->cid
.cid_pres
= i
->calling_pres
;
3274 tmp
->cid
.cid_ton
= i
->calling_ton
;
3275 tmp
->cid
.cid_tns
= i
->calling_tns
;
3276 if (!ast_strlen_zero(i
->language
))
3277 ast_string_field_set(tmp
, language
, i
->language
);
3278 if (!ast_strlen_zero(i
->accountcode
))
3279 ast_string_field_set(tmp
, accountcode
, i
->accountcode
);
3281 tmp
->amaflags
= i
->amaflags
;
3282 ast_copy_string(tmp
->context
, i
->context
, sizeof(tmp
->context
));
3283 ast_copy_string(tmp
->exten
, i
->exten
, sizeof(tmp
->exten
));
3285 tmp
->adsicpe
= i
->peeradsicpe
;
3287 tmp
->adsicpe
= AST_ADSI_UNAVAILABLE
;
3289 i
->capability
= capability
;
3290 ast_setstate(tmp
, state
);
3291 if (state
!= AST_STATE_DOWN
) {
3292 if (ast_pbx_start(tmp
)) {
3293 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", tmp
->name
);
3300 for (v
= i
->vars
; v
; v
= v
->next
)
3301 pbx_builtin_setvar_helper(tmp
, v
->name
, v
->value
);
3303 ast_atomic_fetchadd_int(&usecnt
, 1);
3304 ast_update_use_count();
3309 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer
*tpeer
, int sampms
, struct timeval
*tv
)
3311 unsigned long int mssincetx
; /* unsigned to handle overflows */
3314 tpeer
->trunkact
= *tv
;
3315 mssincetx
= ast_tvdiff_ms(*tv
, tpeer
->lasttxtime
);
3316 if (mssincetx
> 5000 || ast_tvzero(tpeer
->txtrunktime
)) {
3317 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
3318 tpeer
->txtrunktime
= *tv
;
3319 tpeer
->lastsent
= 999999;
3321 /* Update last transmit time now */
3322 tpeer
->lasttxtime
= *tv
;
3324 /* Calculate ms offset */
3325 ms
= ast_tvdiff_ms(*tv
, tpeer
->txtrunktime
);
3326 /* Predict from last value */
3327 pred
= tpeer
->lastsent
+ sampms
;
3328 if (abs(ms
- pred
) < MAX_TIMESTAMP_SKEW
)
3331 /* We never send the same timestamp twice, so fudge a little if we must */
3332 if (ms
== tpeer
->lastsent
)
3333 ms
= tpeer
->lastsent
+ 1;
3334 tpeer
->lastsent
= ms
;
3338 static unsigned int fix_peerts(struct timeval
*tv
, int callno
, unsigned int ts
)
3340 long ms
; /* NOT unsigned */
3341 if (ast_tvzero(iaxs
[callno
]->rxcore
)) {
3342 /* Initialize rxcore time if appropriate */
3343 gettimeofday(&iaxs
[callno
]->rxcore
, NULL
);
3344 /* Round to nearest 20ms so traces look pretty */
3345 iaxs
[callno
]->rxcore
.tv_usec
-= iaxs
[callno
]->rxcore
.tv_usec
% 20000;
3347 /* Calculate difference between trunk and channel */
3348 ms
= ast_tvdiff_ms(*tv
, iaxs
[callno
]->rxcore
);
3349 /* Return as the sum of trunk time and the difference between trunk and real time */
3353 static unsigned int calc_timestamp(struct chan_iax2_pvt
*p
, unsigned int ts
, struct ast_frame
*f
)
3359 struct timeval
*delivery
= NULL
;
3362 /* What sort of frame do we have?: voice is self-explanatory
3363 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
3364 non-genuine frames are CONTROL frames [ringing etc], DTMF
3365 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
3366 the others need a timestamp slaved to the voice frames so that they go in sequence
3369 if (f
->frametype
== AST_FRAME_VOICE
) {
3371 delivery
= &f
->delivery
;
3372 } else if (f
->frametype
== AST_FRAME_IAX
) {
3374 } else if (f
->frametype
== AST_FRAME_CNG
) {
3378 if (ast_tvzero(p
->offset
)) {
3379 gettimeofday(&p
->offset
, NULL
);
3380 /* Round to nearest 20ms for nice looking traces */
3381 p
->offset
.tv_usec
-= p
->offset
.tv_usec
% 20000;
3383 /* If the timestamp is specified, just send it as is */
3386 /* If we have a time that the frame arrived, always use it to make our timestamp */
3387 if (delivery
&& !ast_tvzero(*delivery
)) {
3388 ms
= ast_tvdiff_ms(*delivery
, p
->offset
);
3389 if (option_debug
> 2 && iaxdebug
)
3390 ast_log(LOG_DEBUG
, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p
->callno
, iaxs
[p
->callno
]->peercallno
);
3392 ms
= ast_tvdiff_ms(ast_tvnow(), p
->offset
);
3396 /* On a voice frame, use predicted values if appropriate */
3397 if (p
->notsilenttx
&& abs(ms
- p
->nextpred
) <= MAX_TIMESTAMP_SKEW
) {
3398 /* Adjust our txcore, keeping voice and non-voice synchronized */
3400 When we send voice, we usually send "calculated" timestamps worked out
3401 on the basis of the number of samples sent. When we send other frames,
3402 we usually send timestamps worked out from the real clock.
3403 The problem is that they can tend to drift out of step because the
3404 source channel's clock and our clock may not be exactly at the same rate.
3405 We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
3406 for this call. Moving it adjusts timestamps for non-voice frames.
3407 We make the adjustment in the style of a moving average. Each time we
3408 adjust p->offset by 10% of the difference between our clock-derived
3409 timestamp and the predicted timestamp. That's why you see "10000"
3410 below even though IAX2 timestamps are in milliseconds.
3411 The use of a moving average avoids offset moving too radically.
3412 Generally, "adjust" roams back and forth around 0, with offset hardly
3413 changing at all. But if a consistent different starts to develop it
3414 will be eliminated over the course of 10 frames (200-300msecs)
3416 adjust
= (ms
- p
->nextpred
);
3418 p
->offset
= ast_tvsub(p
->offset
, ast_samp2tv(abs(adjust
), 10000));
3419 else if (adjust
> 0)
3420 p
->offset
= ast_tvadd(p
->offset
, ast_samp2tv(adjust
, 10000));
3423 p
->nextpred
= ms
; /*f->samples / 8;*/
3424 if (p
->nextpred
<= p
->lastsent
)
3425 p
->nextpred
= p
->lastsent
+ 3;
3429 /* in this case, just use the actual
3430 * time, since we're either way off
3431 * (shouldn't happen), or we're ending a
3432 * silent period -- and seed the next
3433 * predicted time. Also, round ms to the
3434 * next multiple of frame size (so our
3435 * silent periods are multiples of
3436 * frame size too) */
3438 if (iaxdebug
&& abs(ms
- p
->nextpred
) > MAX_TIMESTAMP_SKEW
)
3439 ast_log(LOG_DEBUG
, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
3440 abs(ms
- p
->nextpred
), MAX_TIMESTAMP_SKEW
);
3442 if (f
->samples
>= 8) /* check to make sure we dont core dump */
3444 int diff
= ms
% (f
->samples
/ 8);
3446 ms
+= f
->samples
/8 - diff
;
3453 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
3454 it's a genuine frame */
3456 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
3457 if (ms
<= p
->lastsent
)
3458 ms
= p
->lastsent
+ 3;
3459 } else if (abs(ms
- p
->lastsent
) <= MAX_TIMESTAMP_SKEW
) {
3460 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
3461 ms
= p
->lastsent
+ 3;
3467 p
->nextpred
= p
->nextpred
+ f
->samples
/ 8;
3471 static unsigned int calc_rxstamp(struct chan_iax2_pvt
*p
, unsigned int offset
)
3473 /* Returns where in "receive time" we are. That is, how many ms
3474 since we received (or would have received) the frame with timestamp 0 */
3478 #endif /* IAXTESTS */
3479 /* Setup rxcore if necessary */
3480 if (ast_tvzero(p
->rxcore
)) {
3481 p
->rxcore
= ast_tvnow();
3482 if (option_debug
&& iaxdebug
)
3483 ast_log(LOG_DEBUG
, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
3484 p
->callno
, (int)(p
->rxcore
.tv_sec
), (int)(p
->rxcore
.tv_usec
), offset
);
3485 p
->rxcore
= ast_tvsub(p
->rxcore
, ast_samp2tv(offset
, 1000));
3487 if (option_debug
&& iaxdebug
)
3488 ast_log(LOG_DEBUG
, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
3489 p
->callno
, (int)(p
->rxcore
.tv_sec
),(int)( p
->rxcore
.tv_usec
));
3493 ms
= ast_tvdiff_ms(ast_tvnow(), p
->rxcore
);
3496 if (!test_jitpct
|| ((100.0 * ast_random() / (RAND_MAX
+ 1.0)) < test_jitpct
)) {
3497 jit
= (int)((float)test_jit
* ast_random() / (RAND_MAX
+ 1.0));
3498 if ((int)(2.0 * ast_random() / (RAND_MAX
+ 1.0)))
3507 #endif /* IAXTESTS */
3511 static struct iax2_trunk_peer
*find_tpeer(struct sockaddr_in
*sin
, int fd
)
3513 struct iax2_trunk_peer
*tpeer
;
3515 /* Finds and locks trunk peer */
3516 ast_mutex_lock(&tpeerlock
);
3517 for (tpeer
= tpeers
; tpeer
; tpeer
= tpeer
->next
) {
3518 /* We don't lock here because tpeer->addr *never* changes */
3519 if (!inaddrcmp(&tpeer
->addr
, sin
)) {
3520 ast_mutex_lock(&tpeer
->lock
);
3525 if ((tpeer
= ast_calloc(1, sizeof(*tpeer
)))) {
3526 ast_mutex_init(&tpeer
->lock
);
3527 tpeer
->lastsent
= 9999;
3528 memcpy(&tpeer
->addr
, sin
, sizeof(tpeer
->addr
));
3529 tpeer
->trunkact
= ast_tvnow();
3530 ast_mutex_lock(&tpeer
->lock
);
3531 tpeer
->next
= tpeers
;
3535 setsockopt(tpeer
->sockfd
, SOL_SOCKET
, SO_NO_CHECK
, &nochecksums
, sizeof(nochecksums
));
3537 ast_log(LOG_DEBUG
, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer
->addr
.sin_addr
), ntohs(tpeer
->addr
.sin_port
));
3540 ast_mutex_unlock(&tpeerlock
);
3544 static int iax2_trunk_queue(struct chan_iax2_pvt
*pvt
, struct iax_frame
*fr
)
3546 struct ast_frame
*f
;
3547 struct iax2_trunk_peer
*tpeer
;
3549 struct ast_iax2_meta_trunk_entry
*met
;
3550 struct ast_iax2_meta_trunk_mini
*mtm
;
3553 tpeer
= find_tpeer(&pvt
->addr
, pvt
->sockfd
);
3555 if (tpeer
->trunkdatalen
+ f
->datalen
+ 4 >= tpeer
->trunkdataalloc
) {
3556 /* Need to reallocate space */
3557 if (tpeer
->trunkdataalloc
< MAX_TRUNKDATA
) {
3558 if (!(tmp
= ast_realloc(tpeer
->trunkdata
, tpeer
->trunkdataalloc
+ DEFAULT_TRUNKDATA
+ IAX2_TRUNK_PREFACE
))) {
3559 ast_mutex_unlock(&tpeer
->lock
);
3563 tpeer
->trunkdataalloc
+= DEFAULT_TRUNKDATA
;
3564 tpeer
->trunkdata
= tmp
;
3565 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
);
3567 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
));
3568 ast_mutex_unlock(&tpeer
->lock
);
3573 /* Append to meta frame */
3574 ptr
= tpeer
->trunkdata
+ IAX2_TRUNK_PREFACE
+ tpeer
->trunkdatalen
;
3575 if (ast_test_flag(&globalflags
, IAX_TRUNKTIMESTAMPS
)) {
3576 mtm
= (struct ast_iax2_meta_trunk_mini
*)ptr
;
3577 mtm
->len
= htons(f
->datalen
);
3578 mtm
->mini
.callno
= htons(pvt
->callno
);
3579 mtm
->mini
.ts
= htons(0xffff & fr
->ts
);
3580 ptr
+= sizeof(struct ast_iax2_meta_trunk_mini
);
3581 tpeer
->trunkdatalen
+= sizeof(struct ast_iax2_meta_trunk_mini
);
3583 met
= (struct ast_iax2_meta_trunk_entry
*)ptr
;
3584 /* Store call number and length in meta header */
3585 met
->callno
= htons(pvt
->callno
);
3586 met
->len
= htons(f
->datalen
);
3587 /* Advance pointers/decrease length past trunk entry header */
3588 ptr
+= sizeof(struct ast_iax2_meta_trunk_entry
);
3589 tpeer
->trunkdatalen
+= sizeof(struct ast_iax2_meta_trunk_entry
);
3591 /* Copy actual trunk data */
3592 memcpy(ptr
, f
->data
, f
->datalen
);
3593 tpeer
->trunkdatalen
+= f
->datalen
;
3596 ast_mutex_unlock(&tpeer
->lock
);
3601 static void build_enc_keys(const unsigned char *digest
, aes_encrypt_ctx
*ecx
, aes_decrypt_ctx
*dcx
)
3603 aes_encrypt_key128(digest
, ecx
);
3604 aes_decrypt_key128(digest
, dcx
);
3607 static void memcpy_decrypt(unsigned char *dst
, const unsigned char *src
, int len
, aes_decrypt_ctx
*dcx
)
3610 /* Debug with "fake encryption" */
3613 ast_log(LOG_WARNING
, "len should be multiple of 16, not %d!\n", len
);
3615 dst
[x
] = src
[x
] ^ 0xff;
3617 unsigned char lastblock
[16] = { 0 };
3620 aes_decrypt(src
, dst
, dcx
);
3622 dst
[x
] ^= lastblock
[x
];
3623 memcpy(lastblock
, src
, sizeof(lastblock
));
3631 static void memcpy_encrypt(unsigned char *dst
, const unsigned char *src
, int len
, aes_encrypt_ctx
*ecx
)
3634 /* Debug with "fake encryption" */
3637 ast_log(LOG_WARNING
, "len should be multiple of 16, not %d!\n", len
);
3639 dst
[x
] = src
[x
] ^ 0xff;
3641 unsigned char curblock
[16] = { 0 };
3645 curblock
[x
] ^= src
[x
];
3646 aes_encrypt(curblock
, dst
, ecx
);
3647 memcpy(curblock
, dst
, sizeof(curblock
));
3655 static int decode_frame(aes_decrypt_ctx
*dcx
, struct ast_iax2_full_hdr
*fh
, struct ast_frame
*f
, int *datalen
)
3658 unsigned char *workspace
;
3659 workspace
= alloca(*datalen
);
3662 if (ntohs(fh
->scallno
) & IAX_FLAG_FULL
) {
3663 struct ast_iax2_full_enc_hdr
*efh
= (struct ast_iax2_full_enc_hdr
*)fh
;
3664 if (*datalen
< 16 + sizeof(struct ast_iax2_full_hdr
))
3667 memcpy_decrypt(workspace
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
), dcx
);
3669 padding
= 16 + (workspace
[15] & 0xf);
3670 if (option_debug
&& iaxdebug
)
3671 ast_log(LOG_DEBUG
, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen
, padding
, workspace
[15]);
3672 if (*datalen
< padding
+ sizeof(struct ast_iax2_full_hdr
))
3675 *datalen
-= padding
;
3676 memcpy(efh
->encdata
, workspace
+ padding
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
));
3677 f
->frametype
= fh
->type
;
3678 if (f
->frametype
== AST_FRAME_VIDEO
) {
3679 f
->subclass
= uncompress_subclass(fh
->csub
& ~0x40) | ((fh
->csub
>> 6) & 0x1);
3681 f
->subclass
= uncompress_subclass(fh
->csub
);
3684 struct ast_iax2_mini_enc_hdr
*efh
= (struct ast_iax2_mini_enc_hdr
*)fh
;
3685 if (option_debug
&& iaxdebug
)
3686 ast_log(LOG_DEBUG
, "Decoding mini with length %d\n", *datalen
);
3687 if (*datalen
< 16 + sizeof(struct ast_iax2_mini_hdr
))
3690 memcpy_decrypt(workspace
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
), dcx
);
3691 padding
= 16 + (workspace
[15] & 0x0f);
3692 if (*datalen
< padding
+ sizeof(struct ast_iax2_mini_hdr
))
3694 *datalen
-= padding
;
3695 memcpy(efh
->encdata
, workspace
+ padding
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
));
3700 static int encrypt_frame(aes_encrypt_ctx
*ecx
, struct ast_iax2_full_hdr
*fh
, unsigned char *poo
, int *datalen
)
3703 unsigned char *workspace
;
3704 workspace
= alloca(*datalen
+ 32);
3707 if (ntohs(fh
->scallno
) & IAX_FLAG_FULL
) {
3708 struct ast_iax2_full_enc_hdr
*efh
= (struct ast_iax2_full_enc_hdr
*)fh
;
3709 if (option_debug
&& iaxdebug
)
3710 ast_log(LOG_DEBUG
, "Encoding full frame %d/%d with length %d\n", fh
->type
, fh
->csub
, *datalen
);
3711 padding
= 16 - ((*datalen
- sizeof(struct ast_iax2_full_enc_hdr
)) % 16);
3712 padding
= 16 + (padding
& 0xf);
3713 memcpy(workspace
, poo
, padding
);
3714 memcpy(workspace
+ padding
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
));
3715 workspace
[15] &= 0xf0;
3716 workspace
[15] |= (padding
& 0xf);
3717 if (option_debug
&& iaxdebug
)
3718 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]);
3719 *datalen
+= padding
;
3720 memcpy_encrypt(efh
->encdata
, workspace
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
), ecx
);
3721 if (*datalen
>= 32 + sizeof(struct ast_iax2_full_enc_hdr
))
3722 memcpy(poo
, workspace
+ *datalen
- 32, 32);
3724 struct ast_iax2_mini_enc_hdr
*efh
= (struct ast_iax2_mini_enc_hdr
*)fh
;
3725 if (option_debug
&& iaxdebug
)
3726 ast_log(LOG_DEBUG
, "Encoding mini frame with length %d\n", *datalen
);
3727 padding
= 16 - ((*datalen
- sizeof(struct ast_iax2_mini_enc_hdr
)) % 16);
3728 padding
= 16 + (padding
& 0xf);
3729 memcpy(workspace
, poo
, padding
);
3730 memcpy(workspace
+ padding
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
));
3731 workspace
[15] &= 0xf0;
3732 workspace
[15] |= (padding
& 0x0f);
3733 *datalen
+= padding
;
3734 memcpy_encrypt(efh
->encdata
, workspace
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
), ecx
);
3735 if (*datalen
>= 32 + sizeof(struct ast_iax2_mini_enc_hdr
))
3736 memcpy(poo
, workspace
+ *datalen
- 32, 32);
3741 static int decrypt_frame(int callno
, struct ast_iax2_full_hdr
*fh
, struct ast_frame
*f
, int *datalen
)
3744 if (!ast_test_flag(iaxs
[callno
], IAX_KEYPOPULATED
)) {
3745 /* Search for possible keys, given secrets */
3746 struct MD5Context md5
;
3747 unsigned char digest
[16];
3748 char *tmppw
, *stringp
;
3750 tmppw
= ast_strdupa(iaxs
[callno
]->secret
);
3752 while ((tmppw
= strsep(&stringp
, ";"))) {
3754 MD5Update(&md5
, (unsigned char *)iaxs
[callno
]->challenge
, strlen(iaxs
[callno
]->challenge
));
3755 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
3756 MD5Final(digest
, &md5
);
3757 build_enc_keys(digest
, &iaxs
[callno
]->ecx
, &iaxs
[callno
]->dcx
);
3758 res
= decode_frame(&iaxs
[callno
]->dcx
, fh
, f
, datalen
);
3760 ast_set_flag(iaxs
[callno
], IAX_KEYPOPULATED
);
3765 res
= decode_frame(&iaxs
[callno
]->dcx
, fh
, f
, datalen
);
3769 static int iax2_send(struct chan_iax2_pvt
*pvt
, struct ast_frame
*f
, unsigned int ts
, int seqno
, int now
, int transfer
, int final
)
3771 /* Queue a packet for delivery on a given private structure. Use "ts" for
3772 timestamp, or calculate if ts is 0. Send immediately without retransmission
3773 or delayed, with retransmission */
3774 struct ast_iax2_full_hdr
*fh
;
3775 struct ast_iax2_mini_hdr
*mh
;
3776 struct ast_iax2_video_hdr
*vh
;
3778 struct iax_frame fr2
;
3779 unsigned char buffer
[4096];
3781 struct iax_frame
*fr
;
3784 unsigned int lastsent
;
3788 ast_log(LOG_WARNING
, "No private structure for packet?\n");
3792 lastsent
= pvt
->lastsent
;
3794 /* Calculate actual timestamp */
3795 fts
= calc_timestamp(pvt
, ts
, f
);
3797 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
3798 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
3799 * increment the "predicted timestamps" for voice, if we're predecting */
3800 if(f
->frametype
== AST_FRAME_VOICE
&& f
->datalen
== 0)
3804 if ((ast_test_flag(pvt
, IAX_TRUNK
) ||
3805 (((fts
& 0xFFFF0000L
) == (lastsent
& 0xFFFF0000L
)) ||
3806 ((fts
& 0xFFFF0000L
) == ((lastsent
+ 0x10000) & 0xFFFF0000L
))))
3807 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
3808 (f
->frametype
== AST_FRAME_VOICE
)
3809 /* is a voice frame */ &&
3810 (f
->subclass
== pvt
->svoiceformat
)
3811 /* is the same type */ ) {
3812 /* Force immediate rather than delayed transmission */
3814 /* Mark that mini-style frame is appropriate */
3817 if (((fts
& 0xFFFF8000L
) == (lastsent
& 0xFFFF8000L
)) &&
3818 (f
->frametype
== AST_FRAME_VIDEO
) &&
3819 ((f
->subclass
& ~0x1) == pvt
->svideoformat
)) {
3823 /* Allocate an iax_frame */
3827 fr
= iax_frame_new(DIRECTION_OUTGRESS
, ast_test_flag(pvt
, IAX_ENCRYPTED
) ? f
->datalen
+ 32 : f
->datalen
);
3829 ast_log(LOG_WARNING
, "Out of memory\n");
3832 /* Copy our prospective frame into our immediate or retransmitted wrapper */
3833 iax_frame_wrap(fr
, f
);
3836 fr
->callno
= pvt
->callno
;
3837 fr
->transfer
= transfer
;
3840 /* We need a full frame */
3844 fr
->oseqno
= pvt
->oseqno
++;
3845 fr
->iseqno
= pvt
->iseqno
;
3846 fh
= (struct ast_iax2_full_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_full_hdr
));
3847 fh
->scallno
= htons(fr
->callno
| IAX_FLAG_FULL
);
3848 fh
->ts
= htonl(fr
->ts
);
3849 fh
->oseqno
= fr
->oseqno
;
3853 fh
->iseqno
= fr
->iseqno
;
3854 /* Keep track of the last thing we've acknowledged */
3856 pvt
->aseqno
= fr
->iseqno
;
3857 fh
->type
= fr
->af
.frametype
& 0xFF;
3858 if (fr
->af
.frametype
== AST_FRAME_VIDEO
)
3859 fh
->csub
= compress_subclass(fr
->af
.subclass
& ~0x1) | ((fr
->af
.subclass
& 0x1) << 6);
3861 fh
->csub
= compress_subclass(fr
->af
.subclass
);
3863 fr
->dcallno
= pvt
->transfercallno
;
3865 fr
->dcallno
= pvt
->peercallno
;
3866 fh
->dcallno
= htons(fr
->dcallno
);
3867 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_full_hdr
);
3870 /* Retry after 2x the ping time has passed */
3871 fr
->retrytime
= pvt
->pingtime
* 2;
3872 if (fr
->retrytime
< MIN_RETRY_TIME
)
3873 fr
->retrytime
= MIN_RETRY_TIME
;
3874 if (fr
->retrytime
> MAX_RETRY_TIME
)
3875 fr
->retrytime
= MAX_RETRY_TIME
;
3876 /* Acks' don't get retried */
3877 if ((f
->frametype
== AST_FRAME_IAX
) && (f
->subclass
== IAX_COMMAND_ACK
))
3879 else if (f
->frametype
== AST_FRAME_VOICE
)
3880 pvt
->svoiceformat
= f
->subclass
;
3881 else if (f
->frametype
== AST_FRAME_VIDEO
)
3882 pvt
->svideoformat
= f
->subclass
& ~0x1;
3883 if (ast_test_flag(pvt
, IAX_ENCRYPTED
)) {
3884 if (ast_test_flag(pvt
, IAX_KEYPOPULATED
)) {
3887 iax_showframe(fr
, NULL
, 2, &pvt
->transfer
, fr
->datalen
- sizeof(struct ast_iax2_full_hdr
));
3889 iax_showframe(fr
, NULL
, 2, &pvt
->addr
, fr
->datalen
- sizeof(struct ast_iax2_full_hdr
));
3891 encrypt_frame(&pvt
->ecx
, fh
, pvt
->semirand
, &fr
->datalen
);
3893 ast_log(LOG_WARNING
, "Supposed to send packet encrypted, but no key?\n");
3897 res
= send_packet(fr
);
3899 res
= iax2_transmit(fr
);
3901 if (ast_test_flag(pvt
, IAX_TRUNK
)) {
3902 iax2_trunk_queue(pvt
, fr
);
3904 } else if (fr
->af
.frametype
== AST_FRAME_VIDEO
) {
3905 /* Video frame have no sequence number */
3908 vh
= (struct ast_iax2_video_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_video_hdr
));
3910 vh
->callno
= htons(0x8000 | fr
->callno
);
3911 vh
->ts
= htons((fr
->ts
& 0x7FFF) | (fr
->af
.subclass
& 0x1 ? 0x8000 : 0));
3912 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_video_hdr
);
3915 res
= send_packet(fr
);
3917 /* Mini-frames have no sequence number */
3920 /* Mini frame will do */
3921 mh
= (struct ast_iax2_mini_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_mini_hdr
));
3922 mh
->callno
= htons(fr
->callno
);
3923 mh
->ts
= htons(fr
->ts
& 0xFFFF);
3924 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_mini_hdr
);
3927 if (pvt
->transferring
== TRANSFER_MEDIAPASS
)
3929 if (ast_test_flag(pvt
, IAX_ENCRYPTED
)) {
3930 if (ast_test_flag(pvt
, IAX_KEYPOPULATED
)) {
3931 encrypt_frame(&pvt
->ecx
, (struct ast_iax2_full_hdr
*)mh
, pvt
->semirand
, &fr
->datalen
);
3933 ast_log(LOG_WARNING
, "Supposed to send packet encrypted, but no key?\n");
3935 res
= send_packet(fr
);
3941 static int iax2_show_users(int fd
, int argc
, char *argv
[])
3944 int havepattern
= 0;
3946 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
3947 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
3949 struct iax2_user
*user
= NULL
;
3955 if (!strcasecmp(argv
[3], "like")) {
3956 if (regcomp(®exbuf
, argv
[4], REG_EXTENDED
| REG_NOSUB
))
3957 return RESULT_SHOWUSAGE
;
3960 return RESULT_SHOWUSAGE
;
3964 return RESULT_SHOWUSAGE
;
3967 ast_cli(fd
, FORMAT
, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
3968 AST_LIST_LOCK(&users
);
3969 AST_LIST_TRAVERSE(&users
, user
, entry
) {
3970 if (havepattern
&& regexec(®exbuf
, user
->name
, 0, NULL
, 0))
3973 if (!ast_strlen_zero(user
->secret
)) {
3974 ast_copy_string(auth
,user
->secret
,sizeof(auth
));
3975 } else if (!ast_strlen_zero(user
->inkeys
)) {
3976 snprintf(auth
, sizeof(auth
), "Key: %-15.15s ", user
->inkeys
);
3978 ast_copy_string(auth
, "-no secret-", sizeof(auth
));
3980 if(ast_test_flag(user
,IAX_CODEC_NOCAP
))
3982 else if(ast_test_flag(user
,IAX_CODEC_NOPREFS
))
3985 pstr
= ast_test_flag(user
,IAX_CODEC_USER_FIRST
) ? "Caller" : "Host";
3987 ast_cli(fd
, FORMAT2
, user
->name
, auth
, user
->authmethods
,
3988 user
->contexts
? user
->contexts
->context
: context
,
3989 user
->ha
? "Yes" : "No", pstr
);
3992 AST_LIST_UNLOCK(&users
);
3997 return RESULT_SUCCESS
;
4002 static int __iax2_show_peers(int manager
, int fd
, struct mansession
*s
, int argc
, char *argv
[])
4005 int havepattern
= 0;
4006 int total_peers
= 0;
4007 int online_peers
= 0;
4008 int offline_peers
= 0;
4009 int unmonitored_peers
= 0;
4011 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
4012 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
4014 struct iax2_peer
*peer
= NULL
;
4016 int registeredonly
=0;
4017 char *term
= manager
? "\r\n" : "\n";
4021 if (!strcasecmp(argv
[3], "registered"))
4024 return RESULT_SHOWUSAGE
;
4025 if (!strcasecmp(argv
[4], "like")) {
4026 if (regcomp(®exbuf
, argv
[5], REG_EXTENDED
| REG_NOSUB
))
4027 return RESULT_SHOWUSAGE
;
4030 return RESULT_SHOWUSAGE
;
4033 if (!strcasecmp(argv
[3], "like")) {
4034 if (regcomp(®exbuf
, argv
[4], REG_EXTENDED
| REG_NOSUB
))
4035 return RESULT_SHOWUSAGE
;
4038 return RESULT_SHOWUSAGE
;
4041 if (!strcasecmp(argv
[3], "registered"))
4044 return RESULT_SHOWUSAGE
;
4049 return RESULT_SHOWUSAGE
;
4054 astman_append(s
, FORMAT2
, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term
);
4056 ast_cli(fd
, FORMAT2
, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term
);
4058 AST_LIST_LOCK(&peers
);
4059 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
4065 if (registeredonly
&& !peer
->addr
.sin_addr
.s_addr
)
4067 if (havepattern
&& regexec(®exbuf
, peer
->name
, 0, NULL
, 0))
4070 if (!ast_strlen_zero(peer
->username
))
4071 snprintf(name
, sizeof(name
), "%s/%s", peer
->name
, peer
->username
);
4073 ast_copy_string(name
, peer
->name
, sizeof(name
));
4075 retstatus
= peer_status(peer
, status
, sizeof(status
));
4078 else if (!retstatus
)
4081 unmonitored_peers
++;
4083 ast_copy_string(nm
, ast_inet_ntoa(peer
->mask
), sizeof(nm
));
4085 snprintf(srch
, sizeof(srch
), FORMAT
, name
,
4086 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "(Unspecified)",
4087 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4089 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4090 peer
->encmethods
? "(E)" : " ", status
, term
);
4093 astman_append(s
, FORMAT
, name
,
4094 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa( peer
->addr
.sin_addr
) : "(Unspecified)",
4095 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4097 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4098 peer
->encmethods
? "(E)" : " ", status
, term
);
4100 ast_cli(fd
, FORMAT
, name
,
4101 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "(Unspecified)",
4102 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4104 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4105 peer
->encmethods
? "(E)" : " ", status
, term
);
4108 AST_LIST_UNLOCK(&peers
);
4111 astman_append(s
,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers
, online_peers
, offline_peers
, unmonitored_peers
, term
);
4113 ast_cli(fd
,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers
, online_peers
, offline_peers
, unmonitored_peers
, term
);
4118 return RESULT_SUCCESS
;
4123 static int iax2_show_threads(int fd
, int argc
, char *argv
[])
4125 struct iax2_thread
*thread
= NULL
;
4127 int threadcount
= 0, dynamiccount
= 0;
4131 return RESULT_SHOWUSAGE
;
4133 ast_cli(fd
, "IAX2 Thread Information\n");
4135 ast_cli(fd
, "Idle Threads:\n");
4136 AST_LIST_LOCK(&idle_list
);
4137 AST_LIST_TRAVERSE(&idle_list
, thread
, list
) {
4138 #ifdef DEBUG_SCHED_MULTITHREAD
4139 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4140 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4142 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d\n",
4143 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4147 AST_LIST_UNLOCK(&idle_list
);
4148 ast_cli(fd
, "Active Threads:\n");
4149 AST_LIST_LOCK(&active_list
);
4150 AST_LIST_TRAVERSE(&active_list
, thread
, list
) {
4151 if (thread
->type
== IAX_TYPE_DYNAMIC
)
4155 #ifdef DEBUG_SCHED_MULTITHREAD
4156 ast_cli(fd
, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
4157 type
, thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4159 ast_cli(fd
, "Thread %c%d: state=%d, update=%d, actions=%d\n",
4160 type
, thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4164 AST_LIST_UNLOCK(&active_list
);
4165 ast_cli(fd
, "Dynamic Threads:\n");
4166 AST_LIST_LOCK(&dynamic_list
);
4167 AST_LIST_TRAVERSE(&dynamic_list
, thread
, list
) {
4168 #ifdef DEBUG_SCHED_MULTITHREAD
4169 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4170 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4172 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d\n",
4173 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4177 AST_LIST_UNLOCK(&dynamic_list
);
4178 ast_cli(fd
, "%d of %d threads accounted for with %d dynamic threads\n", threadcount
, iaxthreadcount
, dynamiccount
);
4179 return RESULT_SUCCESS
;
4182 static int iax2_show_peers(int fd
, int argc
, char *argv
[])
4184 return __iax2_show_peers(0, fd
, NULL
, argc
, argv
);
4186 static int manager_iax2_show_netstats( struct mansession
*s
, struct message
*m
)
4188 ast_cli_netstats(s
, -1, 0);
4189 astman_append(s
, "\r\n");
4190 return RESULT_SUCCESS
;
4193 static int iax2_show_firmware(int fd
, int argc
, char *argv
[])
4195 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
4196 #if !defined(__FreeBSD__)
4197 #define FORMAT "%-15.15s %-15d %-15d\n"
4198 #else /* __FreeBSD__ */
4199 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */
4200 #endif /* __FreeBSD__ */
4201 struct iax_firmware
*cur
;
4202 if ((argc
!= 3) && (argc
!= 4))
4203 return RESULT_SHOWUSAGE
;
4204 ast_mutex_lock(&waresl
.lock
);
4206 ast_cli(fd
, FORMAT2
, "Device", "Version", "Size");
4207 for (cur
= waresl
.wares
;cur
;cur
= cur
->next
) {
4208 if ((argc
== 3) || (!strcasecmp(argv
[3], (char *)cur
->fwh
->devname
)))
4209 ast_cli(fd
, FORMAT
, cur
->fwh
->devname
, ntohs(cur
->fwh
->version
),
4210 (int)ntohl(cur
->fwh
->datalen
));
4212 ast_mutex_unlock(&waresl
.lock
);
4213 return RESULT_SUCCESS
;
4218 /* JDG: callback to display iax peers in manager */
4219 static int manager_iax2_show_peers( struct mansession
*s
, struct message
*m
)
4221 char *a
[] = { "iax2", "show", "users" };
4224 id
= astman_get_header(m
,"ActionID");
4225 if (!ast_strlen_zero(id
))
4226 astman_append(s
, "ActionID: %s\r\n",id
);
4227 ret
= __iax2_show_peers(1, -1, s
, 3, a
);
4228 astman_append(s
, "\r\n\r\n" );
4232 static char *regstate2str(int regstate
)
4235 case REG_STATE_UNREGISTERED
:
4236 return "Unregistered";
4237 case REG_STATE_REGSENT
:
4238 return "Request Sent";
4239 case REG_STATE_AUTHSENT
:
4240 return "Auth. Sent";
4241 case REG_STATE_REGISTERED
:
4242 return "Registered";
4243 case REG_STATE_REJECTED
:
4245 case REG_STATE_TIMEOUT
:
4247 case REG_STATE_NOAUTH
:
4248 return "No Authentication";
4254 static int iax2_show_registry(int fd
, int argc
, char *argv
[])
4256 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
4257 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
4258 struct iax2_registry
*reg
= NULL
;
4263 return RESULT_SHOWUSAGE
;
4264 AST_LIST_LOCK(&peers
);
4265 ast_cli(fd
, FORMAT2
, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
4266 for (reg
= registrations
;reg
;reg
= reg
->next
) {
4267 snprintf(host
, sizeof(host
), "%s:%d", ast_inet_ntoa(reg
->addr
.sin_addr
), ntohs(reg
->addr
.sin_port
));
4268 if (reg
->us
.sin_addr
.s_addr
)
4269 snprintf(perceived
, sizeof(perceived
), "%s:%d", ast_inet_ntoa(reg
->us
.sin_addr
), ntohs(reg
->us
.sin_port
));
4271 ast_copy_string(perceived
, "<Unregistered>", sizeof(perceived
));
4272 ast_cli(fd
, FORMAT
, host
,
4273 (reg
->dnsmgr
) ? "Y" : "N",
4274 reg
->username
, perceived
, reg
->refresh
, regstate2str(reg
->regstate
));
4276 AST_LIST_UNLOCK(&peers
);
4277 return RESULT_SUCCESS
;
4282 static int iax2_show_channels(int fd
, int argc
, char *argv
[])
4284 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
4285 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
4286 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
4291 return RESULT_SHOWUSAGE
;
4292 ast_cli(fd
, FORMAT2
, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
4293 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
4294 ast_mutex_lock(&iaxsl
[x
]);
4296 int lag
, jitter
, localdelay
;
4299 if(ast_test_flag(iaxs
[x
], IAX_USEJITTERBUF
)) {
4300 jb_getinfo(iaxs
[x
]->jb
, &jbinfo
);
4301 jitter
= jbinfo
.jitter
;
4302 localdelay
= jbinfo
.current
- jbinfo
.min
;
4307 lag
= iaxs
[x
]->remote_rr
.delay
;
4309 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4310 ast_inet_ntoa(iaxs
[x
]->addr
.sin_addr
),
4311 S_OR(iaxs
[x
]->username
, "(None)"),
4312 iaxs
[x
]->callno
, iaxs
[x
]->peercallno
,
4313 iaxs
[x
]->oseqno
, iaxs
[x
]->iseqno
,
4317 ast_getformatname(iaxs
[x
]->voiceformat
) );
4320 ast_mutex_unlock(&iaxsl
[x
]);
4322 ast_cli(fd
, "%d active IAX channel%s\n", numchans
, (numchans
!= 1) ? "s" : "");
4323 return RESULT_SUCCESS
;
4329 static int ast_cli_netstats(struct mansession
*s
, int fd
, int limit_fmt
)
4333 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
4334 ast_mutex_lock(&iaxsl
[x
]);
4336 int localjitter
, localdelay
, locallost
, locallosspct
, localdropped
, localooo
;
4340 if(ast_test_flag(iaxs
[x
], IAX_USEJITTERBUF
)) {
4341 jb_getinfo(iaxs
[x
]->jb
, &jbinfo
);
4342 localjitter
= jbinfo
.jitter
;
4343 localdelay
= jbinfo
.current
- jbinfo
.min
;
4344 locallost
= jbinfo
.frames_lost
;
4345 locallosspct
= jbinfo
.losspct
/1000;
4346 localdropped
= jbinfo
.frames_dropped
;
4347 localooo
= jbinfo
.frames_ooo
;
4357 fmt
= "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
4359 fmt
= "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
4362 astman_append(s
, fmt
,
4363 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4371 iaxs
[x
]->frames_received
/1000,
4372 iaxs
[x
]->remote_rr
.jitter
,
4373 iaxs
[x
]->remote_rr
.delay
,
4374 iaxs
[x
]->remote_rr
.losscnt
,
4375 iaxs
[x
]->remote_rr
.losspct
,
4376 iaxs
[x
]->remote_rr
.dropped
,
4377 iaxs
[x
]->remote_rr
.ooo
,
4378 iaxs
[x
]->remote_rr
.packets
/1000);
4381 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4389 iaxs
[x
]->frames_received
/1000,
4390 iaxs
[x
]->remote_rr
.jitter
,
4391 iaxs
[x
]->remote_rr
.delay
,
4392 iaxs
[x
]->remote_rr
.losscnt
,
4393 iaxs
[x
]->remote_rr
.losspct
,
4394 iaxs
[x
]->remote_rr
.dropped
,
4395 iaxs
[x
]->remote_rr
.ooo
,
4396 iaxs
[x
]->remote_rr
.packets
/1000
4400 ast_mutex_unlock(&iaxsl
[x
]);
4405 static int iax2_show_netstats(int fd
, int argc
, char *argv
[])
4409 return RESULT_SHOWUSAGE
;
4410 ast_cli(fd
, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
4411 ast_cli(fd
, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
4412 numchans
= ast_cli_netstats(NULL
, fd
, 1);
4413 ast_cli(fd
, "%d active IAX channel%s\n", numchans
, (numchans
!= 1) ? "s" : "");
4414 return RESULT_SUCCESS
;
4417 static int iax2_do_debug(int fd
, int argc
, char *argv
[])
4420 return RESULT_SHOWUSAGE
;
4422 ast_cli(fd
, "IAX2 Debugging Enabled\n");
4423 return RESULT_SUCCESS
;
4426 static int iax2_do_trunk_debug(int fd
, int argc
, char *argv
[])
4429 return RESULT_SHOWUSAGE
;
4431 ast_cli(fd
, "IAX2 Trunk Debug Requested\n");
4432 return RESULT_SUCCESS
;
4435 static int iax2_do_jb_debug(int fd
, int argc
, char *argv
[])
4438 return RESULT_SHOWUSAGE
;
4439 jb_setoutput(jb_error_output
, jb_warning_output
, jb_debug_output
);
4440 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Enabled\n");
4441 return RESULT_SUCCESS
;
4444 static int iax2_no_debug_deprecated(int fd
, int argc
, char *argv
[])
4447 return RESULT_SHOWUSAGE
;
4449 ast_cli(fd
, "IAX2 Debugging Disabled\n");
4450 return RESULT_SUCCESS
;
4453 static int iax2_no_debug(int fd
, int argc
, char *argv
[])
4456 return RESULT_SHOWUSAGE
;
4458 ast_cli(fd
, "IAX2 Debugging Disabled\n");
4459 return RESULT_SUCCESS
;
4462 static int iax2_no_trunk_debug_deprecated(int fd
, int argc
, char *argv
[])
4465 return RESULT_SHOWUSAGE
;
4467 ast_cli(fd
, "IAX2 Trunk Debugging Disabled\n");
4468 return RESULT_SUCCESS
;
4471 static int iax2_no_trunk_debug(int fd
, int argc
, char *argv
[])
4474 return RESULT_SHOWUSAGE
;
4476 ast_cli(fd
, "IAX2 Trunk Debugging Disabled\n");
4477 return RESULT_SUCCESS
;
4480 static int iax2_no_jb_debug_deprecated(int fd
, int argc
, char *argv
[])
4483 return RESULT_SHOWUSAGE
;
4484 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
4485 jb_debug_output("\n");
4486 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Disabled\n");
4487 return RESULT_SUCCESS
;
4490 static int iax2_no_jb_debug(int fd
, int argc
, char *argv
[])
4493 return RESULT_SHOWUSAGE
;
4494 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
4495 jb_debug_output("\n");
4496 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Disabled\n");
4497 return RESULT_SUCCESS
;
4500 static int iax2_write(struct ast_channel
*c
, struct ast_frame
*f
)
4502 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
4504 ast_mutex_lock(&iaxsl
[callno
]);
4506 /* If there's an outstanding error, return failure now */
4507 if (!iaxs
[callno
]->error
) {
4508 if (ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
))
4510 /* Don't waste bandwidth sending null frames */
4511 else if (f
->frametype
== AST_FRAME_NULL
)
4513 else if ((f
->frametype
== AST_FRAME_VOICE
) && ast_test_flag(iaxs
[callno
], IAX_QUELCH
))
4515 else if (!ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_STARTED
))
4518 /* Simple, just queue for transmission */
4519 res
= iax2_send(iaxs
[callno
], f
, 0, -1, 0, 0, 0);
4521 ast_log(LOG_DEBUG
, "Write error: %s\n", strerror(errno
));
4524 /* If it's already gone, just return */
4525 ast_mutex_unlock(&iaxsl
[callno
]);
4529 static int __send_command(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
,
4530 int now
, int transfer
, int final
)
4534 f
.subclass
= command
;
4535 f
.datalen
= datalen
;
4539 f
.src
= (char *)__FUNCTION__
;
4540 f
.data
= (char *)data
;
4541 return iax2_send(i
, &f
, ts
, seqno
, now
, transfer
, final
);
4544 static int send_command(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4546 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 0, 0, 0);
4549 static int send_command_locked(unsigned short callno
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4552 ast_mutex_lock(&iaxsl
[callno
]);
4553 res
= send_command(iaxs
[callno
], type
, command
, ts
, data
, datalen
, seqno
);
4554 ast_mutex_unlock(&iaxsl
[callno
]);
4558 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
)
4560 /* It is assumed that the callno has already been locked */
4561 iax2_predestroy_nolock(i
->callno
);
4562 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 0, 0, 1);
4565 static int send_command_immediate(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4567 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 1, 0, 0);
4570 static int send_command_transfer(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
)
4572 return __send_command(i
, type
, command
, ts
, data
, datalen
, 0, 0, 1, 0);
4575 static int apply_context(struct iax2_context
*con
, const char *context
)
4578 if (!strcmp(con
->context
, context
) || !strcmp(con
->context
, "*"))
4586 static int check_access(int callno
, struct sockaddr_in
*sin
, struct iax_ies
*ies
)
4588 /* Start pessimistic */
4591 struct iax2_user
*user
= NULL
, *best
= NULL
;
4593 int gotcapability
= 0;
4594 struct ast_variable
*v
= NULL
, *tmpvar
= NULL
;
4598 if (ies
->called_number
)
4599 ast_string_field_set(iaxs
[callno
], exten
, ies
->called_number
);
4600 if (ies
->calling_number
) {
4601 ast_shrink_phone_number(ies
->calling_number
);
4602 ast_string_field_set(iaxs
[callno
], cid_num
, ies
->calling_number
);
4604 if (ies
->calling_name
)
4605 ast_string_field_set(iaxs
[callno
], cid_name
, ies
->calling_name
);
4606 if (ies
->calling_ani
)
4607 ast_string_field_set(iaxs
[callno
], ani
, ies
->calling_ani
);
4609 ast_string_field_set(iaxs
[callno
], dnid
, ies
->dnid
);
4611 ast_string_field_set(iaxs
[callno
], rdnis
, ies
->rdnis
);
4612 if (ies
->called_context
)
4613 ast_string_field_set(iaxs
[callno
], context
, ies
->called_context
);
4615 ast_string_field_set(iaxs
[callno
], language
, ies
->language
);
4617 ast_string_field_set(iaxs
[callno
], username
, ies
->username
);
4618 if (ies
->calling_ton
> -1)
4619 iaxs
[callno
]->calling_ton
= ies
->calling_ton
;
4620 if (ies
->calling_tns
> -1)
4621 iaxs
[callno
]->calling_tns
= ies
->calling_tns
;
4622 if (ies
->calling_pres
> -1)
4623 iaxs
[callno
]->calling_pres
= ies
->calling_pres
;
4625 iaxs
[callno
]->peerformat
= ies
->format
;
4627 iaxs
[callno
]->peeradsicpe
= ies
->adsicpe
;
4628 if (ies
->capability
) {
4630 iaxs
[callno
]->peercapability
= ies
->capability
;
4633 version
= ies
->version
;
4635 /* Use provided preferences until told otherwise for actual preferences */
4636 if(ies
->codec_prefs
) {
4637 ast_codec_pref_convert(&iaxs
[callno
]->rprefs
, ies
->codec_prefs
, 32, 0);
4638 ast_codec_pref_convert(&iaxs
[callno
]->prefs
, ies
->codec_prefs
, 32, 0);
4642 iaxs
[callno
]->peercapability
= iaxs
[callno
]->peerformat
;
4643 if (version
> IAX_PROTO_VERSION
) {
4644 ast_log(LOG_WARNING
, "Peer '%s' has too new a protocol version (%d) for me\n",
4645 ast_inet_ntoa(sin
->sin_addr
), version
);
4648 /* Search the userlist for a compatible entry, and fill in the rest */
4649 AST_LIST_LOCK(&users
);
4650 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4651 if ((ast_strlen_zero(iaxs
[callno
]->username
) || /* No username specified */
4652 !strcmp(iaxs
[callno
]->username
, user
->name
)) /* Or this username specified */
4653 && ast_apply_ha(user
->ha
, sin
) /* Access is permitted from this IP */
4654 && (ast_strlen_zero(iaxs
[callno
]->context
) || /* No context specified */
4655 apply_context(user
->contexts
, iaxs
[callno
]->context
))) { /* Context is permitted */
4656 if (!ast_strlen_zero(iaxs
[callno
]->username
)) {
4657 /* Exact match, stop right now. */
4660 } else if (ast_strlen_zero(user
->secret
) && ast_strlen_zero(user
->inkeys
)) {
4661 /* No required authentication */
4663 /* There was host authentication and we passed, bonus! */
4664 if (bestscore
< 4) {
4669 /* No host access, but no secret, either, not bad */
4670 if (bestscore
< 3) {
4677 /* Authentication, but host access too, eh, it's something.. */
4678 if (bestscore
< 2) {
4683 /* Authentication and no host access... This is our baseline */
4684 if (bestscore
< 1) {
4692 AST_LIST_UNLOCK(&users
);
4694 if (!user
&& !ast_strlen_zero(iaxs
[callno
]->username
)) {
4695 user
= realtime_user(iaxs
[callno
]->username
);
4696 if (user
&& !ast_strlen_zero(iaxs
[callno
]->context
) && /* No context specified */
4697 !apply_context(user
->contexts
, iaxs
[callno
]->context
)) { /* Context is permitted */
4703 /* We found our match (use the first) */
4705 for (v
= user
->vars
; v
; v
= v
->next
) {
4706 if((tmpvar
= ast_variable_new(v
->name
, v
->value
))) {
4707 tmpvar
->next
= iaxs
[callno
]->vars
;
4708 iaxs
[callno
]->vars
= tmpvar
;
4711 /* If a max AUTHREQ restriction is in place, activate it */
4712 if (user
->maxauthreq
> 0)
4713 ast_set_flag(iaxs
[callno
], IAX_MAXAUTHREQ
);
4714 iaxs
[callno
]->prefs
= user
->prefs
;
4715 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_USER_FIRST
);
4716 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_NOPREFS
);
4717 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_NOCAP
);
4718 iaxs
[callno
]->encmethods
= user
->encmethods
;
4719 /* Store the requested username if not specified */
4720 if (ast_strlen_zero(iaxs
[callno
]->username
))
4721 ast_string_field_set(iaxs
[callno
], username
, user
->name
);
4722 /* Store whether this is a trunked call, too, of course, and move if appropriate */
4723 ast_copy_flags(iaxs
[callno
], user
, IAX_TRUNK
);
4724 iaxs
[callno
]->capability
= user
->capability
;
4725 /* And use the default context */
4726 if (ast_strlen_zero(iaxs
[callno
]->context
)) {
4728 ast_string_field_set(iaxs
[callno
], context
, user
->contexts
->context
);
4730 ast_string_field_set(iaxs
[callno
], context
, context
);
4732 /* And any input keys */
4733 ast_string_field_set(iaxs
[callno
], inkeys
, user
->inkeys
);
4734 /* And the permitted authentication methods */
4735 iaxs
[callno
]->authmethods
= user
->authmethods
;
4736 iaxs
[callno
]->adsi
= user
->adsi
;
4737 /* If they have callerid, override the given caller id. Always store the ANI */
4738 if (!ast_strlen_zero(iaxs
[callno
]->cid_num
) || !ast_strlen_zero(iaxs
[callno
]->cid_name
)) {
4739 if (ast_test_flag(user
, IAX_HASCALLERID
)) {
4740 iaxs
[callno
]->calling_tns
= 0;
4741 iaxs
[callno
]->calling_ton
= 0;
4742 ast_string_field_set(iaxs
[callno
], cid_num
, user
->cid_num
);
4743 ast_string_field_set(iaxs
[callno
], cid_name
, user
->cid_name
);
4744 iaxs
[callno
]->calling_pres
= AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
;
4746 if (ast_strlen_zero(iaxs
[callno
]->ani
))
4747 ast_string_field_set(iaxs
[callno
], ani
, user
->cid_num
);
4749 iaxs
[callno
]->calling_pres
= AST_PRES_NUMBER_NOT_AVAILABLE
;
4751 if (!ast_strlen_zero(user
->accountcode
))
4752 ast_string_field_set(iaxs
[callno
], accountcode
, user
->accountcode
);
4753 if (!ast_strlen_zero(user
->mohinterpret
))
4754 ast_string_field_set(iaxs
[callno
], mohinterpret
, user
->mohinterpret
);
4755 if (!ast_strlen_zero(user
->mohsuggest
))
4756 ast_string_field_set(iaxs
[callno
], mohsuggest
, user
->mohsuggest
);
4758 iaxs
[callno
]->amaflags
= user
->amaflags
;
4759 if (!ast_strlen_zero(user
->language
))
4760 ast_string_field_set(iaxs
[callno
], language
, user
->language
);
4761 ast_copy_flags(iaxs
[callno
], user
, IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
4762 /* Keep this check last */
4763 if (!ast_strlen_zero(user
->dbsecret
)) {
4764 char *family
, *key
=NULL
;
4766 family
= ast_strdupa(user
->dbsecret
);
4767 key
= strchr(family
, '/');
4772 if (!key
|| ast_db_get(family
, key
, buf
, sizeof(buf
))) {
4773 ast_log(LOG_WARNING
, "Unable to retrieve database password for family/key '%s'!\n", user
->dbsecret
);
4774 if (ast_test_flag(user
, IAX_TEMPONLY
)) {
4779 ast_string_field_set(iaxs
[callno
], secret
, buf
);
4781 ast_string_field_set(iaxs
[callno
], secret
, user
->secret
);
4784 ast_set2_flag(iaxs
[callno
], iax2_getpeertrunk(*sin
), IAX_TRUNK
);
4788 static int raw_hangup(struct sockaddr_in
*sin
, unsigned short src
, unsigned short dst
, int sockfd
)
4790 struct ast_iax2_full_hdr fh
;
4791 fh
.scallno
= htons(src
| IAX_FLAG_FULL
);
4792 fh
.dcallno
= htons(dst
);
4796 fh
.type
= AST_FRAME_IAX
;
4797 fh
.csub
= compress_subclass(IAX_COMMAND_INVAL
);
4799 iax_showframe(NULL
, &fh
, 0, sin
, 0);
4803 ast_log(LOG_DEBUG
, "Raw Hangup %s:%d, src=%d, dst=%d\n",
4804 ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), src
, dst
);
4805 return sendto(sockfd
, &fh
, sizeof(fh
), 0, (struct sockaddr
*)sin
, sizeof(*sin
));
4808 static void merge_encryption(struct chan_iax2_pvt
*p
, unsigned int enc
)
4810 /* Select exactly one common encryption if there are any */
4811 p
->encmethods
&= enc
;
4812 if (p
->encmethods
) {
4813 if (p
->encmethods
& IAX_ENCRYPT_AES128
)
4814 p
->encmethods
= IAX_ENCRYPT_AES128
;
4820 static int authenticate_request(struct chan_iax2_pvt
*p
)
4822 struct iax2_user
*user
= NULL
;
4823 struct iax_ie_data ied
;
4824 int res
= -1, authreq_restrict
= 0;
4827 memset(&ied
, 0, sizeof(ied
));
4829 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
4830 if (ast_test_flag(p
, IAX_MAXAUTHREQ
)) {
4831 AST_LIST_LOCK(&users
);
4832 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4833 if (!strcmp(user
->name
, p
->username
)) {
4834 if (user
->curauthreq
== user
->maxauthreq
)
4835 authreq_restrict
= 1;
4841 AST_LIST_UNLOCK(&users
);
4844 /* If the AUTHREQ limit test failed, send back an error */
4845 if (authreq_restrict
) {
4846 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Unauthenticated call limit reached");
4847 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_CALL_REJECTED
);
4848 send_command_final(p
, AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied
.buf
, ied
.pos
, -1);
4852 iax_ie_append_short(&ied
, IAX_IE_AUTHMETHODS
, p
->authmethods
);
4853 if (p
->authmethods
& (IAX_AUTH_MD5
| IAX_AUTH_RSA
)) {
4854 snprintf(challenge
, sizeof(challenge
), "%d", (int)ast_random());
4855 ast_string_field_set(p
, challenge
, challenge
);
4856 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
4857 iax_ie_append_str(&ied
, IAX_IE_CHALLENGE
, p
->challenge
);
4860 iax_ie_append_short(&ied
, IAX_IE_ENCRYPTION
, p
->encmethods
);
4862 iax_ie_append_str(&ied
,IAX_IE_USERNAME
, p
->username
);
4864 res
= send_command(p
, AST_FRAME_IAX
, IAX_COMMAND_AUTHREQ
, 0, ied
.buf
, ied
.pos
, -1);
4867 ast_set_flag(p
, IAX_ENCRYPTED
);
4872 static int authenticate_verify(struct chan_iax2_pvt
*p
, struct iax_ies
*ies
)
4874 char requeststr
[256];
4875 char md5secret
[256] = "";
4876 char secret
[256] = "";
4877 char rsasecret
[256] = "";
4880 struct iax2_user
*user
= NULL
;
4882 if (ast_test_flag(p
, IAX_MAXAUTHREQ
)) {
4883 AST_LIST_LOCK(&users
);
4884 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4885 if (!strcmp(user
->name
, p
->username
)) {
4890 AST_LIST_UNLOCK(&users
);
4891 ast_clear_flag(p
, IAX_MAXAUTHREQ
);
4894 if (!ast_test_flag(&p
->state
, IAX_STATE_AUTHENTICATED
))
4897 ast_copy_string(secret
, ies
->password
, sizeof(secret
));
4898 if (ies
->md5_result
)
4899 ast_copy_string(md5secret
, ies
->md5_result
, sizeof(md5secret
));
4900 if (ies
->rsa_result
)
4901 ast_copy_string(rsasecret
, ies
->rsa_result
, sizeof(rsasecret
));
4902 if ((p
->authmethods
& IAX_AUTH_RSA
) && !ast_strlen_zero(rsasecret
) && !ast_strlen_zero(p
->inkeys
)) {
4903 struct ast_key
*key
;
4907 ast_copy_string(tmpkey
, p
->inkeys
, sizeof(tmpkey
));
4909 keyn
= strsep(&stringp
, ":");
4911 key
= ast_key_get(keyn
, AST_KEY_PUBLIC
);
4912 if (key
&& !ast_check_signature(key
, p
->challenge
, rsasecret
)) {
4916 ast_log(LOG_WARNING
, "requested inkey '%s' for RSA authentication does not exist\n", keyn
);
4917 keyn
= strsep(&stringp
, ":");
4919 } else if (p
->authmethods
& IAX_AUTH_MD5
) {
4920 struct MD5Context md5
;
4921 unsigned char digest
[16];
4922 char *tmppw
, *stringp
;
4924 tmppw
= ast_strdupa(p
->secret
);
4926 while((tmppw
= strsep(&stringp
, ";"))) {
4928 MD5Update(&md5
, (unsigned char *)p
->challenge
, strlen(p
->challenge
));
4929 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
4930 MD5Final(digest
, &md5
);
4931 /* If they support md5, authenticate with it. */
4933 sprintf(requeststr
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
4934 if (!strcasecmp(requeststr
, md5secret
)) {
4939 } else if (p
->authmethods
& IAX_AUTH_PLAINTEXT
) {
4940 if (!strcmp(secret
, p
->secret
))
4946 /*! \brief Verify inbound registration */
4947 static int register_verify(int callno
, struct sockaddr_in
*sin
, struct iax_ies
*ies
)
4949 char requeststr
[256] = "";
4950 char peer
[256] = "";
4951 char md5secret
[256] = "";
4952 char rsasecret
[256] = "";
4953 char secret
[256] = "";
4954 struct iax2_peer
*p
;
4955 struct ast_key
*key
;
4960 ast_clear_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
| IAX_STATE_UNCHANGED
);
4961 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
4963 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
4965 ast_copy_string(secret
, ies
->password
, sizeof(secret
));
4966 if (ies
->md5_result
)
4967 ast_copy_string(md5secret
, ies
->md5_result
, sizeof(md5secret
));
4968 if (ies
->rsa_result
)
4969 ast_copy_string(rsasecret
, ies
->rsa_result
, sizeof(rsasecret
));
4971 expire
= ies
->refresh
;
4973 if (ast_strlen_zero(peer
)) {
4974 ast_log(LOG_NOTICE
, "Empty registration from %s\n", ast_inet_ntoa(sin
->sin_addr
));
4977 /* We release the lock for the call to prevent a deadlock, but it's okay because
4978 only the current thread could possibly make it go away or make changes */
4979 ast_mutex_unlock(&iaxsl
[callno
]);
4980 /* SLD: first call to lookup peer during registration */
4981 p
= find_peer(peer
, 1);
4982 ast_mutex_lock(&iaxsl
[callno
]);
4984 if (!iaxs
[callno
]) {
4985 /* Call has disappeared */
4986 ast_mutex_unlock(&iaxsl
[callno
]);
4991 ast_log(LOG_NOTICE
, "No registration for peer '%s' (from %s)\n", peer
, ast_inet_ntoa(sin
->sin_addr
));
4995 if (!ast_test_flag(p
, IAX_DYNAMIC
)) {
4997 ast_log(LOG_NOTICE
, "Peer '%s' is not dynamic (from %s)\n", peer
, ast_inet_ntoa(sin
->sin_addr
));
4998 if (ast_test_flag(p
, IAX_TEMPONLY
))
5003 if (!ast_apply_ha(p
->ha
, sin
)) {
5005 ast_log(LOG_NOTICE
, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
);
5006 if (ast_test_flag(p
, IAX_TEMPONLY
))
5010 if (!inaddrcmp(&p
->addr
, sin
))
5011 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_UNCHANGED
);
5012 ast_string_field_set(iaxs
[callno
], secret
, p
->secret
);
5013 ast_string_field_set(iaxs
[callno
], inkeys
, p
->inkeys
);
5014 /* Check secret against what we have on file */
5015 if (!ast_strlen_zero(rsasecret
) && (p
->authmethods
& IAX_AUTH_RSA
) && !ast_strlen_zero(iaxs
[callno
]->challenge
)) {
5016 if (!ast_strlen_zero(p
->inkeys
)) {
5019 ast_copy_string(tmpkeys
, p
->inkeys
, sizeof(tmpkeys
));
5021 keyn
= strsep(&stringp
, ":");
5023 key
= ast_key_get(keyn
, AST_KEY_PUBLIC
);
5024 if (key
&& !ast_check_signature(key
, iaxs
[callno
]->challenge
, rsasecret
)) {
5025 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5028 ast_log(LOG_WARNING
, "requested inkey '%s' does not exist\n", keyn
);
5029 keyn
= strsep(&stringp
, ":");
5033 ast_log(LOG_NOTICE
, "Host %s failed RSA authentication with inkeys '%s'\n", peer
, p
->inkeys
);
5034 if (ast_test_flag(p
, IAX_TEMPONLY
))
5040 ast_log(LOG_NOTICE
, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer
);
5041 if (ast_test_flag(p
, IAX_TEMPONLY
))
5045 } else if (!ast_strlen_zero(md5secret
) && (p
->authmethods
& IAX_AUTH_MD5
) && !ast_strlen_zero(iaxs
[callno
]->challenge
)) {
5046 struct MD5Context md5
;
5047 unsigned char digest
[16];
5048 char *tmppw
, *stringp
;
5050 tmppw
= ast_strdupa(p
->secret
);
5052 while((tmppw
= strsep(&stringp
, ";"))) {
5054 MD5Update(&md5
, (unsigned char *)iaxs
[callno
]->challenge
, strlen(iaxs
[callno
]->challenge
));
5055 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
5056 MD5Final(digest
, &md5
);
5058 sprintf(requeststr
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
5059 if (!strcasecmp(requeststr
, md5secret
))
5063 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5066 ast_log(LOG_NOTICE
, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
, requeststr
, md5secret
);
5067 if (ast_test_flag(p
, IAX_TEMPONLY
))
5071 } else if (!ast_strlen_zero(secret
) && (p
->authmethods
& IAX_AUTH_PLAINTEXT
)) {
5072 /* They've provided a plain text password and we support that */
5073 if (strcmp(secret
, p
->secret
)) {
5075 ast_log(LOG_NOTICE
, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
);
5076 if (ast_test_flag(p
, IAX_TEMPONLY
))
5080 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5081 } else if (!ast_strlen_zero(md5secret
) || !ast_strlen_zero(secret
)) {
5083 ast_log(LOG_NOTICE
, "Inappropriate authentication received\n");
5084 if (ast_test_flag(p
, IAX_TEMPONLY
))
5088 ast_string_field_set(iaxs
[callno
], peer
, peer
);
5089 /* Choose lowest expiry number */
5090 if (expire
&& (expire
< iaxs
[callno
]->expiry
))
5091 iaxs
[callno
]->expiry
= expire
;
5093 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5095 if (ast_test_flag(p
, IAX_TEMPONLY
))
5101 static int authenticate(const char *challenge
, const char *secret
, const char *keyn
, int authmethods
, struct iax_ie_data
*ied
, struct sockaddr_in
*sin
, aes_encrypt_ctx
*ecx
, aes_decrypt_ctx
*dcx
)
5105 if (!ast_strlen_zero(keyn
)) {
5106 if (!(authmethods
& IAX_AUTH_RSA
)) {
5107 if (ast_strlen_zero(secret
))
5108 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
));
5109 } else if (ast_strlen_zero(challenge
)) {
5110 ast_log(LOG_NOTICE
, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin
->sin_addr
));
5113 struct ast_key
*key
;
5114 key
= ast_key_get(keyn
, AST_KEY_PRIVATE
);
5116 ast_log(LOG_NOTICE
, "Unable to find private key '%s'\n", keyn
);
5118 if (ast_sign(key
, (char*)challenge
, sig
)) {
5119 ast_log(LOG_NOTICE
, "Unable to sign challenge with key\n");
5122 iax_ie_append_str(ied
, IAX_IE_RSA_RESULT
, sig
);
5129 if (res
&& !ast_strlen_zero(secret
)) {
5130 if ((authmethods
& IAX_AUTH_MD5
) && !ast_strlen_zero(challenge
)) {
5131 struct MD5Context md5
;
5132 unsigned char digest
[16];
5135 MD5Update(&md5
, (unsigned char *)challenge
, strlen(challenge
));
5136 MD5Update(&md5
, (unsigned char *)secret
, strlen(secret
));
5137 MD5Final(digest
, &md5
);
5138 /* If they support md5, authenticate with it. */
5140 sprintf(digres
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
5142 build_enc_keys(digest
, ecx
, dcx
);
5143 iax_ie_append_str(ied
, IAX_IE_MD5_RESULT
, digres
);
5145 } else if (authmethods
& IAX_AUTH_PLAINTEXT
) {
5146 iax_ie_append_str(ied
, IAX_IE_PASSWORD
, secret
);
5149 ast_log(LOG_NOTICE
, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin
->sin_addr
), authmethods
);
5154 static int authenticate_reply(struct chan_iax2_pvt
*p
, struct sockaddr_in
*sin
, struct iax_ies
*ies
, const char *override
, const char *okey
)
5156 struct iax2_peer
*peer
= NULL
;
5157 /* Start pessimistic */
5159 int authmethods
= 0;
5160 struct iax_ie_data ied
;
5162 memset(&ied
, 0, sizeof(ied
));
5165 ast_string_field_set(p
, username
, ies
->username
);
5167 ast_string_field_set(p
, challenge
, ies
->challenge
);
5168 if (ies
->authmethods
)
5169 authmethods
= ies
->authmethods
;
5170 if (authmethods
& IAX_AUTH_MD5
)
5171 merge_encryption(p
, ies
->encmethods
);
5175 /* Check for override RSA authentication first */
5176 if (!ast_strlen_zero(override
) || !ast_strlen_zero(okey
)) {
5177 /* Normal password authentication */
5178 res
= authenticate(p
->challenge
, override
, okey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5180 AST_LIST_LOCK(&peers
);
5181 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
5182 if ((ast_strlen_zero(p
->peer
) || !strcmp(p
->peer
, peer
->name
))
5183 /* No peer specified at our end, or this is the peer */
5184 && (ast_strlen_zero(peer
->username
) || (!strcmp(peer
->username
, p
->username
)))
5185 /* No username specified in peer rule, or this is the right username */
5186 && (!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
)))
5187 /* No specified host, or this is our host */
5189 res
= authenticate(p
->challenge
, peer
->secret
, peer
->outkey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5194 AST_LIST_UNLOCK(&peers
);
5196 /* We checked our list and didn't find one. It's unlikely, but possible,
5197 that we're trying to authenticate *to* a realtime peer */
5198 if ((peer
= realtime_peer(p
->peer
, NULL
))) {
5199 res
= authenticate(p
->challenge
, peer
->secret
,peer
->outkey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5200 if (ast_test_flag(peer
, IAX_TEMPONLY
))
5205 if (ies
->encmethods
)
5206 ast_set_flag(p
, IAX_ENCRYPTED
| IAX_KEYPOPULATED
);
5208 res
= send_command(p
, AST_FRAME_IAX
, IAX_COMMAND_AUTHREP
, 0, ied
.buf
, ied
.pos
, -1);
5212 static int iax2_do_register(struct iax2_registry
*reg
);
5214 static void __iax2_do_register_s(void *data
)
5216 struct iax2_registry
*reg
= data
;
5218 iax2_do_register(reg
);
5221 static int iax2_do_register_s(void *data
)
5223 #ifdef SCHED_MULTITHREADED
5224 if (schedule_action(__iax2_do_register_s
, data
))
5226 __iax2_do_register_s(data
);
5230 static int try_transfer(struct chan_iax2_pvt
*pvt
, struct iax_ies
*ies
)
5234 struct iax_ie_data ied
;
5235 struct sockaddr_in
new;
5238 memset(&ied
, 0, sizeof(ied
));
5239 if (ies
->apparent_addr
)
5240 bcopy(ies
->apparent_addr
, &new, sizeof(new));
5242 newcall
= ies
->callno
;
5243 if (!newcall
|| !new.sin_addr
.s_addr
|| !new.sin_port
) {
5244 ast_log(LOG_WARNING
, "Invalid transfer request\n");
5247 pvt
->transfercallno
= newcall
;
5248 memcpy(&pvt
->transfer
, &new, sizeof(pvt
->transfer
));
5249 inet_aton(newip
, &pvt
->transfer
.sin_addr
);
5250 pvt
->transfer
.sin_family
= AF_INET
;
5251 pvt
->transferring
= TRANSFER_BEGIN
;
5252 pvt
->transferid
= ies
->transferid
;
5253 if (ies
->transferid
)
5254 iax_ie_append_int(&ied
, IAX_IE_TRANSFERID
, ies
->transferid
);
5255 send_command_transfer(pvt
, AST_FRAME_IAX
, IAX_COMMAND_TXCNT
, 0, ied
.buf
, ied
.pos
);
5259 static int complete_dpreply(struct chan_iax2_pvt
*pvt
, struct iax_ies
*ies
)
5261 char exten
[256] = "";
5262 int status
= CACHE_FLAG_UNKNOWN
;
5263 int expiry
= iaxdefaultdpcache
;
5266 struct iax2_dpcache
*dp
, *prev
;
5268 if (ies
->called_number
)
5269 ast_copy_string(exten
, ies
->called_number
, sizeof(exten
));
5271 if (ies
->dpstatus
& IAX_DPSTATUS_EXISTS
)
5272 status
= CACHE_FLAG_EXISTS
;
5273 else if (ies
->dpstatus
& IAX_DPSTATUS_CANEXIST
)
5274 status
= CACHE_FLAG_CANEXIST
;
5275 else if (ies
->dpstatus
& IAX_DPSTATUS_NONEXISTENT
)
5276 status
= CACHE_FLAG_NONEXISTENT
;
5278 if (ies
->dpstatus
& IAX_DPSTATUS_IGNOREPAT
) {
5279 /* Don't really do anything with this */
5282 expiry
= ies
->refresh
;
5283 if (ies
->dpstatus
& IAX_DPSTATUS_MATCHMORE
)
5284 matchmore
= CACHE_FLAG_MATCHMORE
;
5285 ast_mutex_lock(&dpcache_lock
);
5287 dp
= pvt
->dpentries
;
5289 if (!strcmp(dp
->exten
, exten
)) {
5292 prev
->peer
= dp
->peer
;
5294 pvt
->dpentries
= dp
->peer
;
5297 dp
->expiry
.tv_sec
= dp
->orig
.tv_sec
+ expiry
;
5298 if (dp
->flags
& CACHE_FLAG_PENDING
) {
5299 dp
->flags
&= ~CACHE_FLAG_PENDING
;
5300 dp
->flags
|= status
;
5301 dp
->flags
|= matchmore
;
5303 /* Wake up waiters */
5304 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
5305 if (dp
->waiters
[x
] > -1)
5306 write(dp
->waiters
[x
], "asdf", 4);
5311 ast_mutex_unlock(&dpcache_lock
);
5315 static int complete_transfer(int callno
, struct iax_ies
*ies
)
5318 struct chan_iax2_pvt
*pvt
= iaxs
[callno
];
5319 struct iax_frame
*cur
;
5323 peercallno
= ies
->callno
;
5325 if (peercallno
< 1) {
5326 ast_log(LOG_WARNING
, "Invalid transfer request\n");
5329 memcpy(&pvt
->addr
, &pvt
->transfer
, sizeof(pvt
->addr
));
5330 memset(&pvt
->transfer
, 0, sizeof(pvt
->transfer
));
5331 /* Reset sequence numbers */
5336 pvt
->peercallno
= peercallno
;
5337 pvt
->transferring
= TRANSFER_NONE
;
5338 pvt
->svoiceformat
= -1;
5339 pvt
->voiceformat
= 0;
5340 pvt
->svideoformat
= -1;
5341 pvt
->videoformat
= 0;
5342 pvt
->transfercallno
= -1;
5343 memset(&pvt
->rxcore
, 0, sizeof(pvt
->rxcore
));
5344 memset(&pvt
->offset
, 0, sizeof(pvt
->offset
));
5345 /* reset jitterbuffer */
5346 while(jb_getall(pvt
->jb
,&frame
) == JB_OK
)
5347 iax2_frame_free(frame
.data
);
5353 pvt
->pingtime
= DEFAULT_RETRY_TIME
;
5354 AST_LIST_LOCK(&iaxq
.queue
);
5355 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
5356 /* We must cancel any packets that would have been transmitted
5357 because now we're talking to someone new. It's okay, they
5358 were transmitted to someone that didn't care anyway. */
5359 if (callno
== cur
->callno
)
5362 AST_LIST_UNLOCK(&iaxq
.queue
);
5366 /*! \brief Acknowledgment received for OUR registration */
5367 static int iax2_ack_registry(struct iax_ies
*ies
, struct sockaddr_in
*sin
, int callno
)
5369 struct iax2_registry
*reg
;
5370 /* Start pessimistic */
5371 char peer
[256] = "";
5374 char ourip
[256] = "<Unspecified>";
5375 struct sockaddr_in oldus
;
5376 struct sockaddr_in us
;
5379 memset(&us
, 0, sizeof(us
));
5380 if (ies
->apparent_addr
)
5381 bcopy(ies
->apparent_addr
, &us
, sizeof(us
));
5383 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
5385 refresh
= ies
->refresh
;
5386 if (ies
->calling_number
) {
5387 /* We don't do anything with it really, but maybe we should */
5389 reg
= iaxs
[callno
]->reg
;
5391 ast_log(LOG_WARNING
, "Registry acknowledge on unknown registry '%s'\n", peer
);
5394 memcpy(&oldus
, ®
->us
, sizeof(oldus
));
5395 oldmsgs
= reg
->messages
;
5396 if (inaddrcmp(®
->addr
, sin
)) {
5397 ast_log(LOG_WARNING
, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin
->sin_addr
));
5400 memcpy(®
->us
, &us
, sizeof(reg
->us
));
5401 if (ies
->msgcount
>= 0)
5402 reg
->messages
= ies
->msgcount
& 0xffff; /* only low 16 bits are used in the transmission of the IE */
5403 /* always refresh the registration at the interval requested by the server
5404 we are registering to
5406 reg
->refresh
= refresh
;
5407 if (reg
->expire
> -1)
5408 ast_sched_del(sched
, reg
->expire
);
5409 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
5410 if (inaddrcmp(&oldus
, ®
->us
) || (reg
->messages
!= oldmsgs
)) {
5411 if (option_verbose
> 2) {
5412 if (reg
->messages
> 255)
5413 snprintf(msgstatus
, sizeof(msgstatus
), " with %d new and %d old messages waiting", reg
->messages
& 0xff, reg
->messages
>> 8);
5414 else if (reg
->messages
> 1)
5415 snprintf(msgstatus
, sizeof(msgstatus
), " with %d new messages waiting\n", reg
->messages
);
5416 else if (reg
->messages
> 0)
5417 snprintf(msgstatus
, sizeof(msgstatus
), " with 1 new message waiting\n");
5419 snprintf(msgstatus
, sizeof(msgstatus
), " with no messages waiting\n");
5420 snprintf(ourip
, sizeof(ourip
), "%s:%d", ast_inet_ntoa(reg
->us
.sin_addr
), ntohs(reg
->us
.sin_port
));
5421 ast_verbose(VERBOSE_PREFIX_3
"Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin
->sin_addr
), ourip
, msgstatus
);
5423 manager_event(EVENT_FLAG_SYSTEM
, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin
->sin_addr
));
5425 reg
->regstate
= REG_STATE_REGISTERED
;
5429 static int iax2_register(char *value
, int lineno
)
5431 struct iax2_registry
*reg
;
5433 char *username
, *hostname
, *secret
;
5439 ast_copy_string(copy
, value
, sizeof(copy
));
5441 username
= strsep(&stringp
, "@");
5442 hostname
= strsep(&stringp
, "@");
5444 ast_log(LOG_WARNING
, "Format for registration is user[:secret]@host[:port] at line %d", lineno
);
5448 username
= strsep(&stringp
, ":");
5449 secret
= strsep(&stringp
, ":");
5451 hostname
= strsep(&stringp
, ":");
5452 porta
= strsep(&stringp
, ":");
5454 if (porta
&& !atoi(porta
)) {
5455 ast_log(LOG_WARNING
, "%s is not a valid port number at line %d\n", porta
, lineno
);
5458 if (!(reg
= ast_calloc(1, sizeof(*reg
))))
5460 if (ast_dnsmgr_lookup(hostname
, ®
->addr
.sin_addr
, ®
->dnsmgr
) < 0) {
5464 ast_copy_string(reg
->username
, username
, sizeof(reg
->username
));
5466 ast_copy_string(reg
->secret
, secret
, sizeof(reg
->secret
));
5468 reg
->refresh
= IAX_DEFAULT_REG_EXPIRE
;
5469 reg
->addr
.sin_family
= AF_INET
;
5470 reg
->addr
.sin_port
= porta
? htons(atoi(porta
)) : htons(IAX_DEFAULT_PORTNO
);
5471 reg
->next
= registrations
;
5473 registrations
= reg
;
5478 static void register_peer_exten(struct iax2_peer
*peer
, int onoff
)
5481 char *stringp
, *ext
;
5482 if (!ast_strlen_zero(regcontext
)) {
5483 ast_copy_string(multi
, S_OR(peer
->regexten
, peer
->name
), sizeof(multi
));
5485 while((ext
= strsep(&stringp
, "&"))) {
5487 if (!ast_exists_extension(NULL
, regcontext
, ext
, 1, NULL
))
5488 ast_add_extension(regcontext
, 1, ext
, 1, NULL
, NULL
,
5489 "Noop", ast_strdup(peer
->name
), ast_free
, "IAX2");
5491 ast_context_remove_extension(regcontext
, ext
, 1, NULL
);
5495 static void prune_peers(void);
5497 static void __expire_registry(void *data
)
5500 struct iax2_peer
*p
= NULL
;
5502 /* Go through and grab this peer... and if it needs to be removed... then do it */
5503 AST_LIST_LOCK(&peers
);
5504 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers
, p
, entry
) {
5505 if (!strcasecmp(p
->name
, name
)) {
5510 AST_LIST_TRAVERSE_SAFE_END
5511 AST_LIST_UNLOCK(&peers
);
5513 /* Peer is already gone for whatever reason */
5517 ast_log(LOG_DEBUG
, "Expiring registration for peer '%s'\n", p
->name
);
5518 if (ast_test_flag((&globalflags
), IAX_RTUPDATE
) && (ast_test_flag(p
, IAX_TEMPONLY
|IAX_RTCACHEFRIENDS
)))
5519 realtime_update_peer(p
->name
, &p
->addr
, 0);
5520 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p
->name
);
5521 /* Reset the address */
5522 memset(&p
->addr
, 0, sizeof(p
->addr
));
5523 /* Reset expiry value */
5524 p
->expiry
= min_reg_expire
;
5525 if (!ast_test_flag(p
, IAX_TEMPONLY
))
5526 ast_db_del("IAX/Registry", p
->name
);
5527 register_peer_exten(p
, 0);
5528 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5530 iax2_regfunk(p
->name
, 0);
5532 if (ast_test_flag(p
, IAX_RTAUTOCLEAR
)) {
5533 ast_set_flag(p
, IAX_DELME
);
5538 static int expire_registry(void *data
)
5540 #ifdef SCHED_MULTITHREADED
5541 if (schedule_action(__expire_registry
, data
))
5543 __expire_registry(data
);
5547 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
);
5549 static void reg_source_db(struct iax2_peer
*p
)
5554 if (!ast_test_flag(p
, IAX_TEMPONLY
) && (!ast_db_get("IAX/Registry", p
->name
, data
, sizeof(data
)))) {
5555 c
= strchr(data
, ':');
5559 if (inet_aton(data
, &in
)) {
5564 if (option_verbose
> 2)
5565 ast_verbose(VERBOSE_PREFIX_3
"Seeding '%s' at %s:%d for %d\n", p
->name
,
5566 ast_inet_ntoa(in
), atoi(c
), atoi(d
));
5567 iax2_poke_peer(p
, 0);
5568 p
->expiry
= atoi(d
);
5569 memset(&p
->addr
, 0, sizeof(p
->addr
));
5570 p
->addr
.sin_family
= AF_INET
;
5571 p
->addr
.sin_addr
= in
;
5572 p
->addr
.sin_port
= htons(atoi(c
));
5574 ast_sched_del(sched
, p
->expire
);
5575 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5576 p
->expire
= ast_sched_add(sched
, (p
->expiry
+ 10) * 1000, expire_registry
, (void *)p
->name
);
5578 iax2_regfunk(p
->name
, 1);
5579 register_peer_exten(p
, 1);
5587 static int update_registry(const char *name
, struct sockaddr_in
*sin
, int callno
, char *devtype
, int fd
, unsigned short refresh
)
5589 /* Called from IAX thread only, with proper iaxsl lock */
5590 struct iax_ie_data ied
;
5591 struct iax2_peer
*p
;
5596 memset(&ied
, 0, sizeof(ied
));
5598 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
5599 if (!(p
= find_peer(name
, 1))) {
5600 ast_log(LOG_WARNING
, "No such peer '%s'\n", name
);
5604 if (ast_test_flag((&globalflags
), IAX_RTUPDATE
) && (ast_test_flag(p
, IAX_TEMPONLY
|IAX_RTCACHEFRIENDS
))) {
5605 if (sin
->sin_addr
.s_addr
) {
5608 realtime_update_peer(name
, sin
, nowtime
);
5610 realtime_update_peer(name
, sin
, 0);
5613 if (inaddrcmp(&p
->addr
, sin
)) {
5615 iax2_regfunk(p
->name
, 1);
5616 /* Stash the IP address from which they registered */
5617 memcpy(&p
->addr
, sin
, sizeof(p
->addr
));
5618 snprintf(data
, sizeof(data
), "%s:%d:%d", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), p
->expiry
);
5619 if (!ast_test_flag(p
, IAX_TEMPONLY
) && sin
->sin_addr
.s_addr
) {
5620 ast_db_put("IAX/Registry", p
->name
, data
);
5621 if (option_verbose
> 2)
5622 ast_verbose(VERBOSE_PREFIX_3
"Registered IAX2 '%s' (%s) at %s:%d\n", p
->name
,
5623 ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
5624 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p
->name
);
5625 register_peer_exten(p
, 1);
5626 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5627 } else if (!ast_test_flag(p
, IAX_TEMPONLY
)) {
5628 if (option_verbose
> 2)
5629 ast_verbose(VERBOSE_PREFIX_3
"Unregistered IAX2 '%s' (%s)\n", p
->name
,
5630 ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
) ? "AUTHENTICATED" : "UNAUTHENTICATED");
5631 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p
->name
);
5632 register_peer_exten(p
, 0);
5633 ast_db_del("IAX/Registry", p
->name
);
5634 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5636 /* Update the host */
5637 /* Verify that the host is really there */
5638 iax2_poke_peer(p
, callno
);
5640 /* Store socket fd */
5642 /* Setup the expiry */
5644 ast_sched_del(sched
, p
->expire
);
5645 /* treat an unspecified refresh interval as the minimum */
5647 refresh
= min_reg_expire
;
5648 if (refresh
> max_reg_expire
) {
5649 ast_log(LOG_NOTICE
, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5650 p
->name
, max_reg_expire
, refresh
);
5651 p
->expiry
= max_reg_expire
;
5652 } else if (refresh
< min_reg_expire
) {
5653 ast_log(LOG_NOTICE
, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5654 p
->name
, min_reg_expire
, refresh
);
5655 p
->expiry
= min_reg_expire
;
5657 p
->expiry
= refresh
;
5659 if (p
->expiry
&& sin
->sin_addr
.s_addr
)
5660 p
->expire
= ast_sched_add(sched
, (p
->expiry
+ 10) * 1000, expire_registry
, (void *)p
->name
);
5661 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, p
->name
);
5662 iax_ie_append_int(&ied
, IAX_IE_DATETIME
, iax2_datetime(p
->zonetag
));
5663 if (sin
->sin_addr
.s_addr
) {
5664 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, p
->expiry
);
5665 iax_ie_append_addr(&ied
, IAX_IE_APPARENT_ADDR
, &p
->addr
);
5666 if (!ast_strlen_zero(p
->mailbox
)) {
5668 ast_app_inboxcount(p
->mailbox
, &new, &old
);
5673 msgcount
= (old
<< 8) | new;
5674 iax_ie_append_short(&ied
, IAX_IE_MSGCOUNT
, msgcount
);
5676 if (ast_test_flag(p
, IAX_HASCALLERID
)) {
5677 iax_ie_append_str(&ied
, IAX_IE_CALLING_NUMBER
, p
->cid_num
);
5678 iax_ie_append_str(&ied
, IAX_IE_CALLING_NAME
, p
->cid_name
);
5681 version
= iax_check_version(devtype
);
5683 iax_ie_append_short(&ied
, IAX_IE_FIRMWAREVER
, version
);
5684 if (ast_test_flag(p
, IAX_TEMPONLY
))
5686 return send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGACK
, 0, ied
.buf
, ied
.pos
, -1);
5689 static int registry_authrequest(const char *name
, int callno
)
5691 struct iax_ie_data ied
;
5692 struct iax2_peer
*p
;
5694 /* SLD: third call to find_peer in registration */
5695 p
= find_peer(name
, 1);
5697 memset(&ied
, 0, sizeof(ied
));
5698 iax_ie_append_short(&ied
, IAX_IE_AUTHMETHODS
, p
->authmethods
);
5699 if (p
->authmethods
& (IAX_AUTH_RSA
| IAX_AUTH_MD5
)) {
5700 /* Build the challenge */
5701 snprintf(challenge
, sizeof(challenge
), "%d", (int)ast_random());
5702 ast_string_field_set(iaxs
[callno
], challenge
, challenge
);
5703 /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */
5704 iax_ie_append_str(&ied
, IAX_IE_CHALLENGE
, iaxs
[callno
]->challenge
);
5706 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, name
);
5707 if (ast_test_flag(p
, IAX_TEMPONLY
))
5709 return send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGAUTH
, 0, ied
.buf
, ied
.pos
, -1);;
5711 ast_log(LOG_WARNING
, "No such peer '%s'\n", name
);
5715 static int registry_rerequest(struct iax_ies
*ies
, int callno
, struct sockaddr_in
*sin
)
5717 struct iax2_registry
*reg
;
5718 /* Start pessimistic */
5719 struct iax_ie_data ied
;
5720 char peer
[256] = "";
5721 char challenge
[256] = "";
5723 int authmethods
= 0;
5724 if (ies
->authmethods
)
5725 authmethods
= ies
->authmethods
;
5727 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
5729 ast_copy_string(challenge
, ies
->challenge
, sizeof(challenge
));
5730 memset(&ied
, 0, sizeof(ied
));
5731 reg
= iaxs
[callno
]->reg
;
5733 if (inaddrcmp(®
->addr
, sin
)) {
5734 ast_log(LOG_WARNING
, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin
->sin_addr
));
5737 if (ast_strlen_zero(reg
->secret
)) {
5738 ast_log(LOG_NOTICE
, "No secret associated with peer '%s'\n", reg
->username
);
5739 reg
->regstate
= REG_STATE_NOAUTH
;
5742 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, reg
->username
);
5743 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, reg
->refresh
);
5744 if (reg
->secret
[0] == '[') {
5746 ast_copy_string(tmpkey
, reg
->secret
+ 1, sizeof(tmpkey
));
5747 tmpkey
[strlen(tmpkey
) - 1] = '\0';
5748 res
= authenticate(challenge
, NULL
, tmpkey
, authmethods
, &ied
, sin
, NULL
, NULL
);
5750 res
= authenticate(challenge
, reg
->secret
, NULL
, authmethods
, &ied
, sin
, NULL
, NULL
);
5752 reg
->regstate
= REG_STATE_AUTHSENT
;
5753 return send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGREQ
, 0, ied
.buf
, ied
.pos
, -1);
5756 ast_log(LOG_WARNING
, "Registry acknowledge on unknown registery '%s'\n", peer
);
5758 ast_log(LOG_NOTICE
, "Can't reregister without a reg\n");
5762 static void stop_stuff(int callno
)
5764 iax2_destroy_helper(iaxs
[callno
]);
5767 static void __auth_reject(void *nothing
)
5769 /* Called from IAX thread only, without iaxs lock */
5770 int callno
= (int)(long)(nothing
);
5771 struct iax_ie_data ied
;
5772 ast_mutex_lock(&iaxsl
[callno
]);
5774 memset(&ied
, 0, sizeof(ied
));
5775 if (iaxs
[callno
]->authfail
== IAX_COMMAND_REGREJ
) {
5776 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Registration Refused");
5777 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_REJECTED
);
5778 } else if (iaxs
[callno
]->authfail
== IAX_COMMAND_REJECT
) {
5779 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "No authority found");
5780 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_NOT_SUBSCRIBED
);
5782 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, iaxs
[callno
]->authfail
, 0, ied
.buf
, ied
.pos
, -1);
5784 ast_mutex_unlock(&iaxsl
[callno
]);
5787 static int auth_reject(void *data
)
5789 int callno
= (int)(long)(data
);
5790 ast_mutex_lock(&iaxsl
[callno
]);
5792 iaxs
[callno
]->authid
= -1;
5793 ast_mutex_unlock(&iaxsl
[callno
]);
5794 #ifdef SCHED_MULTITHREADED
5795 if (schedule_action(__auth_reject
, data
))
5797 __auth_reject(data
);
5801 static int auth_fail(int callno
, int failcode
)
5803 /* Schedule sending the authentication failure in one second, to prevent
5805 ast_mutex_lock(&iaxsl
[callno
]);
5807 iaxs
[callno
]->authfail
= failcode
;
5809 if (iaxs
[callno
]->authid
> -1)
5810 ast_sched_del(sched
, iaxs
[callno
]->authid
);
5811 iaxs
[callno
]->authid
= ast_sched_add(sched
, 1000, auth_reject
, (void *)(long)callno
);
5813 auth_reject((void *)(long)callno
);
5815 ast_mutex_unlock(&iaxsl
[callno
]);
5819 static void __auto_hangup(void *nothing
)
5821 /* Called from IAX thread only, without iaxs lock */
5822 int callno
= (int)(long)(nothing
);
5823 struct iax_ie_data ied
;
5824 ast_mutex_lock(&iaxsl
[callno
]);
5826 memset(&ied
, 0, sizeof(ied
));
5827 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Timeout");
5828 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_USER_RESPONSE
);
5829 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_HANGUP
, 0, ied
.buf
, ied
.pos
, -1);
5831 ast_mutex_unlock(&iaxsl
[callno
]);
5834 static int auto_hangup(void *data
)
5836 int callno
= (int)(long)(data
);
5837 ast_mutex_lock(&iaxsl
[callno
]);
5839 iaxs
[callno
]->autoid
= -1;
5841 ast_mutex_unlock(&iaxsl
[callno
]);
5842 #ifdef SCHED_MULTITHREADED
5843 if (schedule_action(__auto_hangup
, data
))
5845 __auto_hangup(data
);
5849 static void iax2_dprequest(struct iax2_dpcache
*dp
, int callno
)
5851 struct iax_ie_data ied
;
5852 /* Auto-hangup with 30 seconds of inactivity */
5853 if (iaxs
[callno
]->autoid
> -1)
5854 ast_sched_del(sched
, iaxs
[callno
]->autoid
);
5855 iaxs
[callno
]->autoid
= ast_sched_add(sched
, 30000, auto_hangup
, (void *)(long)callno
);
5856 memset(&ied
, 0, sizeof(ied
));
5857 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, dp
->exten
);
5858 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_DPREQ
, 0, ied
.buf
, ied
.pos
, -1);
5859 dp
->flags
|= CACHE_FLAG_TRANSMITTED
;
5862 static int iax2_vnak(int callno
)
5864 return send_command_immediate(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_VNAK
, 0, NULL
, 0, iaxs
[callno
]->iseqno
);
5867 static void vnak_retransmit(int callno
, int last
)
5869 struct iax_frame
*f
;
5871 AST_LIST_LOCK(&iaxq
.queue
);
5872 AST_LIST_TRAVERSE(&iaxq
.queue
, f
, list
) {
5873 /* Send a copy immediately */
5874 if ((f
->callno
== callno
) && iaxs
[f
->callno
] &&
5875 (f
->oseqno
>= last
)) {
5879 AST_LIST_UNLOCK(&iaxq
.queue
);
5882 static void __iax2_poke_peer_s(void *data
)
5884 struct iax2_peer
*peer
= data
;
5885 iax2_poke_peer(peer
, 0);
5888 static int iax2_poke_peer_s(void *data
)
5890 struct iax2_peer
*peer
= data
;
5891 peer
->pokeexpire
= -1;
5892 #ifdef SCHED_MULTITHREADED
5893 if (schedule_action(__iax2_poke_peer_s
, data
))
5895 __iax2_poke_peer_s(data
);
5899 static int send_trunk(struct iax2_trunk_peer
*tpeer
, struct timeval
*now
)
5902 struct iax_frame
*fr
;
5903 struct ast_iax2_meta_hdr
*meta
;
5904 struct ast_iax2_meta_trunk_hdr
*mth
;
5907 /* Point to frame */
5908 fr
= (struct iax_frame
*)tpeer
->trunkdata
;
5909 /* Point to meta data */
5910 meta
= (struct ast_iax2_meta_hdr
*)fr
->afdata
;
5911 mth
= (struct ast_iax2_meta_trunk_hdr
*)meta
->data
;
5912 if (tpeer
->trunkdatalen
) {
5913 /* We're actually sending a frame, so fill the meta trunk header and meta header */
5915 meta
->metacmd
= IAX_META_TRUNK
;
5916 if (ast_test_flag(&globalflags
, IAX_TRUNKTIMESTAMPS
))
5917 meta
->cmddata
= IAX_META_TRUNK_MINI
;
5919 meta
->cmddata
= IAX_META_TRUNK_SUPERMINI
;
5920 mth
->ts
= htonl(calc_txpeerstamp(tpeer
, trunkfreq
, now
));
5921 /* And the rest of the ast_iax2 header */
5922 fr
->direction
= DIRECTION_OUTGRESS
;
5925 /* Any appropriate call will do */
5926 fr
->data
= fr
->afdata
;
5927 fr
->datalen
= tpeer
->trunkdatalen
+ sizeof(struct ast_iax2_meta_hdr
) + sizeof(struct ast_iax2_meta_trunk_hdr
);
5928 res
= transmit_trunk(fr
, &tpeer
->addr
, tpeer
->sockfd
);
5929 calls
= tpeer
->calls
;
5931 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
));
5933 /* Reset transmit trunk side data */
5934 tpeer
->trunkdatalen
= 0;
5942 static inline int iax2_trunk_expired(struct iax2_trunk_peer
*tpeer
, struct timeval
*now
)
5944 /* Drop when trunk is about 5 seconds idle */
5945 if (now
->tv_sec
> tpeer
->trunkact
.tv_sec
+ 5)
5950 static int timing_read(int *id
, int fd
, short events
, void *cbdata
)
5954 struct iax2_trunk_peer
*tpeer
, *prev
= NULL
, *drop
=NULL
;
5962 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA
);
5963 gettimeofday(&now
, NULL
);
5964 if (events
& AST_IO_PRI
) {
5966 /* Great, this is a timing interface, just call the ioctl */
5967 if (ioctl(fd
, ZT_TIMERACK
, &x
))
5968 ast_log(LOG_WARNING
, "Unable to acknowledge zap timer\n");
5972 /* Read and ignore from the pseudo channel for timing */
5973 res
= read(fd
, buf
, sizeof(buf
));
5975 ast_log(LOG_WARNING
, "Unable to read from timing fd\n");
5979 /* For each peer that supports trunking... */
5980 ast_mutex_lock(&tpeerlock
);
5985 ast_mutex_lock(&tpeer
->lock
);
5986 /* We can drop a single tpeer per pass. That makes all this logic
5987 substantially easier */
5988 if (!drop
&& iax2_trunk_expired(tpeer
, &now
)) {
5989 /* Take it out of the list, but don't free it yet, because it
5992 prev
->next
= tpeer
->next
;
5994 tpeers
= tpeer
->next
;
5997 res
= send_trunk(tpeer
, &now
);
5999 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
);
6003 ast_mutex_unlock(&tpeer
->lock
);
6005 tpeer
= tpeer
->next
;
6007 ast_mutex_unlock(&tpeerlock
);
6009 ast_mutex_lock(&drop
->lock
);
6010 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
6011 because by the time they could get tpeerlock, we've already grabbed it */
6012 ast_log(LOG_DEBUG
, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop
->addr
.sin_addr
), ntohs(drop
->addr
.sin_port
));
6013 free(drop
->trunkdata
);
6014 ast_mutex_unlock(&drop
->lock
);
6015 ast_mutex_destroy(&drop
->lock
);
6020 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed
, totalcalls
);
6027 char context
[AST_MAX_EXTENSION
];
6028 char callednum
[AST_MAX_EXTENSION
];
6032 static void dp_lookup(int callno
, const char *context
, const char *callednum
, const char *callerid
, int skiplock
)
6034 unsigned short dpstatus
= 0;
6035 struct iax_ie_data ied1
;
6038 memset(&ied1
, 0, sizeof(ied1
));
6039 mm
= ast_matchmore_extension(NULL
, context
, callednum
, 1, callerid
);
6040 /* Must be started */
6041 if (!strcmp(callednum
, ast_parking_ext()) || ast_exists_extension(NULL
, context
, callednum
, 1, callerid
)) {
6042 dpstatus
= IAX_DPSTATUS_EXISTS
;
6043 } else if (ast_canmatch_extension(NULL
, context
, callednum
, 1, callerid
)) {
6044 dpstatus
= IAX_DPSTATUS_CANEXIST
;
6046 dpstatus
= IAX_DPSTATUS_NONEXISTENT
;
6048 if (ast_ignore_pattern(context
, callednum
))
6049 dpstatus
|= IAX_DPSTATUS_IGNOREPAT
;
6051 dpstatus
|= IAX_DPSTATUS_MATCHMORE
;
6053 ast_mutex_lock(&iaxsl
[callno
]);
6055 iax_ie_append_str(&ied1
, IAX_IE_CALLED_NUMBER
, callednum
);
6056 iax_ie_append_short(&ied1
, IAX_IE_DPSTATUS
, dpstatus
);
6057 iax_ie_append_short(&ied1
, IAX_IE_REFRESH
, iaxdefaultdpcache
);
6058 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_DPREP
, 0, ied1
.buf
, ied1
.pos
, -1);
6061 ast_mutex_unlock(&iaxsl
[callno
]);
6064 static void *dp_lookup_thread(void *data
)
6066 /* Look up for dpreq */
6067 struct dpreq_data
*dpr
= data
;
6068 dp_lookup(dpr
->callno
, dpr
->context
, dpr
->callednum
, dpr
->callerid
, 0);
6070 free(dpr
->callerid
);
6075 static void spawn_dp_lookup(int callno
, const char *context
, const char *callednum
, const char *callerid
)
6077 pthread_t newthread
;
6078 struct dpreq_data
*dpr
;
6080 if (!(dpr
= ast_calloc(1, sizeof(*dpr
))))
6083 dpr
->callno
= callno
;
6084 ast_copy_string(dpr
->context
, context
, sizeof(dpr
->context
));
6085 ast_copy_string(dpr
->callednum
, callednum
, sizeof(dpr
->callednum
));
6087 dpr
->callerid
= ast_strdup(callerid
);
6088 if (ast_pthread_create(&newthread
, NULL
, dp_lookup_thread
, dpr
)) {
6089 ast_log(LOG_WARNING
, "Unable to start lookup thread!\n");
6094 struct ast_channel
*chan1
;
6095 struct ast_channel
*chan2
;
6098 static void *iax_park_thread(void *stuff
)
6100 struct ast_channel
*chan1
, *chan2
;
6102 struct ast_frame
*f
;
6109 f
= ast_read(chan1
);
6112 res
= ast_park_call(chan1
, chan2
, 0, &ext
);
6114 ast_log(LOG_NOTICE
, "Parked on extension '%d'\n", ext
);
6118 static int iax_park(struct ast_channel
*chan1
, struct ast_channel
*chan2
)
6121 struct ast_channel
*chan1m
, *chan2m
;
6123 chan1m
= ast_channel_alloc(0);
6124 chan2m
= ast_channel_alloc(0);
6125 if (chan2m
&& chan1m
) {
6126 ast_string_field_build(chan1m
, name
, "Parking/%s", chan1
->name
);
6127 /* Make formats okay */
6128 chan1m
->readformat
= chan1
->readformat
;
6129 chan1m
->writeformat
= chan1
->writeformat
;
6130 ast_channel_masquerade(chan1m
, chan1
);
6131 /* Setup the extensions and such */
6132 ast_copy_string(chan1m
->context
, chan1
->context
, sizeof(chan1m
->context
));
6133 ast_copy_string(chan1m
->exten
, chan1
->exten
, sizeof(chan1m
->exten
));
6134 chan1m
->priority
= chan1
->priority
;
6136 /* We make a clone of the peer channel too, so we can play
6137 back the announcement */
6138 ast_string_field_build(chan2m
, name
, "IAXPeer/%s",chan2
->name
);
6139 /* Make formats okay */
6140 chan2m
->readformat
= chan2
->readformat
;
6141 chan2m
->writeformat
= chan2
->writeformat
;
6142 ast_channel_masquerade(chan2m
, chan2
);
6143 /* Setup the extensions and such */
6144 ast_copy_string(chan2m
->context
, chan2
->context
, sizeof(chan2m
->context
));
6145 ast_copy_string(chan2m
->exten
, chan2
->exten
, sizeof(chan2m
->exten
));
6146 chan2m
->priority
= chan2
->priority
;
6147 if (ast_do_masquerade(chan2m
)) {
6148 ast_log(LOG_WARNING
, "Masquerade failed :(\n");
6159 if ((d
= ast_calloc(1, sizeof(*d
)))) {
6162 if (!ast_pthread_create(&th
, NULL
, iax_park_thread
, d
))
6170 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
);
6172 static int check_provisioning(struct sockaddr_in
*sin
, int sockfd
, char *si
, unsigned int ver
)
6174 unsigned int ourver
;
6176 snprintf(rsi
, sizeof(rsi
), "si-%s", si
);
6177 if (iax_provision_version(&ourver
, rsi
, 1))
6180 ast_log(LOG_DEBUG
, "Service identifier '%s', we think '%08x', they think '%08x'\n", si
, ourver
, ver
);
6182 iax2_provision(sin
, sockfd
, NULL
, rsi
, 1);
6186 static void construct_rr(struct chan_iax2_pvt
*pvt
, struct iax_ie_data
*iep
)
6189 jb_getinfo(pvt
->jb
, &stats
);
6191 memset(iep
, 0, sizeof(*iep
));
6193 iax_ie_append_int(iep
,IAX_IE_RR_JITTER
, stats
.jitter
);
6194 if(stats
.frames_in
== 0) stats
.frames_in
= 1;
6195 iax_ie_append_int(iep
,IAX_IE_RR_LOSS
, ((0xff & (stats
.losspct
/1000)) << 24 | (stats
.frames_lost
& 0x00ffffff)));
6196 iax_ie_append_int(iep
,IAX_IE_RR_PKTS
, stats
.frames_in
);
6197 iax_ie_append_short(iep
,IAX_IE_RR_DELAY
, stats
.current
- stats
.min
);
6198 iax_ie_append_int(iep
,IAX_IE_RR_DROPPED
, stats
.frames_dropped
);
6199 iax_ie_append_int(iep
,IAX_IE_RR_OOO
, stats
.frames_ooo
);
6202 static void save_rr(struct iax_frame
*fr
, struct iax_ies
*ies
)
6204 iaxs
[fr
->callno
]->remote_rr
.jitter
= ies
->rr_jitter
;
6205 iaxs
[fr
->callno
]->remote_rr
.losspct
= ies
->rr_loss
>> 24;
6206 iaxs
[fr
->callno
]->remote_rr
.losscnt
= ies
->rr_loss
& 0xffffff;
6207 iaxs
[fr
->callno
]->remote_rr
.packets
= ies
->rr_pkts
;
6208 iaxs
[fr
->callno
]->remote_rr
.delay
= ies
->rr_delay
;
6209 iaxs
[fr
->callno
]->remote_rr
.dropped
= ies
->rr_dropped
;
6210 iaxs
[fr
->callno
]->remote_rr
.ooo
= ies
->rr_ooo
;
6213 static int socket_read(int *id
, int fd
, short events
, void *cbdata
)
6215 struct iax2_thread
*thread
;
6218 static time_t last_errtime
=0;
6220 thread
= find_idle_thread();
6222 len
= sizeof(thread
->iosin
);
6224 thread
->iores
= recvfrom(fd
, thread
->buf
, sizeof(thread
->buf
), 0,(struct sockaddr
*) &thread
->iosin
, &len
);
6225 if (thread
->iores
< 0) {
6226 if (errno
!= ECONNREFUSED
&& errno
!= EAGAIN
)
6227 ast_log(LOG_WARNING
, "Error: %s\n", strerror(errno
));
6229 AST_LIST_LOCK(&idle_list
);
6230 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
6231 AST_LIST_UNLOCK(&idle_list
);
6234 if (test_losspct
&& ((100.0 * ast_random() / (RAND_MAX
+ 1.0)) < test_losspct
)) { /* simulate random loss condition */
6235 AST_LIST_LOCK(&idle_list
);
6236 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
6237 AST_LIST_UNLOCK(&idle_list
);
6240 /* Mark as ready and send on its way */
6241 thread
->iostate
= IAX_IOSTATE_READY
;
6242 #ifdef DEBUG_SCHED_MULTITHREAD
6243 ast_copy_string(thread
->curfunc
, "socket_process", sizeof(thread
->curfunc
));
6245 signal_condition(&thread
->lock
, &thread
->cond
);
6248 if (t
!= last_errtime
)
6249 ast_log(LOG_NOTICE
, "Out of idle IAX2 threads for I/O, pausing!\n");
6256 static int socket_process(struct iax2_thread
*thread
)
6258 struct sockaddr_in sin
;
6260 int updatehistory
=1;
6261 int new = NEW_PREVENT
;
6264 struct ast_iax2_full_hdr
*fh
= (struct ast_iax2_full_hdr
*)thread
->buf
;
6265 struct ast_iax2_mini_hdr
*mh
= (struct ast_iax2_mini_hdr
*)thread
->buf
;
6266 struct ast_iax2_meta_hdr
*meta
= (struct ast_iax2_meta_hdr
*)thread
->buf
;
6267 struct ast_iax2_video_hdr
*vh
= (struct ast_iax2_video_hdr
*)thread
->buf
;
6268 struct ast_iax2_meta_trunk_hdr
*mth
;
6269 struct ast_iax2_meta_trunk_entry
*mte
;
6270 struct ast_iax2_meta_trunk_mini
*mtm
;
6271 struct iax_frame
*fr
;
6272 struct iax_frame
*cur
;
6274 struct ast_channel
*c
;
6275 struct iax2_dpcache
*dp
;
6276 struct iax2_peer
*peer
;
6277 struct iax2_trunk_peer
*tpeer
;
6278 struct timeval rxtrunktime
;
6280 struct iax_ie_data ied0
, ied1
;
6286 char empty
[32]=""; /* Safety measure */
6287 struct iax_frame
*duped_fr
;
6288 char host_pref_buf
[128];
6289 char caller_pref_buf
[128];
6290 struct ast_codec_pref pref
;
6291 char *using_prefs
= "mine";
6293 /* allocate an iax_frame with 4096 bytes of data buffer */
6294 fr
= alloca(sizeof(*fr
) + 4096);
6297 /* Copy frequently used parameters to the stack */
6298 res
= thread
->iores
;
6300 memcpy(&sin
, &thread
->iosin
, sizeof(sin
));
6302 if (res
< sizeof(*mh
)) {
6303 ast_log(LOG_WARNING
, "midget packet received (%d of %zd min)\n", res
, sizeof(*mh
));
6306 if ((vh
->zeros
== 0) && (ntohs(vh
->callno
) & 0x8000)) {
6307 if (res
< sizeof(*vh
)) {
6308 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
));
6312 /* This is a video frame, get call number */
6313 fr
->callno
= find_callno(ntohs(vh
->callno
) & ~0x8000, dcallno
, &sin
, new, 1, fd
);
6315 } else if ((meta
->zeros
== 0) && !(ntohs(meta
->metacmd
) & 0x8000)) {
6316 unsigned char metatype
;
6318 if (res
< sizeof(*meta
)) {
6319 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
));
6323 /* This is a meta header */
6324 switch(meta
->metacmd
) {
6325 case IAX_META_TRUNK
:
6326 if (res
< (sizeof(*meta
) + sizeof(*mth
))) {
6327 ast_log(LOG_WARNING
, "midget meta trunk packet received (%d of %zd min)\n", res
,
6328 sizeof(*meta
) + sizeof(*mth
));
6331 mth
= (struct ast_iax2_meta_trunk_hdr
*)(meta
->data
);
6332 ts
= ntohl(mth
->ts
);
6333 metatype
= meta
->cmddata
;
6334 res
-= (sizeof(*meta
) + sizeof(*mth
));
6336 tpeer
= find_tpeer(&sin
, fd
);
6338 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
));
6341 tpeer
->trunkact
= ast_tvnow();
6342 if (!ts
|| ast_tvzero(tpeer
->rxtrunktime
))
6343 tpeer
->rxtrunktime
= tpeer
->trunkact
;
6344 rxtrunktime
= tpeer
->rxtrunktime
;
6345 ast_mutex_unlock(&tpeer
->lock
);
6346 while(res
>= sizeof(*mte
)) {
6347 /* Process channels */
6348 unsigned short callno
, trunked_ts
, len
;
6350 if (metatype
== IAX_META_TRUNK_MINI
) {
6351 mtm
= (struct ast_iax2_meta_trunk_mini
*)ptr
;
6352 ptr
+= sizeof(*mtm
);
6353 res
-= sizeof(*mtm
);
6354 len
= ntohs(mtm
->len
);
6355 callno
= ntohs(mtm
->mini
.callno
);
6356 trunked_ts
= ntohs(mtm
->mini
.ts
);
6357 } else if (metatype
== IAX_META_TRUNK_SUPERMINI
) {
6358 mte
= (struct ast_iax2_meta_trunk_entry
*)ptr
;
6359 ptr
+= sizeof(*mte
);
6360 res
-= sizeof(*mte
);
6361 len
= ntohs(mte
->len
);
6362 callno
= ntohs(mte
->callno
);
6365 ast_log(LOG_WARNING
, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin
.sin_addr
), ntohs(sin
.sin_port
));
6368 /* Stop if we don't have enough data */
6371 fr
->callno
= find_callno(callno
& ~IAX_FLAG_FULL
, 0, &sin
, NEW_PREVENT
, 1, fd
);
6373 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6374 /* If it's a valid call, deliver the contents. If not, we
6375 drop it, since we don't have a scallno to use for an INVAL */
6376 /* Process as a mini frame */
6377 f
.frametype
= AST_FRAME_VOICE
;
6378 if (iaxs
[fr
->callno
]) {
6379 if (iaxs
[fr
->callno
]->voiceformat
> 0) {
6380 f
.subclass
= iaxs
[fr
->callno
]->voiceformat
;
6382 if (f
.datalen
>= 0) {
6388 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | (trunked_ts
& 0xffff);
6390 fr
->ts
= fix_peerts(&rxtrunktime
, fr
->callno
, ts
);
6391 /* Don't pass any packets until we're started */
6392 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6397 if (f
.datalen
&& (f
.frametype
== AST_FRAME_VOICE
))
6398 f
.samples
= ast_codec_get_samples(&f
);
6402 iax_frame_wrap(fr
, &f
);
6403 duped_fr
= iaxfrdup2(fr
);
6405 schedule_delivery(duped_fr
, updatehistory
, 1, &fr
->ts
);
6407 if (iaxs
[fr
->callno
]->last
< fr
->ts
) {
6408 iaxs
[fr
->callno
]->last
= fr
->ts
;
6410 if (option_debug
&& iaxdebug
)
6411 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
6416 ast_log(LOG_WARNING
, "Datalen < 0?\n");
6419 ast_log(LOG_WARNING
, "Received trunked frame before first full voice frame\n ");
6420 iax2_vnak(fr
->callno
);
6423 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6433 #ifdef DEBUG_SUPPORT
6434 if (iaxdebug
&& (res
>= sizeof(*fh
)))
6435 iax_showframe(NULL
, fh
, 1, &sin
, res
- sizeof(*fh
));
6437 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6438 if (res
< sizeof(*fh
)) {
6439 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
));
6443 /* Get the destination call number */
6444 dcallno
= ntohs(fh
->dcallno
) & ~IAX_FLAG_RETRANS
;
6445 /* Retrieve the type and subclass */
6446 f
.frametype
= fh
->type
;
6447 if (f
.frametype
== AST_FRAME_VIDEO
) {
6448 f
.subclass
= uncompress_subclass(fh
->csub
& ~0x40) | ((fh
->csub
>> 6) & 0x1);
6450 f
.subclass
= uncompress_subclass(fh
->csub
);
6452 if ((f
.frametype
== AST_FRAME_IAX
) && ((f
.subclass
== IAX_COMMAND_NEW
) || (f
.subclass
== IAX_COMMAND_REGREQ
) ||
6453 (f
.subclass
== IAX_COMMAND_POKE
) || (f
.subclass
== IAX_COMMAND_FWDOWNL
) ||
6454 (f
.subclass
== IAX_COMMAND_REGREL
)))
6457 /* Don't know anything about it yet */
6458 f
.frametype
= AST_FRAME_NULL
;
6463 fr
->callno
= find_callno(ntohs(mh
->callno
) & ~IAX_FLAG_FULL
, dcallno
, &sin
, new, 1, fd
);
6466 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6468 if (!fr
->callno
|| !iaxs
[fr
->callno
]) {
6469 /* A call arrived for a nonexistent destination. Unless it's an "inval"
6470 frame, reply with an inval */
6471 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6472 /* We can only raw hangup control frames */
6473 if (((f
.subclass
!= IAX_COMMAND_INVAL
) &&
6474 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6475 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6476 (f
.subclass
!= IAX_COMMAND_FWDOWNL
))||
6477 (f
.frametype
!= AST_FRAME_IAX
))
6478 raw_hangup(&sin
, ntohs(fh
->dcallno
) & ~IAX_FLAG_RETRANS
, ntohs(mh
->callno
) & ~IAX_FLAG_FULL
,
6482 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6485 if (ast_test_flag(iaxs
[fr
->callno
], IAX_ENCRYPTED
)) {
6486 if (decrypt_frame(fr
->callno
, fh
, &f
, &res
)) {
6487 ast_log(LOG_NOTICE
, "Packet Decrypt Failed!\n");
6488 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6491 #ifdef DEBUG_SUPPORT
6493 iax_showframe(NULL
, fh
, 3, &sin
, res
- sizeof(*fh
));
6497 /* count this frame */
6498 iaxs
[fr
->callno
]->frames_received
++;
6500 if (!inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) && !minivid
&&
6501 f
.subclass
!= IAX_COMMAND_TXCNT
&& /* for attended transfer */
6502 f
.subclass
!= IAX_COMMAND_TXACC
) /* for attended transfer */
6503 iaxs
[fr
->callno
]->peercallno
= (unsigned short)(ntohs(mh
->callno
) & ~IAX_FLAG_FULL
);
6504 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6505 if (option_debug
&& iaxdebug
)
6506 ast_log(LOG_DEBUG
, "Received packet %d, (%d, %d)\n", fh
->oseqno
, f
.frametype
, f
.subclass
);
6507 /* Check if it's out of order (and not an ACK or INVAL) */
6508 fr
->oseqno
= fh
->oseqno
;
6509 fr
->iseqno
= fh
->iseqno
;
6510 fr
->ts
= ntohl(fh
->ts
);
6514 ast_log(LOG_DEBUG
, "Simulating frame ts resync, was %u now %u\n", fr
->ts
, fr
->ts
+ test_resync
);
6515 fr
->ts
+= test_resync
;
6517 #endif /* IAXTESTS */
6519 if ( (ntohs(fh
->dcallno
) & IAX_FLAG_RETRANS
) ||
6520 ( (f
.frametype
!= AST_FRAME_VOICE
) && ! (f
.frametype
== AST_FRAME_IAX
&&
6521 (f
.subclass
== IAX_COMMAND_NEW
||
6522 f
.subclass
== IAX_COMMAND_AUTHREQ
||
6523 f
.subclass
== IAX_COMMAND_ACCEPT
||
6524 f
.subclass
== IAX_COMMAND_REJECT
)) ) )
6526 if ((ntohs(fh
->dcallno
) & IAX_FLAG_RETRANS
) || (f
.frametype
!= AST_FRAME_VOICE
))
6528 if ((iaxs
[fr
->callno
]->iseqno
!= fr
->oseqno
) &&
6529 (iaxs
[fr
->callno
]->iseqno
||
6530 ((f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6531 (f
.subclass
!= IAX_COMMAND_TXREADY
) && /* for attended transfer */
6532 (f
.subclass
!= IAX_COMMAND_TXREL
) && /* for attended transfer */
6533 (f
.subclass
!= IAX_COMMAND_UNQUELCH
) && /* for attended transfer */
6534 (f
.subclass
!= IAX_COMMAND_TXACC
)) ||
6535 (f
.frametype
!= AST_FRAME_IAX
))) {
6537 ((f
.subclass
!= IAX_COMMAND_ACK
) &&
6538 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
6539 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6540 (f
.subclass
!= IAX_COMMAND_TXREADY
) && /* for attended transfer */
6541 (f
.subclass
!= IAX_COMMAND_TXREL
) && /* for attended transfer */
6542 (f
.subclass
!= IAX_COMMAND_UNQUELCH
) && /* for attended transfer */
6543 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6544 (f
.subclass
!= IAX_COMMAND_VNAK
)) ||
6545 (f
.frametype
!= AST_FRAME_IAX
)) {
6546 /* If it's not an ACK packet, it's out of order. */
6548 ast_log(LOG_DEBUG
, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
6549 iaxs
[fr
->callno
]->iseqno
, fr
->oseqno
, f
.frametype
, f
.subclass
);
6550 if (iaxs
[fr
->callno
]->iseqno
> fr
->oseqno
) {
6551 /* If we've already seen it, ack it XXX There's a border condition here XXX */
6552 if ((f
.frametype
!= AST_FRAME_IAX
) ||
6553 ((f
.subclass
!= IAX_COMMAND_ACK
) && (f
.subclass
!= IAX_COMMAND_INVAL
))) {
6555 ast_log(LOG_DEBUG
, "Acking anyway\n");
6556 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
6557 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
6558 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6561 /* Send a VNAK requesting retransmission */
6562 iax2_vnak(fr
->callno
);
6564 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6568 /* Increment unless it's an ACK or VNAK */
6569 if (((f
.subclass
!= IAX_COMMAND_ACK
) &&
6570 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
6571 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6572 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6573 (f
.subclass
!= IAX_COMMAND_VNAK
)) ||
6574 (f
.frametype
!= AST_FRAME_IAX
))
6575 iaxs
[fr
->callno
]->iseqno
++;
6578 if (res
< sizeof(*fh
)) {
6579 ast_log(LOG_WARNING
, "midget packet received (%d of %zd min)\n", res
, sizeof(*fh
));
6580 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6583 f
.datalen
= res
- sizeof(*fh
);
6585 /* Handle implicit ACKing unless this is an INVAL, and only if this is
6586 from the real peer, not the transfer peer */
6587 if (!inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) &&
6588 ((f
.subclass
!= IAX_COMMAND_INVAL
) ||
6589 (f
.frametype
!= AST_FRAME_IAX
))) {
6591 /* XXX This code is not very efficient. Surely there is a better way which still
6592 properly handles boundary conditions? XXX */
6593 /* First we have to qualify that the ACKed value is within our window */
6594 for (x
=iaxs
[fr
->callno
]->rseqno
; x
!= iaxs
[fr
->callno
]->oseqno
; x
++)
6595 if (fr
->iseqno
== x
)
6597 if ((x
!= iaxs
[fr
->callno
]->oseqno
) || (iaxs
[fr
->callno
]->oseqno
== fr
->iseqno
)) {
6598 /* The acknowledgement is within our window. Time to acknowledge everything
6600 for (x
=iaxs
[fr
->callno
]->rseqno
; x
!= fr
->iseqno
; x
++) {
6601 /* Ack the packet with the given timestamp */
6602 if (option_debug
&& iaxdebug
)
6603 ast_log(LOG_DEBUG
, "Cancelling transmission of packet %d\n", x
);
6604 AST_LIST_LOCK(&iaxq
.queue
);
6605 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
6606 /* If it's our call, and our timestamp, mark -1 retries */
6607 if ((fr
->callno
== cur
->callno
) && (x
== cur
->oseqno
)) {
6609 /* Destroy call if this is the end */
6611 if (iaxdebug
&& option_debug
)
6612 ast_log(LOG_DEBUG
, "Really destroying %d, having been acked on final message\n", fr
->callno
);
6613 iax2_destroy_nolock(fr
->callno
);
6617 AST_LIST_UNLOCK(&iaxq
.queue
);
6619 /* Note how much we've received acknowledgement for */
6620 if (iaxs
[fr
->callno
])
6621 iaxs
[fr
->callno
]->rseqno
= fr
->iseqno
;
6623 /* Stop processing now */
6624 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6628 ast_log(LOG_DEBUG
, "Received iseqno %d not within window %d->%d\n", fr
->iseqno
, iaxs
[fr
->callno
]->rseqno
, iaxs
[fr
->callno
]->oseqno
);
6630 if (inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) &&
6631 ((f
.frametype
!= AST_FRAME_IAX
) ||
6632 ((f
.subclass
!= IAX_COMMAND_TXACC
) &&
6633 (f
.subclass
!= IAX_COMMAND_TXCNT
)))) {
6634 /* Only messages we accept from a transfer host are TXACC and TXCNT */
6635 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6640 if (f
.frametype
== AST_FRAME_IAX
) {
6641 if (iax_parse_ies(&ies
, thread
->buf
+ sizeof(*fh
), f
.datalen
)) {
6642 ast_log(LOG_WARNING
, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin
.sin_addr
));
6643 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6648 f
.data
= thread
->buf
+ sizeof(*fh
);
6650 if (f
.frametype
== AST_FRAME_IAX
)
6654 memset(&ies
, 0, sizeof(ies
));
6656 if (f
.frametype
== AST_FRAME_VOICE
) {
6657 if (f
.subclass
!= iaxs
[fr
->callno
]->voiceformat
) {
6658 iaxs
[fr
->callno
]->voiceformat
= f
.subclass
;
6659 ast_log(LOG_DEBUG
, "Ooh, voice format changed to %d\n", f
.subclass
);
6660 if (iaxs
[fr
->callno
]->owner
) {
6663 if (ast_mutex_trylock(&iaxs
[fr
->callno
]->owner
->lock
)) {
6664 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6666 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6667 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) goto retryowner
;
6669 if (iaxs
[fr
->callno
]) {
6670 if (iaxs
[fr
->callno
]->owner
) {
6671 orignative
= iaxs
[fr
->callno
]->owner
->nativeformats
;
6672 iaxs
[fr
->callno
]->owner
->nativeformats
= f
.subclass
;
6673 if (iaxs
[fr
->callno
]->owner
->readformat
)
6674 ast_set_read_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->readformat
);
6675 iaxs
[fr
->callno
]->owner
->nativeformats
= orignative
;
6676 ast_mutex_unlock(&iaxs
[fr
->callno
]->owner
->lock
);
6679 ast_log(LOG_DEBUG
, "Neat, somebody took away the channel at a magical time but i found it!\n");
6680 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6686 if (f
.frametype
== AST_FRAME_VIDEO
) {
6687 if (f
.subclass
!= iaxs
[fr
->callno
]->videoformat
) {
6688 ast_log(LOG_DEBUG
, "Ooh, video format changed to %d\n", f
.subclass
& ~0x1);
6689 iaxs
[fr
->callno
]->videoformat
= f
.subclass
& ~0x1;
6692 if (f
.frametype
== AST_FRAME_IAX
) {
6693 if (iaxs
[fr
->callno
]->initid
> -1) {
6694 /* Don't auto congest anymore since we've gotten something usefulb ack */
6695 ast_sched_del(sched
, iaxs
[fr
->callno
]->initid
);
6696 iaxs
[fr
->callno
]->initid
= -1;
6698 /* Handle the IAX pseudo frame itself */
6699 if (option_debug
&& iaxdebug
)
6700 ast_log(LOG_DEBUG
, "IAX subclass %d received\n", f
.subclass
);
6702 /* Update last ts unless the frame's timestamp originated with us. */
6703 if (iaxs
[fr
->callno
]->last
< fr
->ts
&&
6704 f
.subclass
!= IAX_COMMAND_ACK
&&
6705 f
.subclass
!= IAX_COMMAND_PONG
&&
6706 f
.subclass
!= IAX_COMMAND_LAGRP
) {
6707 iaxs
[fr
->callno
]->last
= fr
->ts
;
6708 if (option_debug
&& iaxdebug
)
6709 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
6712 switch(f
.subclass
) {
6713 case IAX_COMMAND_ACK
:
6716 case IAX_COMMAND_QUELCH
:
6717 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6718 /* Generate Manager Hold event, if necessary*/
6719 if (iaxs
[fr
->callno
]->owner
) {
6720 manager_event(EVENT_FLAG_CALL
, "Hold",
6723 iaxs
[fr
->callno
]->owner
->name
,
6724 iaxs
[fr
->callno
]->owner
->uniqueid
);
6727 ast_set_flag(iaxs
[fr
->callno
], IAX_QUELCH
);
6728 if (ies
.musiconhold
) {
6729 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
)) {
6730 const char *mohsuggest
= iaxs
[fr
->callno
]->mohsuggest
;
6731 ast_queue_control_data(iaxs
[fr
->callno
]->owner
, AST_CONTROL_HOLD
,
6732 S_OR(mohsuggest
, NULL
),
6733 !ast_strlen_zero(mohsuggest
) ? strlen(mohsuggest
) + 1 : 0);
6738 case IAX_COMMAND_UNQUELCH
:
6739 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6740 /* Generate Manager Unhold event, if necessary*/
6741 if (iaxs
[fr
->callno
]->owner
&& ast_test_flag(iaxs
[fr
->callno
], IAX_QUELCH
)) {
6742 manager_event(EVENT_FLAG_CALL
, "Unhold",
6745 iaxs
[fr
->callno
]->owner
->name
,
6746 iaxs
[fr
->callno
]->owner
->uniqueid
);
6749 ast_clear_flag(iaxs
[fr
->callno
], IAX_QUELCH
);
6750 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
))
6751 ast_queue_control(iaxs
[fr
->callno
]->owner
, AST_CONTROL_UNHOLD
);
6754 case IAX_COMMAND_TXACC
:
6755 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_BEGIN
) {
6756 /* Ack the packet with the given timestamp */
6757 AST_LIST_LOCK(&iaxq
.queue
);
6758 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
6759 /* Cancel any outstanding txcnt's */
6760 if ((fr
->callno
== cur
->callno
) && (cur
->transfer
))
6763 AST_LIST_UNLOCK(&iaxq
.queue
);
6764 memset(&ied1
, 0, sizeof(ied1
));
6765 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->callno
);
6766 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREADY
, 0, ied1
.buf
, ied1
.pos
, -1);
6767 iaxs
[fr
->callno
]->transferring
= TRANSFER_READY
;
6770 case IAX_COMMAND_NEW
:
6771 /* Ignore if it's already up */
6772 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
))
6774 if (ies
.provverpres
&& ies
.serviceident
&& sin
.sin_addr
.s_addr
)
6775 check_provisioning(&sin
, fd
, ies
.serviceident
, ies
.provver
);
6776 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
6777 if (ast_test_flag(iaxs
[fr
->callno
], IAX_TRUNK
)) {
6778 fr
->callno
= make_trunk(fr
->callno
, 1);
6780 /* For security, always ack immediately */
6782 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6783 if (check_access(fr
->callno
, &sin
, &ies
)) {
6784 /* They're not allowed on */
6785 auth_fail(fr
->callno
, IAX_COMMAND_REJECT
);
6787 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
);
6790 /* This might re-enter the IAX code and need the lock */
6791 if (strcasecmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
6792 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6793 exists
= ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
);
6794 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6797 if (ast_strlen_zero(iaxs
[fr
->callno
]->secret
) && ast_strlen_zero(iaxs
[fr
->callno
]->inkeys
)) {
6798 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD") && !exists
) {
6799 memset(&ied0
, 0, sizeof(ied0
));
6800 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
6801 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
6802 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6804 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
);
6806 /* Select an appropriate format */
6808 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
6809 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
6810 using_prefs
= "reqonly";
6812 using_prefs
= "disabled";
6814 format
= iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
;
6815 memset(&pref
, 0, sizeof(pref
));
6816 strcpy(caller_pref_buf
, "disabled");
6817 strcpy(host_pref_buf
, "disabled");
6819 using_prefs
= "mine";
6820 /* If the information elements are in here... use them */
6821 if (ies
.codec_prefs
)
6822 ast_codec_pref_convert(&iaxs
[fr
->callno
]->rprefs
, ies
.codec_prefs
, 32, 0);
6823 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
6824 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
6825 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
6826 pref
= iaxs
[fr
->callno
]->rprefs
;
6827 using_prefs
= "caller";
6829 pref
= iaxs
[fr
->callno
]->prefs
;
6832 pref
= iaxs
[fr
->callno
]->prefs
;
6834 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->capability
& iaxs
[fr
->callno
]->peercapability
, 0);
6835 ast_codec_pref_string(&iaxs
[fr
->callno
]->rprefs
, caller_pref_buf
, sizeof(caller_pref_buf
) - 1);
6836 ast_codec_pref_string(&iaxs
[fr
->callno
]->prefs
, host_pref_buf
, sizeof(host_pref_buf
) - 1);
6839 if(!ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
6840 format
= iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
;
6842 memset(&ied0
, 0, sizeof(ied0
));
6843 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
6844 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
6845 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6847 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
6848 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
);
6850 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
);
6854 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
6855 if(!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
))
6858 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
6859 using_prefs
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ? "reqonly" : "disabled";
6860 memset(&pref
, 0, sizeof(pref
));
6861 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6862 strcpy(caller_pref_buf
,"disabled");
6863 strcpy(host_pref_buf
,"disabled");
6865 using_prefs
= "mine";
6866 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
6867 /* Do the opposite of what we tried above. */
6868 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
6869 pref
= iaxs
[fr
->callno
]->prefs
;
6871 pref
= iaxs
[fr
->callno
]->rprefs
;
6872 using_prefs
= "caller";
6874 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
, 1);
6876 } else /* if no codec_prefs IE do it the old way */
6877 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6882 memset(&ied0
, 0, sizeof(ied0
));
6883 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
6884 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
6885 ast_log(LOG_ERROR
, "No best format in 0x%x???\n", iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6886 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6888 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
);
6889 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
6895 /* No authentication required, let them in */
6896 memset(&ied1
, 0, sizeof(ied1
));
6897 iax_ie_append_int(&ied1
, IAX_IE_FORMAT
, format
);
6898 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACCEPT
, 0, ied1
.buf
, ied1
.pos
, -1);
6899 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
6900 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
6901 if (option_verbose
> 2)
6902 ast_verbose(VERBOSE_PREFIX_3
"Accepting UNAUTHENTICATED call from %s:\n"
6903 "%srequested format = %s,\n"
6904 "%srequested prefs = %s,\n"
6905 "%sactual format = %s,\n"
6906 "%shost prefs = %s,\n"
6907 "%spriority = %s\n",
6908 ast_inet_ntoa(sin
.sin_addr
),
6910 ast_getformatname(iaxs
[fr
->callno
]->peerformat
),
6914 ast_getformatname(format
),
6920 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, format
)))
6921 iax2_destroy_nolock(fr
->callno
);
6923 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
6924 /* If this is a TBD call, we're ready but now what... */
6925 if (option_verbose
> 2)
6926 ast_verbose(VERBOSE_PREFIX_3
"Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin
.sin_addr
));
6932 if (iaxs
[fr
->callno
]->authmethods
& IAX_AUTH_MD5
)
6933 merge_encryption(iaxs
[fr
->callno
],ies
.encmethods
);
6935 iaxs
[fr
->callno
]->encmethods
= 0;
6936 if (!authenticate_request(iaxs
[fr
->callno
]))
6937 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_AUTHENTICATED
);
6939 case IAX_COMMAND_DPREQ
:
6940 /* Request status in the dialplan */
6941 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
) &&
6942 !ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
) && ies
.called_number
) {
6944 /* Spawn a thread for the lookup */
6945 spawn_dp_lookup(fr
->callno
, iaxs
[fr
->callno
]->context
, ies
.called_number
, iaxs
[fr
->callno
]->cid_num
);
6947 /* Just look it up */
6948 dp_lookup(fr
->callno
, iaxs
[fr
->callno
]->context
, ies
.called_number
, iaxs
[fr
->callno
]->cid_num
, 1);
6952 case IAX_COMMAND_HANGUP
:
6953 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
6954 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received hangup\n", fr
->callno
);
6955 /* Set hangup cause according to remote */
6956 if (ies
.causecode
&& iaxs
[fr
->callno
]->owner
)
6957 iaxs
[fr
->callno
]->owner
->hangupcause
= ies
.causecode
;
6958 /* Send ack immediately, before we destroy */
6959 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6960 iax2_destroy_nolock(fr
->callno
);
6962 case IAX_COMMAND_REJECT
:
6963 /* Set hangup cause according to remote */
6964 if (ies
.causecode
&& iaxs
[fr
->callno
]->owner
)
6965 iaxs
[fr
->callno
]->owner
->hangupcause
= ies
.causecode
;
6967 if (!ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
)) {
6968 if (iaxs
[fr
->callno
]->owner
&& authdebug
)
6969 ast_log(LOG_WARNING
, "Call rejected by %s: %s\n",
6970 ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
),
6971 ies
.cause
? ies
.cause
: "<Unknown>");
6972 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received reject\n",
6975 /* Send ack immediately, before we destroy */
6976 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
,
6977 fr
->ts
, NULL
, 0, fr
->iseqno
);
6978 if (!ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
))
6979 iaxs
[fr
->callno
]->error
= EPERM
;
6980 iax2_destroy_nolock(fr
->callno
);
6982 case IAX_COMMAND_TRANSFER
:
6983 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
) && ies
.called_number
) {
6984 /* Set BLINDTRANSFER channel variables */
6985 pbx_builtin_setvar_helper(iaxs
[fr
->callno
]->owner
, "BLINDTRANSFER", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
6986 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), "BLINDTRANSFER", iaxs
[fr
->callno
]->owner
->name
);
6987 if (!strcmp(ies
.called_number
, ast_parking_ext())) {
6988 if (iax_park(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), iaxs
[fr
->callno
]->owner
)) {
6989 ast_log(LOG_WARNING
, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
6991 ast_log(LOG_DEBUG
, "Parked call on '%s'\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
6993 if (ast_async_goto(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), iaxs
[fr
->callno
]->context
, ies
.called_number
, 1))
6994 ast_log(LOG_WARNING
, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
,
6995 ies
.called_number
, iaxs
[fr
->callno
]->context
);
6997 ast_log(LOG_DEBUG
, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
,
6998 ies
.called_number
, iaxs
[fr
->callno
]->context
);
7001 ast_log(LOG_DEBUG
, "Async goto not applicable on call %d\n", fr
->callno
);
7003 case IAX_COMMAND_ACCEPT
:
7004 /* Ignore if call is already up or needs authentication or is a TBD */
7005 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
| IAX_STATE_AUTHENTICATED
))
7007 if (ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
)) {
7008 /* Send ack immediately, before we destroy */
7009 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7010 iax2_destroy_nolock(fr
->callno
);
7014 iaxs
[fr
->callno
]->peerformat
= ies
.format
;
7016 if (iaxs
[fr
->callno
]->owner
)
7017 iaxs
[fr
->callno
]->peerformat
= iaxs
[fr
->callno
]->owner
->nativeformats
;
7019 iaxs
[fr
->callno
]->peerformat
= iaxs
[fr
->callno
]->capability
;
7021 if (option_verbose
> 2)
7022 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
));
7023 if (!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
)) {
7024 memset(&ied0
, 0, sizeof(ied0
));
7025 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7026 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7027 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7029 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
);
7031 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7032 if (iaxs
[fr
->callno
]->owner
) {
7033 /* Switch us to use a compatible format */
7034 iaxs
[fr
->callno
]->owner
->nativeformats
= iaxs
[fr
->callno
]->peerformat
;
7035 if (option_verbose
> 2)
7036 ast_verbose(VERBOSE_PREFIX_3
"Format for call is %s\n", ast_getformatname(iaxs
[fr
->callno
]->owner
->nativeformats
));
7038 if (ast_mutex_trylock(&iaxs
[fr
->callno
]->owner
->lock
)) {
7039 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7041 ast_mutex_lock(&iaxsl
[fr
->callno
]);
7042 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) goto retryowner2
;
7045 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) {
7046 /* Setup read/write formats properly. */
7047 if (iaxs
[fr
->callno
]->owner
->writeformat
)
7048 ast_set_write_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->writeformat
);
7049 if (iaxs
[fr
->callno
]->owner
->readformat
)
7050 ast_set_read_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->readformat
);
7051 ast_mutex_unlock(&iaxs
[fr
->callno
]->owner
->lock
);
7055 ast_mutex_lock(&dpcache_lock
);
7056 dp
= iaxs
[fr
->callno
]->dpentries
;
7058 if (!(dp
->flags
& CACHE_FLAG_TRANSMITTED
)) {
7059 iax2_dprequest(dp
, fr
->callno
);
7063 ast_mutex_unlock(&dpcache_lock
);
7065 case IAX_COMMAND_POKE
:
7066 /* Send back a pong packet with the original timestamp */
7067 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_PONG
, fr
->ts
, NULL
, 0, -1);
7069 case IAX_COMMAND_PING
:
7071 struct iax_ie_data pingied
;
7072 construct_rr(iaxs
[fr
->callno
], &pingied
);
7073 /* Send back a pong packet with the original timestamp */
7074 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_PONG
, fr
->ts
, pingied
.buf
, pingied
.pos
, -1);
7077 case IAX_COMMAND_PONG
:
7078 /* Calculate ping time */
7079 iaxs
[fr
->callno
]->pingtime
= calc_timestamp(iaxs
[fr
->callno
], 0, &f
) - fr
->ts
;
7083 if (iaxs
[fr
->callno
]->peerpoke
) {
7084 peer
= iaxs
[fr
->callno
]->peerpoke
;
7085 if ((peer
->lastms
< 0) || (peer
->historicms
> peer
->maxms
)) {
7086 if (iaxs
[fr
->callno
]->pingtime
<= peer
->maxms
) {
7087 ast_log(LOG_NOTICE
, "Peer '%s' is now REACHABLE! Time: %d\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7088 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7089 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7091 } else if ((peer
->historicms
> 0) && (peer
->historicms
<= peer
->maxms
)) {
7092 if (iaxs
[fr
->callno
]->pingtime
> peer
->maxms
) {
7093 ast_log(LOG_NOTICE
, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7094 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7095 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7098 peer
->lastms
= iaxs
[fr
->callno
]->pingtime
;
7099 if (peer
->smoothing
&& (peer
->lastms
> -1))
7100 peer
->historicms
= (iaxs
[fr
->callno
]->pingtime
+ peer
->historicms
) / 2;
7101 else if (peer
->smoothing
&& peer
->lastms
< 0)
7102 peer
->historicms
= (0 + peer
->historicms
) / 2;
7104 peer
->historicms
= iaxs
[fr
->callno
]->pingtime
;
7106 /* Remove scheduled iax2_poke_noanswer */
7107 if (peer
->pokeexpire
> -1)
7108 ast_sched_del(sched
, peer
->pokeexpire
);
7109 /* Schedule the next cycle */
7110 if ((peer
->lastms
< 0) || (peer
->historicms
> peer
->maxms
))
7111 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_peer_s
, peer
);
7113 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqok
, iax2_poke_peer_s
, peer
);
7114 /* and finally send the ack */
7115 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7116 /* And wrap up the qualify call */
7117 iax2_destroy_nolock(fr
->callno
);
7120 ast_log(LOG_DEBUG
, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer
->name
, peer
->lastms
, peer
->historicms
, peer
->maxms
);
7123 case IAX_COMMAND_LAGRQ
:
7124 case IAX_COMMAND_LAGRP
:
7129 iax_frame_wrap(fr
, &f
);
7130 if(f
.subclass
== IAX_COMMAND_LAGRQ
) {
7131 /* Received a LAGRQ - echo back a LAGRP */
7132 fr
->af
.subclass
= IAX_COMMAND_LAGRP
;
7133 iax2_send(iaxs
[fr
->callno
], &fr
->af
, fr
->ts
, -1, 0, 0, 0);
7135 /* Received LAGRP in response to our LAGRQ */
7137 /* This is a reply we've been given, actually measure the difference */
7138 ts
= calc_timestamp(iaxs
[fr
->callno
], 0, &fr
->af
);
7139 iaxs
[fr
->callno
]->lag
= ts
- fr
->ts
;
7140 if (option_debug
&& iaxdebug
)
7141 ast_log(LOG_DEBUG
, "Peer %s lag measured as %dms\n",
7142 ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
), iaxs
[fr
->callno
]->lag
);
7145 case IAX_COMMAND_AUTHREQ
:
7146 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
)) {
7147 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>");
7150 if (authenticate_reply(iaxs
[fr
->callno
], &iaxs
[fr
->callno
]->addr
, &ies
, iaxs
[fr
->callno
]->secret
, iaxs
[fr
->callno
]->outkey
)) {
7151 ast_log(LOG_WARNING
,
7152 "I don't know how to authenticate %s to %s\n",
7153 ies
.username
? ies
.username
: "<unknown>", ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
));
7156 case IAX_COMMAND_AUTHREP
:
7157 /* For security, always ack immediately */
7159 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7160 /* Ignore once we've started */
7161 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
)) {
7162 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>");
7165 if (authenticate_verify(iaxs
[fr
->callno
], &ies
)) {
7167 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
);
7168 memset(&ied0
, 0, sizeof(ied0
));
7169 auth_fail(fr
->callno
, IAX_COMMAND_REJECT
);
7172 if (strcasecmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
7173 /* This might re-enter the IAX code and need the lock */
7174 exists
= ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
);
7177 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD") && !exists
) {
7179 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
);
7180 memset(&ied0
, 0, sizeof(ied0
));
7181 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
7182 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
7183 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7185 /* Select an appropriate format */
7186 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
7187 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7188 using_prefs
= "reqonly";
7190 using_prefs
= "disabled";
7192 format
= iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
;
7193 memset(&pref
, 0, sizeof(pref
));
7194 strcpy(caller_pref_buf
, "disabled");
7195 strcpy(host_pref_buf
, "disabled");
7197 using_prefs
= "mine";
7198 if (ies
.codec_prefs
)
7199 ast_codec_pref_convert(&iaxs
[fr
->callno
]->rprefs
, ies
.codec_prefs
, 32, 0);
7200 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
7201 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
7202 pref
= iaxs
[fr
->callno
]->rprefs
;
7203 using_prefs
= "caller";
7205 pref
= iaxs
[fr
->callno
]->prefs
;
7207 } else /* if no codec_prefs IE do it the old way */
7208 pref
= iaxs
[fr
->callno
]->prefs
;
7210 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->capability
& iaxs
[fr
->callno
]->peercapability
, 0);
7211 ast_codec_pref_string(&iaxs
[fr
->callno
]->rprefs
, caller_pref_buf
, sizeof(caller_pref_buf
) - 1);
7212 ast_codec_pref_string(&iaxs
[fr
->callno
]->prefs
, host_pref_buf
, sizeof(host_pref_buf
) - 1);
7215 if(!ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7216 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
);
7217 format
= iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
;
7221 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
7222 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
);
7224 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
);
7226 memset(&ied0
, 0, sizeof(ied0
));
7227 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7228 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7229 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7232 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7233 if(!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
))
7236 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
7237 using_prefs
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ? "reqonly" : "disabled";
7238 memset(&pref
, 0, sizeof(pref
));
7239 format
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ?
7240 iaxs
[fr
->callno
]->peerformat
: ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7241 strcpy(caller_pref_buf
,"disabled");
7242 strcpy(host_pref_buf
,"disabled");
7244 using_prefs
= "mine";
7245 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
7246 /* Do the opposite of what we tried above. */
7247 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
7248 pref
= iaxs
[fr
->callno
]->prefs
;
7250 pref
= iaxs
[fr
->callno
]->rprefs
;
7251 using_prefs
= "caller";
7253 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
, 1);
7254 } else /* if no codec_prefs IE do it the old way */
7255 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7259 ast_log(LOG_ERROR
, "No best format in 0x%x???\n", iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7261 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
7262 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
);
7264 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
);
7266 memset(&ied0
, 0, sizeof(ied0
));
7267 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7268 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7269 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7274 /* Authentication received */
7275 memset(&ied1
, 0, sizeof(ied1
));
7276 iax_ie_append_int(&ied1
, IAX_IE_FORMAT
, format
);
7277 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACCEPT
, 0, ied1
.buf
, ied1
.pos
, -1);
7278 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
7279 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7280 if (option_verbose
> 2)
7281 ast_verbose(VERBOSE_PREFIX_3
"Accepting AUTHENTICATED call from %s:\n"
7282 "%srequested format = %s,\n"
7283 "%srequested prefs = %s,\n"
7284 "%sactual format = %s,\n"
7285 "%shost prefs = %s,\n"
7286 "%spriority = %s\n",
7287 ast_inet_ntoa(sin
.sin_addr
),
7289 ast_getformatname(iaxs
[fr
->callno
]->peerformat
),
7293 ast_getformatname(format
),
7299 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7300 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, format
)))
7301 iax2_destroy_nolock(fr
->callno
);
7303 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
7304 /* If this is a TBD call, we're ready but now what... */
7305 if (option_verbose
> 2)
7306 ast_verbose(VERBOSE_PREFIX_3
"Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin
.sin_addr
));
7311 case IAX_COMMAND_DIAL
:
7312 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
)) {
7313 ast_clear_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
7314 ast_string_field_set(iaxs
[fr
->callno
], exten
, ies
.called_number
? ies
.called_number
: "s");
7315 if (!ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
)) {
7317 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
);
7318 memset(&ied0
, 0, sizeof(ied0
));
7319 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
7320 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
7321 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7323 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7324 if (option_verbose
> 2)
7325 ast_verbose(VERBOSE_PREFIX_3
"Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin
.sin_addr
), iaxs
[fr
->callno
]->peerformat
);
7326 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7327 send_command(iaxs
[fr
->callno
], AST_FRAME_CONTROL
, AST_CONTROL_PROGRESS
, 0, NULL
, 0, -1);
7328 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, iaxs
[fr
->callno
]->peerformat
)))
7329 iax2_destroy_nolock(fr
->callno
);
7333 case IAX_COMMAND_INVAL
:
7334 iaxs
[fr
->callno
]->error
= ENOTCONN
;
7335 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received INVAL\n", fr
->callno
);
7336 iax2_destroy_nolock(fr
->callno
);
7338 ast_log(LOG_DEBUG
, "Destroying call %d\n", fr
->callno
);
7340 case IAX_COMMAND_VNAK
:
7341 ast_log(LOG_DEBUG
, "Received VNAK: resending outstanding frames\n");
7342 /* Force retransmission */
7343 vnak_retransmit(fr
->callno
, fr
->iseqno
);
7345 case IAX_COMMAND_REGREQ
:
7346 case IAX_COMMAND_REGREL
:
7347 /* For security, always ack immediately */
7349 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7350 if (register_verify(fr
->callno
, &sin
, &ies
)) {
7351 /* Send delayed failure */
7352 auth_fail(fr
->callno
, IAX_COMMAND_REGREJ
);
7355 if ((ast_strlen_zero(iaxs
[fr
->callno
]->secret
) && ast_strlen_zero(iaxs
[fr
->callno
]->inkeys
)) ||
7356 ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_AUTHENTICATED
| IAX_STATE_UNCHANGED
)) {
7357 if (f
.subclass
== IAX_COMMAND_REGREL
)
7358 memset(&sin
, 0, sizeof(sin
));
7359 if (update_registry(iaxs
[fr
->callno
]->peer
, &sin
, fr
->callno
, ies
.devicetype
, fd
, ies
.refresh
))
7360 ast_log(LOG_WARNING
, "Registry error\n");
7361 if (ies
.provverpres
&& ies
.serviceident
&& sin
.sin_addr
.s_addr
)
7362 check_provisioning(&sin
, fd
, ies
.serviceident
, ies
.provver
);
7365 registry_authrequest(iaxs
[fr
->callno
]->peer
, fr
->callno
);
7367 case IAX_COMMAND_REGACK
:
7368 if (iax2_ack_registry(&ies
, &sin
, fr
->callno
))
7369 ast_log(LOG_WARNING
, "Registration failure\n");
7370 /* Send ack immediately, before we destroy */
7371 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7372 iax2_destroy_nolock(fr
->callno
);
7374 case IAX_COMMAND_REGREJ
:
7375 if (iaxs
[fr
->callno
]->reg
) {
7377 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
));
7378 manager_event(EVENT_FLAG_SYSTEM
, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs
[fr
->callno
]->reg
->username
, ies
.cause
? ies
.cause
: "<unknown>");
7380 iaxs
[fr
->callno
]->reg
->regstate
= REG_STATE_REJECTED
;
7382 /* Send ack immediately, before we destroy */
7383 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7384 iax2_destroy_nolock(fr
->callno
);
7386 case IAX_COMMAND_REGAUTH
:
7387 /* Authentication request */
7388 if (registry_rerequest(&ies
, fr
->callno
, &sin
)) {
7389 memset(&ied0
, 0, sizeof(ied0
));
7390 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No authority found");
7391 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_NOT_SUBSCRIBED
);
7392 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7395 case IAX_COMMAND_TXREJ
:
7396 iaxs
[fr
->callno
]->transferring
= 0;
7397 if (option_verbose
> 2)
7398 ast_verbose(VERBOSE_PREFIX_3
"Channel '%s' unable to transfer\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>");
7399 memset(&iaxs
[fr
->callno
]->transfer
, 0, sizeof(iaxs
[fr
->callno
]->transfer
));
7400 if (iaxs
[fr
->callno
]->bridgecallno
) {
7401 if (iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
) {
7402 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= 0;
7403 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXREJ
, 0, NULL
, 0, -1);
7407 case IAX_COMMAND_TXREADY
:
7408 if ((iaxs
[fr
->callno
]->transferring
== TRANSFER_BEGIN
) ||
7409 (iaxs
[fr
->callno
]->transferring
== TRANSFER_MBEGIN
)) {
7410 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_MBEGIN
)
7411 iaxs
[fr
->callno
]->transferring
= TRANSFER_MREADY
;
7413 iaxs
[fr
->callno
]->transferring
= TRANSFER_READY
;
7414 if (option_verbose
> 2)
7415 ast_verbose(VERBOSE_PREFIX_3
"Channel '%s' ready to transfer\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>");
7416 if (iaxs
[fr
->callno
]->bridgecallno
) {
7417 if ((iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
== TRANSFER_READY
) ||
7418 (iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
== TRANSFER_MREADY
)) {
7419 /* They're both ready, now release them. */
7420 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_MREADY
) {
7421 if (option_verbose
> 2)
7422 ast_verbose(VERBOSE_PREFIX_3
"Attempting media bridge of %s and %s\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>",
7423 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
? iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
->name
: "<Unknown>");
7425 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= TRANSFER_MEDIA
;
7426 iaxs
[fr
->callno
]->transferring
= TRANSFER_MEDIA
;
7428 memset(&ied0
, 0, sizeof(ied0
));
7429 memset(&ied1
, 0, sizeof(ied1
));
7430 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->peercallno
);
7431 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->peercallno
);
7432 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXMEDIA
, 0, ied0
.buf
, ied0
.pos
, -1);
7433 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXMEDIA
, 0, ied1
.buf
, ied1
.pos
, -1);
7435 if (option_verbose
> 2)
7436 ast_verbose(VERBOSE_PREFIX_3
"Releasing %s and %s\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>",
7437 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
? iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
->name
: "<Unknown>");
7439 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= TRANSFER_RELEASED
;
7440 iaxs
[fr
->callno
]->transferring
= TRANSFER_RELEASED
;
7441 ast_set_flag(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], IAX_ALREADYGONE
);
7442 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
7444 /* Stop doing lag & ping requests */
7445 stop_stuff(fr
->callno
);
7446 stop_stuff(iaxs
[fr
->callno
]->bridgecallno
);
7448 memset(&ied0
, 0, sizeof(ied0
));
7449 memset(&ied1
, 0, sizeof(ied1
));
7450 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->peercallno
);
7451 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->peercallno
);
7452 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREL
, 0, ied0
.buf
, ied0
.pos
, -1);
7453 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXREL
, 0, ied1
.buf
, ied1
.pos
, -1);
7460 case IAX_COMMAND_TXREQ
:
7461 try_transfer(iaxs
[fr
->callno
], &ies
);
7463 case IAX_COMMAND_TXCNT
:
7464 if (iaxs
[fr
->callno
]->transferring
)
7465 send_command_transfer(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXACC
, 0, NULL
, 0);
7467 case IAX_COMMAND_TXREL
:
7468 /* Send ack immediately, rather than waiting until we've changed addresses */
7469 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7470 complete_transfer(fr
->callno
, &ies
);
7471 stop_stuff(fr
->callno
); /* for attended transfer to work with libiax */
7473 case IAX_COMMAND_TXMEDIA
:
7474 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_READY
) {
7475 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
7476 iaxs
[fr
->callno
]->transferring
= TRANSFER_MEDIAPASS
;
7479 case IAX_COMMAND_DPREP
:
7480 complete_dpreply(iaxs
[fr
->callno
], &ies
);
7482 case IAX_COMMAND_UNSUPPORT
:
7483 ast_log(LOG_NOTICE
, "Peer did not understand our iax command '%d'\n", ies
.iax_unknown
);
7485 case IAX_COMMAND_FWDOWNL
:
7486 /* Firmware download */
7487 memset(&ied0
, 0, sizeof(ied0
));
7488 res
= iax_firmware_append(&ied0
, (unsigned char *)ies
.devicetype
, ies
.fwdesc
);
7490 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7492 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_FWDATA
, 0, ied0
.buf
, ied0
.pos
, -1);
7494 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_FWDATA
, 0, ied0
.buf
, ied0
.pos
, -1);
7497 ast_log(LOG_DEBUG
, "Unknown IAX command %d on %d/%d\n", f
.subclass
, fr
->callno
, iaxs
[fr
->callno
]->peercallno
);
7498 memset(&ied0
, 0, sizeof(ied0
));
7499 iax_ie_append_byte(&ied0
, IAX_IE_IAX_UNKNOWN
, f
.subclass
);
7500 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_UNSUPPORT
, 0, ied0
.buf
, ied0
.pos
, -1);
7502 /* Don't actually pass these frames along */
7503 if ((f
.subclass
!= IAX_COMMAND_ACK
) &&
7504 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
7505 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
7506 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
7507 (f
.subclass
!= IAX_COMMAND_VNAK
)) {
7508 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->aseqno
!= iaxs
[fr
->callno
]->iseqno
)
7509 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7511 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7514 /* Unless this is an ACK or INVAL frame, ack it */
7515 if (iaxs
[fr
->callno
]->aseqno
!= iaxs
[fr
->callno
]->iseqno
)
7516 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7517 } else if (minivid
) {
7518 f
.frametype
= AST_FRAME_VIDEO
;
7519 if (iaxs
[fr
->callno
]->videoformat
> 0)
7520 f
.subclass
= iaxs
[fr
->callno
]->videoformat
| (ntohs(vh
->ts
) & 0x8000 ? 1 : 0);
7522 ast_log(LOG_WARNING
, "Received mini frame before first full video frame\n ");
7523 iax2_vnak(fr
->callno
);
7524 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7527 f
.datalen
= res
- sizeof(*vh
);
7529 f
.data
= thread
->buf
+ sizeof(*vh
);
7534 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF8000L
) | ((ntohs(mh
->ts
) + test_resync
) & 0x7fff);
7536 #endif /* IAXTESTS */
7537 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF8000L
) | (ntohs(mh
->ts
) & 0x7fff);
7540 f
.frametype
= AST_FRAME_VOICE
;
7541 if (iaxs
[fr
->callno
]->voiceformat
> 0)
7542 f
.subclass
= iaxs
[fr
->callno
]->voiceformat
;
7544 ast_log(LOG_WARNING
, "Received mini frame before first full voice frame\n ");
7545 iax2_vnak(fr
->callno
);
7546 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7549 f
.datalen
= res
- sizeof(struct ast_iax2_mini_hdr
);
7550 if (f
.datalen
< 0) {
7551 ast_log(LOG_WARNING
, "Datalen < 0?\n");
7552 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7556 f
.data
= thread
->buf
+ sizeof(*mh
);
7561 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | ((ntohs(mh
->ts
) + test_resync
) & 0xffff);
7563 #endif /* IAXTESTS */
7564 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | ntohs(mh
->ts
);
7565 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
7567 /* Don't pass any packets until we're started */
7568 if (!ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
7569 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7576 if (f
.datalen
&& (f
.frametype
== AST_FRAME_VOICE
)) {
7577 f
.samples
= ast_codec_get_samples(&f
);
7578 /* We need to byteswap incoming slinear samples from network byte order */
7579 if (f
.subclass
== AST_FORMAT_SLINEAR
)
7580 ast_frame_byteswap_be(&f
);
7583 iax_frame_wrap(fr
, &f
);
7585 /* If this is our most recent packet, use it as our basis for timestamping */
7586 if (iaxs
[fr
->callno
]->last
< fr
->ts
) {
7587 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
7590 if (option_debug
&& iaxdebug
)
7591 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
);
7592 fr
->outoforder
= -1;
7594 duped_fr
= iaxfrdup2(fr
);
7596 schedule_delivery(duped_fr
, updatehistory
, 0, &fr
->ts
);
7598 if (iaxs
[fr
->callno
]->last
< fr
->ts
) {
7599 iaxs
[fr
->callno
]->last
= fr
->ts
;
7601 if (option_debug
&& iaxdebug
)
7602 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
7606 /* Always run again */
7607 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7611 static void *iax2_process_thread(void *data
)
7613 struct iax2_thread
*thread
= data
;
7618 /* Wait for something to signal us to be awake */
7619 ast_mutex_lock(&thread
->lock
);
7620 if (thread
->type
== IAX_TYPE_DYNAMIC
) {
7621 /* Wait to be signalled or time out */
7622 tv
= ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
7623 ts
.tv_sec
= tv
.tv_sec
;
7624 ts
.tv_nsec
= tv
.tv_usec
* 1000;
7625 if (ast_cond_timedwait(&thread
->cond
, &thread
->lock
, &ts
) == ETIMEDOUT
) {
7626 ast_mutex_unlock(&thread
->lock
);
7627 AST_LIST_LOCK(&dynamic_list
);
7628 AST_LIST_REMOVE(&dynamic_list
, thread
, list
);
7629 iaxdynamicthreadcount
--;
7630 AST_LIST_UNLOCK(&dynamic_list
);
7634 ast_cond_wait(&thread
->cond
, &thread
->lock
);
7636 ast_mutex_unlock(&thread
->lock
);
7638 /* If we were signalled, then we are already out of both lists or we are shutting down */
7643 /* Add ourselves to the active list now */
7644 AST_LIST_LOCK(&active_list
);
7645 AST_LIST_INSERT_HEAD(&active_list
, thread
, list
);
7646 AST_LIST_UNLOCK(&active_list
);
7648 /* See what we need to do */
7649 switch(thread
->iostate
) {
7650 case IAX_IOSTATE_READY
:
7652 thread
->iostate
= IAX_IOSTATE_PROCESSING
;
7653 socket_process(thread
);
7655 case IAX_IOSTATE_SCHEDREADY
:
7657 thread
->iostate
= IAX_IOSTATE_PROCESSING
;
7658 #ifdef SCHED_MULTITHREADED
7659 thread
->schedfunc(thread
->scheddata
);
7663 time(&thread
->checktime
);
7664 thread
->iostate
= IAX_IOSTATE_IDLE
;
7665 #ifdef DEBUG_SCHED_MULTITHREAD
7666 thread
->curfunc
[0]='\0';
7669 /* Now... remove ourselves from the active list, and return to the idle list */
7670 AST_LIST_LOCK(&active_list
);
7671 AST_LIST_REMOVE(&active_list
, thread
, list
);
7672 AST_LIST_UNLOCK(&active_list
);
7674 /* Go back into our respective list */
7675 if (thread
->type
== IAX_TYPE_DYNAMIC
) {
7676 AST_LIST_LOCK(&dynamic_list
);
7677 AST_LIST_INSERT_TAIL(&dynamic_list
, thread
, list
);
7678 AST_LIST_UNLOCK(&dynamic_list
);
7680 AST_LIST_LOCK(&idle_list
);
7681 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
7682 AST_LIST_UNLOCK(&idle_list
);
7686 /* Free our own memory */
7687 ast_mutex_destroy(&thread
->lock
);
7688 ast_cond_destroy(&thread
->cond
);
7694 static int iax2_do_register(struct iax2_registry
*reg
)
7696 struct iax_ie_data ied
;
7697 if (option_debug
&& iaxdebug
)
7698 ast_log(LOG_DEBUG
, "Sending registration request for '%s'\n", reg
->username
);
7701 ((reg
->regstate
== REG_STATE_TIMEOUT
) || !reg
->addr
.sin_addr
.s_addr
)) {
7702 /* Maybe the IP has changed, force DNS refresh */
7703 ast_dnsmgr_refresh(reg
->dnsmgr
);
7707 * if IP has Changed, free allocated call to create a new one with new IP
7708 * call has the pointer to IP and must be updated to the new one
7710 if (reg
->dnsmgr
&& ast_dnsmgr_changed(reg
->dnsmgr
) && (reg
->callno
> 0)) {
7711 iax2_destroy(reg
->callno
);
7714 if (!reg
->addr
.sin_addr
.s_addr
) {
7715 if (option_debug
&& iaxdebug
)
7716 ast_log(LOG_DEBUG
, "Unable to send registration request for '%s' without IP address\n", reg
->username
);
7717 /* Setup the next registration attempt */
7718 if (reg
->expire
> -1)
7719 ast_sched_del(sched
, reg
->expire
);
7720 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
7726 ast_log(LOG_DEBUG
, "Allocate call number\n");
7727 reg
->callno
= find_callno(0, 0, ®
->addr
, NEW_FORCE
, 1, defaultsockfd
);
7728 if (reg
->callno
< 1) {
7729 ast_log(LOG_WARNING
, "Unable to create call for registration\n");
7731 } else if (option_debug
)
7732 ast_log(LOG_DEBUG
, "Registration created on call %d\n", reg
->callno
);
7733 iaxs
[reg
->callno
]->reg
= reg
;
7735 /* Schedule the next registration attempt */
7736 if (reg
->expire
> -1)
7737 ast_sched_del(sched
, reg
->expire
);
7738 /* Setup the next registration a little early */
7739 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
7740 /* Send the request */
7741 memset(&ied
, 0, sizeof(ied
));
7742 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, reg
->username
);
7743 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, reg
->refresh
);
7744 send_command(iaxs
[reg
->callno
],AST_FRAME_IAX
, IAX_COMMAND_REGREQ
, 0, ied
.buf
, ied
.pos
, -1);
7745 reg
->regstate
= REG_STATE_REGSENT
;
7749 static char *iax2_prov_complete_template_3rd(const char *line
, const char *word
, int pos
, int state
)
7753 return iax_prov_complete_template(line
, word
, pos
, state
);
7756 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
)
7758 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
7759 is found for template */
7760 struct iax_ie_data provdata
;
7761 struct iax_ie_data ied
;
7763 struct sockaddr_in sin
;
7765 struct create_addr_info cai
;
7767 memset(&cai
, 0, sizeof(cai
));
7770 ast_log(LOG_DEBUG
, "Provisioning '%s' from template '%s'\n", dest
, template);
7772 if (iax_provision_build(&provdata
, &sig
, template, force
)) {
7773 ast_log(LOG_DEBUG
, "No provisioning found for template '%s'\n", template);
7778 memcpy(&sin
, end
, sizeof(sin
));
7779 cai
.sockfd
= sockfd
;
7780 } else if (create_addr(dest
, &sin
, &cai
))
7783 /* Build the rest of the message */
7784 memset(&ied
, 0, sizeof(ied
));
7785 iax_ie_append_raw(&ied
, IAX_IE_PROVISIONING
, provdata
.buf
, provdata
.pos
);
7787 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
7791 ast_mutex_lock(&iaxsl
[callno
]);
7793 /* Schedule autodestruct in case they don't ever give us anything back */
7794 if (iaxs
[callno
]->autoid
> -1)
7795 ast_sched_del(sched
, iaxs
[callno
]->autoid
);
7796 iaxs
[callno
]->autoid
= ast_sched_add(sched
, 15000, auto_hangup
, (void *)(long)callno
);
7797 ast_set_flag(iaxs
[callno
], IAX_PROVISION
);
7798 /* Got a call number now, so go ahead and send the provisioning information */
7799 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_PROVISION
, 0, ied
.buf
, ied
.pos
, -1);
7801 ast_mutex_unlock(&iaxsl
[callno
]);
7806 static char *papp
= "IAX2Provision";
7807 static char *psyn
= "Provision a calling IAXy with a given template";
7808 static char *pdescrip
=
7809 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
7810 "the calling entity is in fact an IAXy) with the given template or\n"
7811 "default if one is not specified. Returns -1 on error or 0 on success.\n";
7814 \ingroup applications
7816 static int iax2_prov_app(struct ast_channel
*chan
, void *data
)
7822 unsigned short callno
= PTR_TO_CALLNO(chan
->tech_pvt
);
7823 if (ast_strlen_zero(data
))
7825 sdata
= ast_strdupa(data
);
7826 opts
= strchr(sdata
, '|');
7830 if (chan
->tech
!= &iax2_tech
) {
7831 ast_log(LOG_NOTICE
, "Can't provision a non-IAX device!\n");
7834 if (!callno
|| !iaxs
[callno
] || !iaxs
[callno
]->addr
.sin_addr
.s_addr
) {
7835 ast_log(LOG_NOTICE
, "Can't provision something with no IP?\n");
7838 res
= iax2_provision(&iaxs
[callno
]->addr
, iaxs
[callno
]->sockfd
, NULL
, sdata
, force
);
7839 if (option_verbose
> 2)
7840 ast_verbose(VERBOSE_PREFIX_3
"Provisioned IAXY at '%s' with '%s'= %d\n",
7841 ast_inet_ntoa(iaxs
[callno
]->addr
.sin_addr
),
7847 static int iax2_prov_cmd(int fd
, int argc
, char *argv
[])
7852 return RESULT_SHOWUSAGE
;
7854 if (!strcasecmp(argv
[4], "forced"))
7857 return RESULT_SHOWUSAGE
;
7859 res
= iax2_provision(NULL
, -1, argv
[2], argv
[3], force
);
7861 ast_cli(fd
, "Unable to find peer/address '%s'\n", argv
[2]);
7863 ast_cli(fd
, "No template (including wildcard) matching '%s'\n", argv
[3]);
7865 ast_cli(fd
, "Provisioning '%s' with template '%s'%s\n", argv
[2], argv
[3], force
? ", forced" : "");
7866 return RESULT_SUCCESS
;
7869 static void __iax2_poke_noanswer(void *data
)
7871 struct iax2_peer
*peer
= data
;
7872 if (peer
->lastms
> -1) {
7873 ast_log(LOG_NOTICE
, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer
->name
, peer
->lastms
);
7874 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer
->name
, peer
->lastms
);
7875 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7877 if (peer
->callno
> 0)
7878 iax2_destroy(peer
->callno
);
7881 /* Try again quickly */
7882 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_peer_s
, peer
);
7885 static int iax2_poke_noanswer(void *data
)
7887 struct iax2_peer
*peer
= data
;
7888 peer
->pokeexpire
= -1;
7889 #ifdef SCHED_MULTITHREADED
7890 if (schedule_action(__iax2_poke_noanswer
, data
))
7892 __iax2_poke_noanswer(data
);
7896 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
)
7898 if (!peer
->maxms
|| !peer
->addr
.sin_addr
.s_addr
) {
7899 /* IF we have no IP, or this isn't to be monitored, return
7900 immediately after clearing things out */
7902 peer
->historicms
= 0;
7903 peer
->pokeexpire
= -1;
7907 if (peer
->callno
> 0) {
7908 ast_log(LOG_NOTICE
, "Still have a callno...\n");
7909 iax2_destroy(peer
->callno
);
7912 ast_mutex_unlock(&iaxsl
[heldcall
]);
7913 peer
->callno
= find_callno(0, 0, &peer
->addr
, NEW_FORCE
, 0, peer
->sockfd
);
7915 ast_mutex_lock(&iaxsl
[heldcall
]);
7916 if (peer
->callno
< 1) {
7917 ast_log(LOG_WARNING
, "Unable to allocate call for poking peer '%s'\n", peer
->name
);
7921 /* Speed up retransmission times for this qualify call */
7922 iaxs
[peer
->callno
]->pingtime
= peer
->maxms
/ 4 + 1;
7923 iaxs
[peer
->callno
]->peerpoke
= peer
;
7925 /* Remove any pending pokeexpire task */
7926 if (peer
->pokeexpire
> -1)
7927 ast_sched_del(sched
, peer
->pokeexpire
);
7929 /* Queue up a new task to handle no reply */
7930 /* If the host is already unreachable then use the unreachable interval instead */
7931 if (peer
->lastms
< 0) {
7932 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_noanswer
, peer
);
7934 peer
->pokeexpire
= ast_sched_add(sched
, DEFAULT_MAXMS
* 2, iax2_poke_noanswer
, peer
);
7936 /* And send the poke */
7937 send_command(iaxs
[peer
->callno
], AST_FRAME_IAX
, IAX_COMMAND_POKE
, 0, NULL
, 0, -1);
7942 static void free_context(struct iax2_context
*con
)
7944 struct iax2_context
*conl
;
7952 static struct ast_channel
*iax2_request(const char *type
, int format
, void *data
, int *cause
)
7957 struct sockaddr_in sin
;
7958 struct ast_channel
*c
;
7959 struct parsed_dial_string pds
;
7960 struct create_addr_info cai
;
7963 memset(&pds
, 0, sizeof(pds
));
7964 tmpstr
= ast_strdupa(data
);
7965 parse_dial_string(tmpstr
, &pds
);
7967 memset(&cai
, 0, sizeof(cai
));
7968 cai
.capability
= iax2_capability
;
7970 ast_copy_flags(&cai
, &globalflags
, IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
7973 ast_log(LOG_WARNING
, "No peer given\n");
7978 /* Populate our address from the given */
7979 if (create_addr(pds
.peer
, &sin
, &cai
)) {
7980 *cause
= AST_CAUSE_UNREGISTERED
;
7985 sin
.sin_port
= htons(atoi(pds
.port
));
7987 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
7989 ast_log(LOG_WARNING
, "Unable to create call\n");
7990 *cause
= AST_CAUSE_CONGESTION
;
7994 ast_mutex_lock(&iaxsl
[callno
]);
7996 /* If this is a trunk, update it now */
7997 ast_copy_flags(iaxs
[callno
], &cai
, IAX_TRUNK
| IAX_SENDANI
| IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
7998 if (ast_test_flag(&cai
, IAX_TRUNK
))
7999 callno
= make_trunk(callno
, 1);
8000 iaxs
[callno
]->maxtime
= cai
.maxtime
;
8002 ast_string_field_set(iaxs
[callno
], host
, pds
.peer
);
8004 c
= ast_iax2_new(callno
, AST_STATE_DOWN
, cai
.capability
);
8006 ast_mutex_unlock(&iaxsl
[callno
]);
8009 /* Choose a format we can live with */
8010 if (c
->nativeformats
& format
)
8011 c
->nativeformats
&= format
;
8013 native
= c
->nativeformats
;
8015 res
= ast_translator_best_choice(&fmt
, &native
);
8017 ast_log(LOG_WARNING
, "Unable to create translator path for %s to %s on %s\n",
8018 ast_getformatname(c
->nativeformats
), ast_getformatname(fmt
), c
->name
);
8022 c
->nativeformats
= native
;
8024 c
->readformat
= ast_best_codec(c
->nativeformats
);
8025 c
->writeformat
= c
->readformat
;
8031 static void *sched_thread(void *ignore
)
8039 res
= ast_sched_wait(sched
);
8040 if ((res
> 1000) || (res
< 0))
8042 tv
= ast_tvadd(ast_tvnow(), ast_samp2tv(res
, 1000));
8043 ts
.tv_sec
= tv
.tv_sec
;
8044 ts
.tv_nsec
= tv
.tv_usec
* 1000;
8046 ast_mutex_lock(&sched_lock
);
8047 ast_cond_timedwait(&sched_cond
, &sched_lock
, &ts
);
8048 if (sched_halt
== 1)
8050 ast_mutex_unlock(&sched_lock
);
8052 count
= ast_sched_runq(sched
);
8054 ast_log(LOG_DEBUG
, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count
);
8056 ast_mutex_unlock(&sched_lock
);
8060 static void *network_thread(void *ignore
)
8062 /* Our job is simple: Send queued messages, retrying if necessary. Read frames
8063 from the network, and queue them for delivery to the channels */
8065 struct iax_frame
*f
;
8068 ast_io_add(io
, timingfd
, timing_read
, AST_IO_IN
| AST_IO_PRI
, NULL
);
8071 /* Go through the queue, sending messages which have not yet been
8072 sent, and scheduling retransmissions if appropriate */
8073 AST_LIST_LOCK(&iaxq
.queue
);
8075 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq
.queue
, f
, list
) {
8080 /* Send a copy immediately -- errors here are ok, so don't bother locking */
8081 if (iaxs
[f
->callno
]) {
8085 if (f
->retries
< 0) {
8086 /* This is not supposed to be retransmitted */
8087 AST_LIST_REMOVE(&iaxq
.queue
, f
, list
);
8089 /* Free the iax frame */
8092 /* We need reliable delivery. Schedule a retransmission */
8094 f
->retrans
= ast_sched_add(sched
, f
->retrytime
, attempt_transmit
, f
);
8095 signal_condition(&sched_lock
, &sched_cond
);
8098 AST_LIST_TRAVERSE_SAFE_END
8099 AST_LIST_UNLOCK(&iaxq
.queue
);
8102 ast_log(LOG_DEBUG
, "chan_iax2: Sent %d queued outbound frames all at once\n", count
);
8104 /* Now do the IO, and run scheduled tasks */
8105 res
= ast_io_wait(io
, -1);
8108 ast_log(LOG_DEBUG
, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res
);
8114 static int start_network_thread(void)
8116 int threadcount
= 0;
8118 for (x
= 0; x
< iaxthreadcount
; x
++) {
8119 struct iax2_thread
*thread
= ast_calloc(1, sizeof(struct iax2_thread
));
8121 thread
->type
= IAX_TYPE_POOL
;
8122 thread
->threadnum
= ++threadcount
;
8123 ast_mutex_init(&thread
->lock
);
8124 ast_cond_init(&thread
->cond
, NULL
);
8125 if (ast_pthread_create(&thread
->threadid
, NULL
, iax2_process_thread
, thread
)) {
8126 ast_log(LOG_WARNING
, "Failed to create new thread!\n");
8130 AST_LIST_LOCK(&idle_list
);
8131 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
8132 AST_LIST_UNLOCK(&idle_list
);
8135 ast_pthread_create(&schedthreadid
, NULL
, sched_thread
, NULL
);
8136 ast_pthread_create(&netthreadid
, NULL
, network_thread
, NULL
);
8137 if (option_verbose
> 1)
8138 ast_verbose(VERBOSE_PREFIX_2
"%d helper threaads started\n", threadcount
);
8142 static struct iax2_context
*build_context(char *context
)
8144 struct iax2_context
*con
;
8146 if ((con
= ast_calloc(1, sizeof(*con
))))
8147 ast_copy_string(con
->context
, context
, sizeof(con
->context
));
8152 static int get_auth_methods(char *value
)
8155 if (strstr(value
, "rsa"))
8156 methods
|= IAX_AUTH_RSA
;
8157 if (strstr(value
, "md5"))
8158 methods
|= IAX_AUTH_MD5
;
8159 if (strstr(value
, "plaintext"))
8160 methods
|= IAX_AUTH_PLAINTEXT
;
8165 /*! \brief Check if address can be used as packet source.
8166 \return 0 address available, 1 address unavailable, -1 error
8168 static int check_srcaddr(struct sockaddr
*sa
, socklen_t salen
)
8173 sd
= socket(AF_INET
, SOCK_DGRAM
, 0);
8175 ast_log(LOG_ERROR
, "Socket: %s\n", strerror(errno
));
8179 res
= bind(sd
, sa
, salen
);
8181 ast_log(LOG_DEBUG
, "Can't bind: %s\n", strerror(errno
));
8190 /*! \brief Parse the "sourceaddress" value,
8191 lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
8193 static int peer_set_srcaddr(struct iax2_peer
*peer
, const char *srcaddr
)
8195 struct sockaddr_in sin
;
8197 int port
= IAX_DEFAULT_PORTNO
;
8198 int sockfd
= defaultsockfd
;
8203 if (!(tmp
= ast_strdupa(srcaddr
)))
8206 addr
= strsep(&tmp
, ":");
8210 port
= atoi(portstr
);
8212 port
= IAX_DEFAULT_PORTNO
;
8215 if (!ast_get_ip(&sin
, addr
)) {
8216 struct ast_netsock
*sock
;
8220 sin
.sin_family
= AF_INET
;
8221 res
= check_srcaddr((struct sockaddr
*) &sin
, sizeof(sin
));
8223 /* ip address valid. */
8224 sin
.sin_port
= htons(port
);
8225 sock
= ast_netsock_find(netsock
, &sin
);
8227 sockfd
= ast_netsock_sockfd(sock
);
8233 peer
->sockfd
= sockfd
;
8236 ast_log(LOG_WARNING
, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
8237 srcaddr
, peer
->name
);
8240 ast_log(LOG_DEBUG
, "Using sourceaddress %s for '%s'\n", srcaddr
, peer
->name
);
8246 /*! \brief Create peer structure based on configuration */
8247 static struct iax2_peer
*build_peer(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
)
8249 struct iax2_peer
*peer
= NULL
;
8250 struct ast_ha
*oldha
= NULL
;
8255 AST_LIST_LOCK(&peers
);
8257 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
8258 if (!strcmp(peer
->name
, name
)) {
8259 if (!ast_test_flag(peer
, IAX_DELME
))
8272 AST_LIST_REMOVE(&peers
, peer
, entry
);
8273 AST_LIST_UNLOCK(&peers
);
8275 AST_LIST_UNLOCK(&peers
);
8276 if ((peer
= ast_calloc(1, sizeof(*peer
)))) {
8278 peer
->pokeexpire
= -1;
8279 peer
->sockfd
= defaultsockfd
;
8280 if (ast_string_field_init(peer
, 32)) {
8288 ast_copy_flags(peer
, &globalflags
, IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
8289 peer
->encmethods
= iax2_encryption
;
8291 ast_string_field_set(peer
,secret
,"");
8293 ast_string_field_set(peer
, name
, name
);
8294 peer
->addr
.sin_port
= htons(IAX_DEFAULT_PORTNO
);
8295 peer
->expiry
= min_reg_expire
;
8297 peer
->prefs
= prefs
;
8298 peer
->capability
= iax2_capability
;
8299 peer
->smoothing
= 0;
8300 peer
->pokefreqok
= DEFAULT_FREQ_OK
;
8301 peer
->pokefreqnotok
= DEFAULT_FREQ_NOTOK
;
8302 ast_string_field_set(peer
,context
,"");
8303 ast_string_field_set(peer
,peercontext
,"");
8311 if (!strcasecmp(v
->name
, "secret")) {
8312 ast_string_field_set(peer
, secret
, v
->value
);
8313 } else if (!strcasecmp(v
->name
, "mailbox")) {
8314 ast_string_field_set(peer
, mailbox
, v
->value
);
8315 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
8316 ast_string_field_set(peer
, mohinterpret
, v
->value
);
8317 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
8318 ast_string_field_set(peer
, mohsuggest
, v
->value
);
8319 } else if (!strcasecmp(v
->name
, "dbsecret")) {
8320 ast_string_field_set(peer
, dbsecret
, v
->value
);
8321 } else if (!strcasecmp(v
->name
, "trunk")) {
8322 ast_set2_flag(peer
, ast_true(v
->value
), IAX_TRUNK
);
8323 if (ast_test_flag(peer
, IAX_TRUNK
) && (timingfd
< 0)) {
8324 ast_log(LOG_WARNING
, "Unable to support trunking on peer '%s' without zaptel timing\n", peer
->name
);
8325 ast_clear_flag(peer
, IAX_TRUNK
);
8327 } else if (!strcasecmp(v
->name
, "auth")) {
8328 peer
->authmethods
= get_auth_methods(v
->value
);
8329 } else if (!strcasecmp(v
->name
, "encryption")) {
8330 peer
->encmethods
= get_encrypt_methods(v
->value
);
8331 } else if (!strcasecmp(v
->name
, "notransfer")) {
8332 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8333 ast_clear_flag(peer
, IAX_TRANSFERMEDIA
);
8334 ast_set2_flag(peer
, ast_true(v
->value
), IAX_NOTRANSFER
);
8335 } else if (!strcasecmp(v
->name
, "transfer")) {
8336 if (!strcasecmp(v
->value
, "mediaonly")) {
8337 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8338 } else if (ast_true(v
->value
)) {
8339 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8341 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8342 } else if (!strcasecmp(v
->name
, "jitterbuffer")) {
8343 ast_set2_flag(peer
, ast_true(v
->value
), IAX_USEJITTERBUF
);
8344 } else if (!strcasecmp(v
->name
, "forcejitterbuffer")) {
8345 ast_set2_flag(peer
, ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8346 } else if (!strcasecmp(v
->name
, "host")) {
8347 if (!strcasecmp(v
->value
, "dynamic")) {
8348 /* They'll register with us */
8349 ast_set_flag(peer
, IAX_DYNAMIC
);
8351 /* Initialize stuff iff we're not found, otherwise
8352 we keep going with what we had */
8353 memset(&peer
->addr
.sin_addr
, 0, 4);
8354 if (peer
->addr
.sin_port
) {
8355 /* If we've already got a port, make it the default rather than absolute */
8356 peer
->defaddr
.sin_port
= peer
->addr
.sin_port
;
8357 peer
->addr
.sin_port
= 0;
8361 /* Non-dynamic. Make sure we become that way if we're not */
8362 if (peer
->expire
> -1)
8363 ast_sched_del(sched
, peer
->expire
);
8365 ast_clear_flag(peer
, IAX_DYNAMIC
);
8366 if (ast_dnsmgr_lookup(v
->value
, &peer
->addr
.sin_addr
, &peer
->dnsmgr
)) {
8367 ast_string_field_free_all(peer
);
8371 if (!peer
->addr
.sin_port
)
8372 peer
->addr
.sin_port
= htons(IAX_DEFAULT_PORTNO
);
8375 inet_aton("255.255.255.255", &peer
->mask
);
8376 } else if (!strcasecmp(v
->name
, "defaultip")) {
8377 if (ast_get_ip(&peer
->defaddr
, v
->value
)) {
8378 ast_string_field_free_all(peer
);
8382 } else if (!strcasecmp(v
->name
, "sourceaddress")) {
8383 peer_set_srcaddr(peer
, v
->value
);
8384 } else if (!strcasecmp(v
->name
, "permit") ||
8385 !strcasecmp(v
->name
, "deny")) {
8386 peer
->ha
= ast_append_ha(v
->name
, v
->value
, peer
->ha
);
8387 } else if (!strcasecmp(v
->name
, "mask")) {
8389 inet_aton(v
->value
, &peer
->mask
);
8390 } else if (!strcasecmp(v
->name
, "context")) {
8391 if (ast_strlen_zero(peer
->context
))
8392 ast_string_field_set(peer
, context
, v
->value
);
8393 } else if (!strcasecmp(v
->name
, "regexten")) {
8394 ast_string_field_set(peer
, regexten
, v
->value
);
8395 } else if (!strcasecmp(v
->name
, "peercontext")) {
8396 if (ast_strlen_zero(peer
->peercontext
))
8397 ast_string_field_set(peer
, peercontext
, v
->value
);
8398 } else if (!strcasecmp(v
->name
, "port")) {
8399 if (ast_test_flag(peer
, IAX_DYNAMIC
))
8400 peer
->defaddr
.sin_port
= htons(atoi(v
->value
));
8402 peer
->addr
.sin_port
= htons(atoi(v
->value
));
8403 } else if (!strcasecmp(v
->name
, "username")) {
8404 ast_string_field_set(peer
, username
, v
->value
);
8405 } else if (!strcasecmp(v
->name
, "allow")) {
8406 ast_parse_allow_disallow(&peer
->prefs
, &peer
->capability
, v
->value
, 1);
8407 } else if (!strcasecmp(v
->name
, "disallow")) {
8408 ast_parse_allow_disallow(&peer
->prefs
, &peer
->capability
, v
->value
, 0);
8409 } else if (!strcasecmp(v
->name
, "callerid")) {
8412 ast_callerid_split(v
->value
, name2
, 80, num2
, 80);
8413 ast_string_field_set(peer
, cid_name
, name2
);
8414 ast_string_field_set(peer
, cid_num
, num2
);
8415 ast_set_flag(peer
, IAX_HASCALLERID
);
8416 } else if (!strcasecmp(v
->name
, "fullname")) {
8417 ast_string_field_set(peer
, cid_name
, v
->value
);
8418 ast_set_flag(peer
, IAX_HASCALLERID
);
8419 } else if (!strcasecmp(v
->name
, "cid_number")) {
8420 ast_string_field_set(peer
, cid_num
, v
->value
);
8421 ast_set_flag(peer
, IAX_HASCALLERID
);
8422 } else if (!strcasecmp(v
->name
, "sendani")) {
8423 ast_set2_flag(peer
, ast_true(v
->value
), IAX_SENDANI
);
8424 } else if (!strcasecmp(v
->name
, "inkeys")) {
8425 ast_string_field_set(peer
, inkeys
, v
->value
);
8426 } else if (!strcasecmp(v
->name
, "outkey")) {
8427 ast_string_field_set(peer
, outkey
, v
->value
);
8428 } else if (!strcasecmp(v
->name
, "qualify")) {
8429 if (!strcasecmp(v
->value
, "no")) {
8431 } else if (!strcasecmp(v
->value
, "yes")) {
8432 peer
->maxms
= DEFAULT_MAXMS
;
8433 } else if (sscanf(v
->value
, "%d", &peer
->maxms
) != 1) {
8434 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
);
8437 } else if (!strcasecmp(v
->name
, "qualifysmoothing")) {
8438 peer
->smoothing
= ast_true(v
->value
);
8439 } else if (!strcasecmp(v
->name
, "qualifyfreqok")) {
8440 if (sscanf(v
->value
, "%d", &peer
->pokefreqok
) != 1) {
8441 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
);
8443 } else if (!strcasecmp(v
->name
, "qualifyfreqnotok")) {
8444 if (sscanf(v
->value
, "%d", &peer
->pokefreqnotok
) != 1) {
8445 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
);
8446 } else ast_log(LOG_WARNING
, "Set peer->pokefreqnotok to %d\n", peer
->pokefreqnotok
);
8447 } else if (!strcasecmp(v
->name
, "timezone")) {
8448 ast_string_field_set(peer
, zonetag
, v
->value
);
8449 } else if (!strcasecmp(v
->name
, "adsi")) {
8450 peer
->adsi
= ast_true(v
->value
);
8451 }/* else if (strcasecmp(v->name,"type")) */
8452 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8459 if (!peer
->authmethods
)
8460 peer
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8461 ast_clear_flag(peer
, IAX_DELME
);
8462 /* Make sure these are IPv4 addresses */
8463 peer
->addr
.sin_family
= AF_INET
;
8470 /*! \brief Create in-memory user structure from configuration */
8471 static struct iax2_user
*build_user(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
)
8473 struct iax2_user
*user
= NULL
;
8474 struct iax2_context
*con
, *conl
= NULL
;
8475 struct ast_ha
*oldha
= NULL
;
8476 struct iax2_context
*oldcon
= NULL
;
8479 int oldcurauthreq
= 0;
8480 char *varname
= NULL
, *varval
= NULL
;
8481 struct ast_variable
*tmpvar
= NULL
;
8483 AST_LIST_LOCK(&users
);
8485 AST_LIST_TRAVERSE(&users
, user
, entry
) {
8486 if (!strcmp(user
->name
, name
)) {
8487 if (!ast_test_flag(user
, IAX_DELME
))
8497 oldcurauthreq
= user
->curauthreq
;
8499 oldcon
= user
->contexts
;
8501 user
->contexts
= NULL
;
8503 /* Already in the list, remove it and it will be added back (or FREE'd) */
8504 AST_LIST_REMOVE(&users
, user
, entry
);
8505 AST_LIST_UNLOCK(&users
);
8507 AST_LIST_UNLOCK(&users
);
8508 /* This is going to memset'd to 0 in the next block */
8509 user
= ast_calloc(sizeof(*user
),1);
8514 ast_string_field_free_all(user
);
8515 memset(user
, 0, sizeof(struct iax2_user
));
8516 if (ast_string_field_init(user
, 32)) {
8520 user
->maxauthreq
= maxauthreq
;
8521 user
->curauthreq
= oldcurauthreq
;
8522 user
->prefs
= prefs
;
8523 user
->capability
= iax2_capability
;
8524 user
->encmethods
= iax2_encryption
;
8526 ast_string_field_set(user
, name
, name
);
8527 ast_string_field_set(user
, language
, language
);
8528 ast_copy_flags(user
, &globalflags
, IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
| IAX_CODEC_USER_FIRST
| IAX_CODEC_NOPREFS
| IAX_CODEC_NOCAP
);
8535 if (!strcasecmp(v
->name
, "context")) {
8536 con
= build_context(v
->value
);
8541 user
->contexts
= con
;
8544 } else if (!strcasecmp(v
->name
, "permit") ||
8545 !strcasecmp(v
->name
, "deny")) {
8546 user
->ha
= ast_append_ha(v
->name
, v
->value
, user
->ha
);
8547 } else if (!strcasecmp(v
->name
, "setvar")) {
8548 varname
= ast_strdupa(v
->value
);
8549 if (varname
&& (varval
= strchr(varname
,'='))) {
8552 if((tmpvar
= ast_variable_new(varname
, varval
))) {
8553 tmpvar
->next
= user
->vars
;
8554 user
->vars
= tmpvar
;
8557 } else if (!strcasecmp(v
->name
, "allow")) {
8558 ast_parse_allow_disallow(&user
->prefs
, &user
->capability
, v
->value
, 1);
8559 } else if (!strcasecmp(v
->name
, "disallow")) {
8560 ast_parse_allow_disallow(&user
->prefs
, &user
->capability
,v
->value
, 0);
8561 } else if (!strcasecmp(v
->name
, "trunk")) {
8562 ast_set2_flag(user
, ast_true(v
->value
), IAX_TRUNK
);
8563 if (ast_test_flag(user
, IAX_TRUNK
) && (timingfd
< 0)) {
8564 ast_log(LOG_WARNING
, "Unable to support trunking on user '%s' without zaptel timing\n", user
->name
);
8565 ast_clear_flag(user
, IAX_TRUNK
);
8567 } else if (!strcasecmp(v
->name
, "auth")) {
8568 user
->authmethods
= get_auth_methods(v
->value
);
8569 } else if (!strcasecmp(v
->name
, "encryption")) {
8570 user
->encmethods
= get_encrypt_methods(v
->value
);
8571 } else if (!strcasecmp(v
->name
, "notransfer")) {
8572 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8573 ast_clear_flag(user
, IAX_TRANSFERMEDIA
);
8574 ast_set2_flag(user
, ast_true(v
->value
), IAX_NOTRANSFER
);
8575 } else if (!strcasecmp(v
->name
, "transfer")) {
8576 if (!strcasecmp(v
->value
, "mediaonly")) {
8577 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8578 } else if (ast_true(v
->value
)) {
8579 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8581 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8582 } else if (!strcasecmp(v
->name
, "codecpriority")) {
8583 if(!strcasecmp(v
->value
, "caller"))
8584 ast_set_flag(user
, IAX_CODEC_USER_FIRST
);
8585 else if(!strcasecmp(v
->value
, "disabled"))
8586 ast_set_flag(user
, IAX_CODEC_NOPREFS
);
8587 else if(!strcasecmp(v
->value
, "reqonly")) {
8588 ast_set_flag(user
, IAX_CODEC_NOCAP
);
8589 ast_set_flag(user
, IAX_CODEC_NOPREFS
);
8591 } else if (!strcasecmp(v
->name
, "jitterbuffer")) {
8592 ast_set2_flag(user
, ast_true(v
->value
), IAX_USEJITTERBUF
);
8593 } else if (!strcasecmp(v
->name
, "forcejitterbuffer")) {
8594 ast_set2_flag(user
, ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8595 } else if (!strcasecmp(v
->name
, "dbsecret")) {
8596 ast_string_field_set(user
, dbsecret
, v
->value
);
8597 } else if (!strcasecmp(v
->name
, "secret")) {
8598 if (!ast_strlen_zero(user
->secret
)) {
8600 strncpy(buf99
,user
->secret
,100); /* just in case some weirdness happens in the string_field_build */
8601 ast_string_field_build(user
,secret
,"%s;%s",buf99
,v
->value
);
8602 /* strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
8603 strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1); */
8605 ast_string_field_set(user
, secret
, v
->value
);
8606 } else if (!strcasecmp(v
->name
, "callerid")) {
8609 ast_callerid_split(v
->value
, name2
, 80, num2
, 80);
8610 ast_string_field_set(user
, cid_name
, name2
);
8611 ast_string_field_set(user
, cid_num
, num2
);
8612 ast_set_flag(user
, IAX_HASCALLERID
);
8613 } else if (!strcasecmp(v
->name
, "fullname")) {
8614 ast_string_field_set(user
, cid_name
, v
->value
);
8615 ast_set_flag(user
, IAX_HASCALLERID
);
8616 } else if (!strcasecmp(v
->name
, "cid_number")) {
8617 ast_string_field_set(user
, cid_num
, v
->value
);
8618 ast_set_flag(user
, IAX_HASCALLERID
);
8619 } else if (!strcasecmp(v
->name
, "accountcode")) {
8620 ast_string_field_set(user
, accountcode
, v
->value
);
8621 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
8622 ast_string_field_set(user
, mohinterpret
, v
->value
);
8623 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
8624 ast_string_field_set(user
, mohsuggest
, v
->value
);
8625 } else if (!strcasecmp(v
->name
, "language")) {
8626 ast_string_field_set(user
, language
, v
->value
);
8627 } else if (!strcasecmp(v
->name
, "amaflags")) {
8628 format
= ast_cdr_amaflags2int(v
->value
);
8630 ast_log(LOG_WARNING
, "Invalid AMA Flags: %s at line %d\n", v
->value
, v
->lineno
);
8632 user
->amaflags
= format
;
8634 } else if (!strcasecmp(v
->name
, "inkeys")) {
8635 ast_string_field_set(user
, inkeys
, v
->value
);
8636 } else if (!strcasecmp(v
->name
, "maxauthreq")) {
8637 user
->maxauthreq
= atoi(v
->value
);
8638 if (user
->maxauthreq
< 0)
8639 user
->maxauthreq
= 0;
8640 } else if (!strcasecmp(v
->name
, "adsi")) {
8641 user
->adsi
= ast_true(v
->value
);
8642 }/* else if (strcasecmp(v->name,"type")) */
8643 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8650 if (!user
->authmethods
) {
8651 if (!ast_strlen_zero(user
->secret
)) {
8652 user
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8653 if (!ast_strlen_zero(user
->inkeys
))
8654 user
->authmethods
|= IAX_AUTH_RSA
;
8655 } else if (!ast_strlen_zero(user
->inkeys
)) {
8656 user
->authmethods
= IAX_AUTH_RSA
;
8658 user
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8661 ast_clear_flag(user
, IAX_DELME
);
8666 free_context(oldcon
);
8670 static void delete_users(void)
8672 struct iax2_user
*user
= NULL
;
8673 struct iax2_peer
*peer
= NULL
;
8674 struct iax2_registry
*reg
, *regl
;
8676 AST_LIST_LOCK(&users
);
8677 AST_LIST_TRAVERSE(&users
, user
, entry
)
8678 ast_set_flag(user
, IAX_DELME
);
8679 AST_LIST_UNLOCK(&users
);
8681 for (reg
= registrations
;reg
;) {
8684 if (regl
->expire
> -1) {
8685 ast_sched_del(sched
, regl
->expire
);
8688 /* XXX Is this a potential lock? I don't think so, but you never know */
8689 ast_mutex_lock(&iaxsl
[regl
->callno
]);
8690 if (iaxs
[regl
->callno
]) {
8691 iaxs
[regl
->callno
]->reg
= NULL
;
8692 iax2_destroy_nolock(regl
->callno
);
8694 ast_mutex_unlock(&iaxsl
[regl
->callno
]);
8697 ast_dnsmgr_release(regl
->dnsmgr
);
8700 registrations
= NULL
;
8702 AST_LIST_LOCK(&peers
);
8703 AST_LIST_TRAVERSE(&peers
, peer
, entry
)
8704 ast_set_flag(peer
, IAX_DELME
);
8705 AST_LIST_UNLOCK(&peers
);
8708 static void destroy_user(struct iax2_user
*user
)
8710 ast_free_ha(user
->ha
);
8711 free_context(user
->contexts
);
8713 ast_variables_destroy(user
->vars
);
8716 ast_string_field_free_all(user
);
8720 static void prune_users(void)
8722 struct iax2_user
*user
= NULL
;
8724 AST_LIST_LOCK(&users
);
8725 AST_LIST_TRAVERSE_SAFE_BEGIN(&users
, user
, entry
) {
8726 if (ast_test_flag(user
, IAX_DELME
)) {
8728 AST_LIST_REMOVE_CURRENT(&users
, entry
);
8731 AST_LIST_TRAVERSE_SAFE_END
8732 AST_LIST_UNLOCK(&users
);
8736 static void destroy_peer(struct iax2_peer
*peer
)
8739 ast_free_ha(peer
->ha
);
8740 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
8741 ast_mutex_lock(&iaxsl
[x
]);
8742 if (iaxs
[x
] && (iaxs
[x
]->peerpoke
== peer
)) {
8745 ast_mutex_unlock(&iaxsl
[x
]);
8747 /* Delete it, it needs to disappear */
8748 if (peer
->expire
> -1)
8749 ast_sched_del(sched
, peer
->expire
);
8750 if (peer
->pokeexpire
> -1)
8751 ast_sched_del(sched
, peer
->pokeexpire
);
8752 if (peer
->callno
> 0)
8753 iax2_destroy(peer
->callno
);
8754 register_peer_exten(peer
, 0);
8756 ast_dnsmgr_release(peer
->dnsmgr
);
8757 ast_string_field_free_all(peer
);
8761 static void prune_peers(void){
8762 /* Prune peers who still are supposed to be deleted */
8763 struct iax2_peer
*peer
= NULL
;
8765 AST_LIST_LOCK(&peers
);
8766 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers
, peer
, entry
) {
8767 if (ast_test_flag(peer
, IAX_DELME
)) {
8769 AST_LIST_REMOVE_CURRENT(&peers
, entry
);
8772 AST_LIST_TRAVERSE_SAFE_END
8773 AST_LIST_UNLOCK(&peers
);
8776 static void set_timing(void)
8779 int bs
= trunkfreq
* 8;
8780 if (timingfd
> -1) {
8783 ioctl(timingfd
, ZT_TIMERCONFIG
, &bs
) &&
8785 ioctl(timingfd
, ZT_SET_BLOCKSIZE
, &bs
))
8786 ast_log(LOG_WARNING
, "Unable to set blocksize on timing source\n");
8792 /*! \brief Load configuration */
8793 static int set_config(char *config_file
, int reload
)
8795 struct ast_config
*cfg
, *ucfg
;
8796 int capability
=iax2_capability
;
8797 struct ast_variable
*v
;
8802 int portno
= IAX_DEFAULT_PORTNO
;
8804 struct iax2_user
*user
;
8805 struct iax2_peer
*peer
;
8806 struct ast_netsock
*ns
;
8808 static unsigned short int last_port
=0;
8811 cfg
= ast_config_load(config_file
);
8814 ast_log(LOG_ERROR
, "Unable to load config %s\n", config_file
);
8818 /* Reset global codec prefs */
8819 memset(&prefs
, 0 , sizeof(struct ast_codec_pref
));
8821 /* Reset Global Flags */
8822 memset(&globalflags
, 0, sizeof(globalflags
));
8823 ast_set_flag(&globalflags
, IAX_RTUPDATE
);
8829 min_reg_expire
= IAX_DEFAULT_REG_EXPIRE
;
8830 max_reg_expire
= IAX_DEFAULT_REG_EXPIRE
;
8834 v
= ast_variable_browse(cfg
, "general");
8836 /* Seed initial tos value */
8837 tosval
= ast_variable_retrieve(cfg
, "general", "tos");
8839 if (ast_str2tos(tosval
, &tos
))
8840 ast_log(LOG_WARNING
, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
8843 if (!strcasecmp(v
->name
, "bindport")){
8845 ast_log(LOG_NOTICE
, "Ignoring bindport on reload\n");
8847 portno
= atoi(v
->value
);
8848 } else if (!strcasecmp(v
->name
, "pingtime"))
8849 ping_time
= atoi(v
->value
);
8850 else if (!strcasecmp(v
->name
, "iaxthreadcount")) {
8852 if (atoi(v
->value
) != iaxthreadcount
)
8853 ast_log(LOG_NOTICE
, "Ignoring any changes to iaxthreadcount during reload\n");
8855 iaxthreadcount
= atoi(v
->value
);
8856 if (iaxthreadcount
< 1) {
8857 ast_log(LOG_NOTICE
, "iaxthreadcount must be at least 1.\n");
8859 } else if (iaxthreadcount
> 256) {
8860 ast_log(LOG_NOTICE
, "limiting iaxthreadcount to 256\n");
8861 iaxthreadcount
= 256;
8864 } else if (!strcasecmp(v
->name
, "iaxmaxthreadcount")) {
8866 AST_LIST_LOCK(&dynamic_list
);
8867 iaxmaxthreadcount
= atoi(v
->value
);
8868 AST_LIST_UNLOCK(&dynamic_list
);
8870 iaxmaxthreadcount
= atoi(v
->value
);
8871 if (iaxmaxthreadcount
< 0) {
8872 ast_log(LOG_NOTICE
, "iaxmaxthreadcount must be at least 0.\n");
8873 iaxmaxthreadcount
= 0;
8874 } else if (iaxmaxthreadcount
> 256) {
8875 ast_log(LOG_NOTICE
, "Limiting iaxmaxthreadcount to 256\n");
8876 iaxmaxthreadcount
= 256;
8879 } else if (!strcasecmp(v
->name
, "nochecksums")) {
8881 if (ast_true(v
->value
))
8886 if (ast_true(v
->value
))
8887 ast_log(LOG_WARNING
, "Disabling RTP checksums is not supported on this operating system!\n");
8890 else if (!strcasecmp(v
->name
, "maxjitterbuffer"))
8891 maxjitterbuffer
= atoi(v
->value
);
8892 else if (!strcasecmp(v
->name
, "resyncthreshold"))
8893 resyncthreshold
= atoi(v
->value
);
8894 else if (!strcasecmp(v
->name
, "maxjitterinterps"))
8895 maxjitterinterps
= atoi(v
->value
);
8896 else if (!strcasecmp(v
->name
, "lagrqtime"))
8897 lagrq_time
= atoi(v
->value
);
8898 else if (!strcasecmp(v
->name
, "maxregexpire"))
8899 max_reg_expire
= atoi(v
->value
);
8900 else if (!strcasecmp(v
->name
, "minregexpire"))
8901 min_reg_expire
= atoi(v
->value
);
8902 else if (!strcasecmp(v
->name
, "bindaddr")) {
8904 ast_log(LOG_NOTICE
, "Ignoring bindaddr on reload\n");
8906 if (!(ns
= ast_netsock_bind(netsock
, io
, v
->value
, portno
, tos
, socket_read
, NULL
))) {
8907 ast_log(LOG_WARNING
, "Unable apply binding to '%s' at line %d\n", v
->value
, v
->lineno
);
8909 if (option_verbose
> 1) {
8910 if (strchr(v
->value
, ':'))
8911 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to '%s'\n", v
->value
);
8913 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to '%s:%d'\n", v
->value
, portno
);
8915 if (defaultsockfd
< 0)
8916 defaultsockfd
= ast_netsock_sockfd(ns
);
8917 ast_netsock_unref(ns
);
8920 } else if (!strcasecmp(v
->name
, "authdebug"))
8921 authdebug
= ast_true(v
->value
);
8922 else if (!strcasecmp(v
->name
, "encryption"))
8923 iax2_encryption
= get_encrypt_methods(v
->value
);
8924 else if (!strcasecmp(v
->name
, "notransfer")) {
8925 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8926 ast_clear_flag((&globalflags
), IAX_TRANSFERMEDIA
);
8927 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_NOTRANSFER
);
8928 } else if (!strcasecmp(v
->name
, "transfer")) {
8929 if (!strcasecmp(v
->value
, "mediaonly")) {
8930 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8931 } else if (ast_true(v
->value
)) {
8932 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8934 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8935 } else if (!strcasecmp(v
->name
, "codecpriority")) {
8936 if(!strcasecmp(v
->value
, "caller"))
8937 ast_set_flag((&globalflags
), IAX_CODEC_USER_FIRST
);
8938 else if(!strcasecmp(v
->value
, "disabled"))
8939 ast_set_flag((&globalflags
), IAX_CODEC_NOPREFS
);
8940 else if(!strcasecmp(v
->value
, "reqonly")) {
8941 ast_set_flag((&globalflags
), IAX_CODEC_NOCAP
);
8942 ast_set_flag((&globalflags
), IAX_CODEC_NOPREFS
);
8944 } else if (!strcasecmp(v
->name
, "jitterbuffer"))
8945 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_USEJITTERBUF
);
8946 else if (!strcasecmp(v
->name
, "forcejitterbuffer"))
8947 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8948 else if (!strcasecmp(v
->name
, "delayreject"))
8949 delayreject
= ast_true(v
->value
);
8950 else if (!strcasecmp(v
->name
, "rtcachefriends"))
8951 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTCACHEFRIENDS
);
8952 else if (!strcasecmp(v
->name
, "rtignoreregexpire"))
8953 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTIGNOREREGEXPIRE
);
8954 else if (!strcasecmp(v
->name
, "rtupdate"))
8955 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTUPDATE
);
8956 else if (!strcasecmp(v
->name
, "trunktimestamps"))
8957 ast_set2_flag(&globalflags
, ast_true(v
->value
), IAX_TRUNKTIMESTAMPS
);
8958 else if (!strcasecmp(v
->name
, "rtautoclear")) {
8959 int i
= atoi(v
->value
);
8961 global_rtautoclear
= i
;
8964 ast_set2_flag((&globalflags
), i
|| ast_true(v
->value
), IAX_RTAUTOCLEAR
);
8965 } else if (!strcasecmp(v
->name
, "trunkfreq")) {
8966 trunkfreq
= atoi(v
->value
);
8969 } else if (!strcasecmp(v
->name
, "autokill")) {
8970 if (sscanf(v
->value
, "%d", &x
) == 1) {
8974 ast_log(LOG_NOTICE
, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v
->lineno
);
8975 } else if (ast_true(v
->value
)) {
8976 autokill
= DEFAULT_MAXMS
;
8980 } else if (!strcasecmp(v
->name
, "bandwidth")) {
8981 if (!strcasecmp(v
->value
, "low")) {
8982 capability
= IAX_CAPABILITY_LOWBANDWIDTH
;
8983 } else if (!strcasecmp(v
->value
, "medium")) {
8984 capability
= IAX_CAPABILITY_MEDBANDWIDTH
;
8985 } else if (!strcasecmp(v
->value
, "high")) {
8986 capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
8988 ast_log(LOG_WARNING
, "bandwidth must be either low, medium, or high\n");
8989 } else if (!strcasecmp(v
->name
, "allow")) {
8990 ast_parse_allow_disallow(&prefs
, &capability
, v
->value
, 1);
8991 } else if (!strcasecmp(v
->name
, "disallow")) {
8992 ast_parse_allow_disallow(&prefs
, &capability
, v
->value
, 0);
8993 } else if (!strcasecmp(v
->name
, "register")) {
8994 iax2_register(v
->value
, v
->lineno
);
8995 } else if (!strcasecmp(v
->name
, "iaxcompat")) {
8996 iaxcompat
= ast_true(v
->value
);
8997 } else if (!strcasecmp(v
->name
, "regcontext")) {
8998 ast_copy_string(regcontext
, v
->value
, sizeof(regcontext
));
8999 /* Create context if it doesn't exist already */
9000 if (!ast_context_find(regcontext
))
9001 ast_context_create(NULL
, regcontext
, "IAX2");
9002 } else if (!strcasecmp(v
->name
, "tos")) {
9003 if (ast_str2tos(v
->value
, &tos
))
9004 ast_log(LOG_WARNING
, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v
->lineno
);
9005 } else if (!strcasecmp(v
->name
, "accountcode")) {
9006 ast_copy_string(accountcode
, v
->value
, sizeof(accountcode
));
9007 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
9008 ast_copy_string(mohinterpret
, v
->value
, sizeof(user
->mohinterpret
));
9009 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
9010 ast_copy_string(mohsuggest
, v
->value
, sizeof(user
->mohsuggest
));
9011 } else if (!strcasecmp(v
->name
, "amaflags")) {
9012 format
= ast_cdr_amaflags2int(v
->value
);
9014 ast_log(LOG_WARNING
, "Invalid AMA Flags: %s at line %d\n", v
->value
, v
->lineno
);
9018 } else if (!strcasecmp(v
->name
, "language")) {
9019 ast_copy_string(language
, v
->value
, sizeof(language
));
9020 } else if (!strcasecmp(v
->name
, "maxauthreq")) {
9021 maxauthreq
= atoi(v
->value
);
9024 } else if (!strcasecmp(v
->name
, "adsi")) {
9025 adsi
= ast_true(v
->value
);
9026 } /*else if (strcasecmp(v->name,"type")) */
9027 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
9031 if (defaultsockfd
< 0) {
9032 if (!(ns
= ast_netsock_bind(netsock
, io
, "0.0.0.0", portno
, tos
, socket_read
, NULL
))) {
9033 ast_log(LOG_ERROR
, "Unable to create network socket: %s\n", strerror(errno
));
9035 if (option_verbose
> 1)
9036 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to default address 0.0.0.0:%d\n", portno
);
9037 defaultsockfd
= ast_netsock_sockfd(ns
);
9038 ast_netsock_unref(ns
);
9042 if (min_reg_expire
> max_reg_expire
) {
9043 ast_log(LOG_WARNING
, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
9044 min_reg_expire
, max_reg_expire
, max_reg_expire
);
9045 min_reg_expire
= max_reg_expire
;
9047 iax2_capability
= capability
;
9049 ucfg
= ast_config_load("users.conf");
9051 struct ast_variable
*gen
;
9054 char *hasiax
, *registeriax
;
9056 genhasiax
= ast_true(ast_variable_retrieve(ucfg
, "general", "hasiax"));
9057 genregisteriax
= ast_true(ast_variable_retrieve(ucfg
, "general", "registeriax"));
9058 gen
= ast_variable_browse(ucfg
, "general");
9059 cat
= ast_category_browse(ucfg
, NULL
);
9061 if (strcasecmp(cat
, "general")) {
9062 hasiax
= ast_variable_retrieve(ucfg
, cat
, "hasiax");
9063 registeriax
= ast_variable_retrieve(ucfg
, cat
, "registeriax");
9064 if (ast_true(hasiax
) || (!hasiax
&& genhasiax
)) {
9065 /* Start with general parameters, then specific parameters, user and peer */
9066 user
= build_user(cat
, gen
, ast_variable_browse(ucfg
, cat
), 0);
9068 AST_LIST_LOCK(&users
);
9069 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
9070 AST_LIST_UNLOCK(&users
);
9072 peer
= build_peer(cat
, gen
, ast_variable_browse(ucfg
, cat
), 0);
9074 AST_LIST_LOCK(&peers
);
9075 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
9076 AST_LIST_UNLOCK(&peers
);
9077 if (ast_test_flag(peer
, IAX_DYNAMIC
))
9078 reg_source_db(peer
);
9081 if (ast_true(registeriax
) || (!registeriax
&& genregisteriax
)) {
9083 char *host
= ast_variable_retrieve(ucfg
, cat
, "host");
9084 char *username
= ast_variable_retrieve(ucfg
, cat
, "username");
9085 char *secret
= ast_variable_retrieve(ucfg
, cat
, "secret");
9087 host
= ast_variable_retrieve(ucfg
, "general", "host");
9089 username
= ast_variable_retrieve(ucfg
, "general", "username");
9091 secret
= ast_variable_retrieve(ucfg
, "general", "secret");
9092 if (!ast_strlen_zero(username
) && !ast_strlen_zero(host
)) {
9093 if (!ast_strlen_zero(secret
))
9094 snprintf(tmp
, sizeof(tmp
), "%s:%s@%s", username
, secret
, host
);
9096 snprintf(tmp
, sizeof(tmp
), "%s@%s", username
, host
);
9097 iax2_register(tmp
, 0);
9101 cat
= ast_category_browse(ucfg
, cat
);
9103 ast_config_destroy(ucfg
);
9106 cat
= ast_category_browse(cfg
, NULL
);
9108 if (strcasecmp(cat
, "general")) {
9109 utype
= ast_variable_retrieve(cfg
, cat
, "type");
9111 if (!strcasecmp(utype
, "user") || !strcasecmp(utype
, "friend")) {
9112 user
= build_user(cat
, ast_variable_browse(cfg
, cat
), NULL
, 0);
9114 AST_LIST_LOCK(&users
);
9115 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
9116 AST_LIST_UNLOCK(&users
);
9119 if (!strcasecmp(utype
, "peer") || !strcasecmp(utype
, "friend")) {
9120 peer
= build_peer(cat
, ast_variable_browse(cfg
, cat
), NULL
, 0);
9122 AST_LIST_LOCK(&peers
);
9123 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
9124 AST_LIST_UNLOCK(&peers
);
9125 if (ast_test_flag(peer
, IAX_DYNAMIC
))
9126 reg_source_db(peer
);
9128 } else if (strcasecmp(utype
, "user")) {
9129 ast_log(LOG_WARNING
, "Unknown type '%s' for '%s' in %s\n", utype
, cat
, config_file
);
9132 ast_log(LOG_WARNING
, "Section '%s' lacks type\n", cat
);
9134 cat
= ast_category_browse(cfg
, cat
);
9136 ast_config_destroy(cfg
);
9141 static int reload_config(void)
9143 char *config
= "iax.conf";
9144 struct iax2_registry
*reg
;
9145 struct iax2_peer
*peer
= NULL
;
9147 strcpy(accountcode
, "");
9148 strcpy(language
, "");
9149 strcpy(mohinterpret
, "default");
9150 strcpy(mohsuggest
, "");
9153 ast_clear_flag((&globalflags
), IAX_NOTRANSFER
);
9154 ast_clear_flag((&globalflags
), IAX_TRANSFERMEDIA
);
9155 ast_clear_flag((&globalflags
), IAX_USEJITTERBUF
);
9156 ast_clear_flag((&globalflags
), IAX_FORCEJITTERBUF
);
9158 set_config(config
,1);
9161 for (reg
= registrations
; reg
; reg
= reg
->next
)
9162 iax2_do_register(reg
);
9163 /* Qualify hosts, too */
9164 AST_LIST_LOCK(&peers
);
9165 AST_LIST_TRAVERSE(&peers
, peer
, entry
)
9166 iax2_poke_peer(peer
, 0);
9167 AST_LIST_UNLOCK(&peers
);
9169 iax_provision_reload();
9174 static int iax2_reload(int fd
, int argc
, char *argv
[])
9176 return reload_config();
9179 static int reload(void)
9181 return reload_config();
9184 static int cache_get_callno_locked(const char *data
)
9186 struct sockaddr_in sin
;
9189 struct iax_ie_data ied
;
9190 struct create_addr_info cai
;
9191 struct parsed_dial_string pds
;
9194 for (x
=0; x
<IAX_MAX_CALLS
; x
++) {
9195 /* Look for an *exact match* call. Once a call is negotiated, it can only
9196 look up entries for a single context */
9197 if (!ast_mutex_trylock(&iaxsl
[x
])) {
9198 if (iaxs
[x
] && !strcasecmp(data
, iaxs
[x
]->dproot
))
9200 ast_mutex_unlock(&iaxsl
[x
]);
9204 /* No match found, we need to create a new one */
9206 memset(&cai
, 0, sizeof(cai
));
9207 memset(&ied
, 0, sizeof(ied
));
9208 memset(&pds
, 0, sizeof(pds
));
9210 tmpstr
= ast_strdupa(data
);
9211 parse_dial_string(tmpstr
, &pds
);
9213 /* Populate our address from the given */
9214 if (create_addr(pds
.peer
, &sin
, &cai
))
9217 ast_log(LOG_DEBUG
, "peer: %s, username: %s, password: %s, context: %s\n",
9218 pds
.peer
, pds
.username
, pds
.password
, pds
.context
);
9220 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
9222 ast_log(LOG_WARNING
, "Unable to create call\n");
9226 ast_mutex_lock(&iaxsl
[callno
]);
9227 ast_string_field_set(iaxs
[callno
], dproot
, data
);
9228 iaxs
[callno
]->capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
9230 iax_ie_append_short(&ied
, IAX_IE_VERSION
, IAX_PROTO_VERSION
);
9231 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, "TBD");
9232 /* the string format is slightly different from a standard dial string,
9233 because the context appears in the 'exten' position
9236 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, pds
.exten
);
9238 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, pds
.username
);
9239 iax_ie_append_int(&ied
, IAX_IE_FORMAT
, IAX_CAPABILITY_FULLBANDWIDTH
);
9240 iax_ie_append_int(&ied
, IAX_IE_CAPABILITY
, IAX_CAPABILITY_FULLBANDWIDTH
);
9241 /* Keep password handy */
9243 ast_string_field_set(iaxs
[callno
], secret
, pds
.password
);
9245 ast_string_field_set(iaxs
[callno
], outkey
, pds
.key
);
9246 /* Start the call going */
9247 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_NEW
, 0, ied
.buf
, ied
.pos
, -1);
9252 static struct iax2_dpcache
*find_cache(struct ast_channel
*chan
, const char *data
, const char *context
, const char *exten
, int priority
)
9254 struct iax2_dpcache
*dp
, *prev
= NULL
, *next
;
9263 struct ast_channel
*c
;
9264 struct ast_frame
*f
;
9265 gettimeofday(&tv
, NULL
);
9269 /* Expire old caches */
9270 if (ast_tvcmp(tv
, dp
->expiry
) > 0) {
9271 /* It's expired, let it disappear */
9273 prev
->next
= dp
->next
;
9276 if (!dp
->peer
&& !(dp
->flags
& CACHE_FLAG_PENDING
) && !dp
->callno
) {
9277 /* Free memory and go again */
9280 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
);
9285 /* We found an entry that matches us! */
9286 if (!strcmp(dp
->peercontext
, data
) && !strcmp(dp
->exten
, exten
))
9292 /* No matching entry. Create a new one. */
9293 /* First, can we make a callno? */
9294 callno
= cache_get_callno_locked(data
);
9296 ast_log(LOG_WARNING
, "Unable to generate call for '%s'\n", data
);
9299 if (!(dp
= ast_calloc(1, sizeof(*dp
)))) {
9300 ast_mutex_unlock(&iaxsl
[callno
]);
9303 ast_copy_string(dp
->peercontext
, data
, sizeof(dp
->peercontext
));
9304 ast_copy_string(dp
->exten
, exten
, sizeof(dp
->exten
));
9305 gettimeofday(&dp
->expiry
, NULL
);
9306 dp
->orig
= dp
->expiry
;
9307 /* Expires in 30 mins by default */
9308 dp
->expiry
.tv_sec
+= iaxdefaultdpcache
;
9310 dp
->flags
= CACHE_FLAG_PENDING
;
9311 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
9312 dp
->waiters
[x
] = -1;
9314 dp
->peer
= iaxs
[callno
]->dpentries
;
9315 iaxs
[callno
]->dpentries
= dp
;
9316 /* Send the request if we're already up */
9317 if (ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_STARTED
))
9318 iax2_dprequest(dp
, callno
);
9319 ast_mutex_unlock(&iaxsl
[callno
]);
9321 /* By here we must have a dp */
9322 if (dp
->flags
& CACHE_FLAG_PENDING
) {
9323 /* Okay, here it starts to get nasty. We need a pipe now to wait
9324 for a reply to come back so long as it's pending */
9325 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++) {
9326 /* Find an empty slot */
9327 if (dp
->waiters
[x
] < 0)
9330 if (x
>= sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0])) {
9331 ast_log(LOG_WARNING
, "No more waiter positions available\n");
9335 ast_log(LOG_WARNING
, "Unable to create pipe for comm\n");
9338 dp
->waiters
[x
] = com
[1];
9339 /* Okay, now we wait */
9340 timeout
= iaxdefaulttimeout
* 1000;
9341 /* Temporarily unlock */
9342 ast_mutex_unlock(&dpcache_lock
);
9343 /* Defer any dtmf */
9345 old
= ast_channel_defer_dtmf(chan
);
9348 c
= ast_waitfor_nandfds(&chan
, chan
? 1 : 0, &com
[0], 1, NULL
, &outfd
, &timeout
);
9357 /* Got hung up on, abort! */
9364 ast_log(LOG_WARNING
, "Timeout waiting for %s exten %s\n", data
, exten
);
9366 ast_mutex_lock(&dpcache_lock
);
9367 dp
->waiters
[x
] = -1;
9371 /* Don't interpret anything, just abort. Not sure what th epoint
9372 of undeferring dtmf on a hung up channel is but hey whatever */
9374 ast_channel_undefer_dtmf(chan
);
9377 if (!(dp
->flags
& CACHE_FLAG_TIMEOUT
)) {
9378 /* Now to do non-independent analysis the results of our wait */
9379 if (dp
->flags
& CACHE_FLAG_PENDING
) {
9380 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
9381 pending. Don't let it take as long to timeout. */
9382 dp
->flags
&= ~CACHE_FLAG_PENDING
;
9383 dp
->flags
|= CACHE_FLAG_TIMEOUT
;
9384 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
9385 systems without leaving it unavailable once the server comes back online */
9386 dp
->expiry
.tv_sec
= dp
->orig
.tv_sec
+ 60;
9387 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
9388 if (dp
->waiters
[x
] > -1)
9389 write(dp
->waiters
[x
], "asdf", 4);
9392 /* Our caller will obtain the rest */
9394 ast_channel_undefer_dtmf(chan
);
9399 /*! \brief Part of the IAX2 switch interface */
9400 static int iax2_exists(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9402 struct iax2_dpcache
*dp
;
9405 ast_log(LOG_NOTICE
, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9407 if ((priority
!= 1) && (priority
!= 2))
9409 ast_mutex_lock(&dpcache_lock
);
9410 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9412 if (dp
->flags
& CACHE_FLAG_EXISTS
)
9415 ast_mutex_unlock(&dpcache_lock
);
9417 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9422 /*! \brief part of the IAX2 dial plan switch interface */
9423 static int iax2_canmatch(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9426 struct iax2_dpcache
*dp
;
9428 ast_log(LOG_NOTICE
, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9430 if ((priority
!= 1) && (priority
!= 2))
9432 ast_mutex_lock(&dpcache_lock
);
9433 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9435 if (dp
->flags
& CACHE_FLAG_CANEXIST
)
9438 ast_mutex_unlock(&dpcache_lock
);
9440 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9445 /*! \brief Part of the IAX2 Switch interface */
9446 static int iax2_matchmore(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9449 struct iax2_dpcache
*dp
;
9451 ast_log(LOG_NOTICE
, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9453 if ((priority
!= 1) && (priority
!= 2))
9455 ast_mutex_lock(&dpcache_lock
);
9456 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9458 if (dp
->flags
& CACHE_FLAG_MATCHMORE
)
9461 ast_mutex_unlock(&dpcache_lock
);
9463 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9468 /*! \brief Execute IAX2 dialplan switch */
9469 static int iax2_exec(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9474 struct iax2_dpcache
*dp
;
9475 struct ast_app
*dial
;
9477 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
);
9479 if (priority
== 2) {
9480 /* Indicate status, can be overridden in dialplan */
9481 const char *dialstatus
= pbx_builtin_getvar_helper(chan
, "DIALSTATUS");
9483 dial
= pbx_findapp(dialstatus
);
9485 pbx_exec(chan
, dial
, "");
9488 } else if (priority
!= 1)
9490 ast_mutex_lock(&dpcache_lock
);
9491 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9493 if (dp
->flags
& CACHE_FLAG_EXISTS
) {
9494 ast_copy_string(odata
, data
, sizeof(odata
));
9495 ncontext
= strchr(odata
, '/');
9499 snprintf(req
, sizeof(req
), "IAX2/%s/%s@%s", odata
, exten
, ncontext
);
9501 snprintf(req
, sizeof(req
), "IAX2/%s/%s", odata
, exten
);
9503 if (option_verbose
> 2)
9504 ast_verbose(VERBOSE_PREFIX_3
"Executing Dial('%s')\n", req
);
9506 ast_mutex_unlock(&dpcache_lock
);
9507 ast_log(LOG_WARNING
, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten
, context
, data
);
9511 ast_mutex_unlock(&dpcache_lock
);
9512 dial
= pbx_findapp("Dial");
9514 return pbx_exec(chan
, dial
, req
);
9516 ast_log(LOG_WARNING
, "No dial application registered\n");
9521 static int function_iaxpeer(struct ast_channel
*chan
, char *cmd
, char *data
, char *buf
, size_t len
)
9523 struct iax2_peer
*peer
;
9524 char *peername
, *colname
;
9526 if (!(peername
= ast_strdupa(data
)))
9529 /* if our channel, return the IP address of the endpoint of current channel */
9530 if (!strcmp(peername
,"CURRENTCHANNEL")) {
9531 unsigned short callno
= PTR_TO_CALLNO(chan
->tech_pvt
);
9532 ast_copy_string(buf
, iaxs
[callno
]->addr
.sin_addr
.s_addr
? ast_inet_ntoa(iaxs
[callno
]->addr
.sin_addr
) : "", len
);
9536 if ((colname
= strchr(peername
, ':'))) /*! \todo : will be removed after the 1.4 relese */
9538 else if ((colname
= strchr(peername
, '|')))
9543 if (!(peer
= find_peer(peername
, 1)))
9546 if (!strcasecmp(colname
, "ip")) {
9547 ast_copy_string(buf
, peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "", len
);
9548 } else if (!strcasecmp(colname
, "status")) {
9549 peer_status(peer
, buf
, len
);
9550 } else if (!strcasecmp(colname
, "mailbox")) {
9551 ast_copy_string(buf
, peer
->mailbox
, len
);
9552 } else if (!strcasecmp(colname
, "context")) {
9553 ast_copy_string(buf
, peer
->context
, len
);
9554 } else if (!strcasecmp(colname
, "expire")) {
9555 snprintf(buf
, len
, "%d", peer
->expire
);
9556 } else if (!strcasecmp(colname
, "dynamic")) {
9557 ast_copy_string(buf
, (ast_test_flag(peer
, IAX_DYNAMIC
) ? "yes" : "no"), len
);
9558 } else if (!strcasecmp(colname
, "callerid_name")) {
9559 ast_copy_string(buf
, peer
->cid_name
, len
);
9560 } else if (!strcasecmp(colname
, "callerid_num")) {
9561 ast_copy_string(buf
, peer
->cid_num
, len
);
9562 } else if (!strcasecmp(colname
, "codecs")) {
9563 ast_getformatname_multiple(buf
, len
-1, peer
->capability
);
9564 } else if (!strncasecmp(colname
, "codec[", 6)) {
9565 char *codecnum
, *ptr
;
9566 int index
= 0, codec
= 0;
9568 codecnum
= strchr(colname
, '[');
9571 if ((ptr
= strchr(codecnum
, ']'))) {
9574 index
= atoi(codecnum
);
9575 if((codec
= ast_codec_pref_index(&peer
->prefs
, index
))) {
9576 ast_copy_string(buf
, ast_getformatname(codec
), len
);
9583 struct ast_custom_function iaxpeer_function
= {
9585 .synopsis
= "Gets IAX peer information",
9586 .syntax
= "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
9587 .read
= function_iaxpeer
,
9588 .desc
= "If peername specified, valid items are:\n"
9589 "- ip (default) The IP address.\n"
9590 "- status The peer's status (if qualify=yes)\n"
9591 "- mailbox The configured mailbox.\n"
9592 "- context The configured context.\n"
9593 "- expire The epoch time of the next expire.\n"
9594 "- dynamic Is it dynamic? (yes/no).\n"
9595 "- callerid_name The configured Caller ID name.\n"
9596 "- callerid_num The configured Caller ID number.\n"
9597 "- codecs The configured codecs.\n"
9598 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
9600 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
9605 /*! \brief Part of the device state notification system ---*/
9606 static int iax2_devicestate(void *data
)
9608 struct parsed_dial_string pds
;
9609 char *tmp
= ast_strdupa(data
);
9610 struct iax2_peer
*p
;
9611 int res
= AST_DEVICE_INVALID
;
9613 memset(&pds
, 0, sizeof(pds
));
9614 parse_dial_string(tmp
, &pds
);
9615 if (ast_strlen_zero(pds
.peer
))
9618 if (option_debug
> 2)
9619 ast_log(LOG_DEBUG
, "Checking device state for device %s\n", pds
.peer
);
9621 /* SLD: FIXME: second call to find_peer during registration */
9622 if (!(p
= find_peer(pds
.peer
, 1)))
9625 res
= AST_DEVICE_UNAVAILABLE
;
9626 if (option_debug
> 2)
9627 ast_log(LOG_DEBUG
, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
9628 pds
.peer
, p
->addr
.sin_addr
.s_addr
, p
->defaddr
.sin_addr
.s_addr
, p
->maxms
, p
->lastms
);
9630 if ((p
->addr
.sin_addr
.s_addr
|| p
->defaddr
.sin_addr
.s_addr
) &&
9631 (!p
->maxms
|| ((p
->lastms
> -1) && (p
->historicms
<= p
->maxms
)))) {
9632 /* Peer is registered, or have default IP address
9633 and a valid registration */
9634 if (p
->historicms
== 0 || p
->historicms
<= p
->maxms
)
9635 /* let the core figure out whether it is in use or not */
9636 res
= AST_DEVICE_UNKNOWN
;
9639 if (ast_test_flag(p
, IAX_TEMPONLY
))
9645 static struct ast_switch iax2_switch
=
9648 description
: "IAX Remote Dialplan Switch",
9649 exists
: iax2_exists
,
9650 canmatch
: iax2_canmatch
,
9652 matchmore
: iax2_matchmore
,
9655 static char show_stats_usage
[] =
9656 "Usage: iax2 list stats\n"
9657 " Display statistics on IAX channel driver.\n";
9659 static char show_cache_usage
[] =
9660 "Usage: iax2 list cache\n"
9661 " Display currently cached IAX Dialplan results.\n";
9663 static char show_peer_usage
[] =
9664 "Usage: iax2 show peer <name>\n"
9665 " Display details on specific IAX peer\n";
9667 static char prune_realtime_usage
[] =
9668 "Usage: iax2 prune realtime [<peername>|all]\n"
9669 " Prunes object(s) from the cache\n";
9671 static char iax2_reload_usage
[] =
9672 "Usage: iax2 reload\n"
9673 " Reloads IAX configuration from iax.conf\n";
9675 static char show_prov_usage
[] =
9676 "Usage: iax2 provision <host> <template> [forced]\n"
9677 " Provisions the given peer or IP address using a template\n"
9678 " matching either 'template' or '*' if the template is not\n"
9679 " found. If 'forced' is specified, even empty provisioning\n"
9680 " fields will be provisioned as empty fields.\n";
9682 static char show_users_usage
[] =
9683 "Usage: iax2 list users [like <pattern>]\n"
9684 " Lists all known IAX2 users.\n"
9685 " Optional regular expression pattern is used to filter the user list.\n";
9687 static char show_channels_usage
[] =
9688 "Usage: iax2 list channels\n"
9689 " Lists all currently active IAX channels.\n";
9691 static char show_netstats_usage
[] =
9692 "Usage: iax2 list netstats\n"
9693 " Lists network status for all currently active IAX channels.\n";
9695 static char show_threads_usage
[] =
9696 "Usage: iax2 list threads\n"
9697 " Lists status of IAX helper threads\n";
9699 static char show_peers_usage
[] =
9700 "Usage: iax2 list peers [registered] [like <pattern>]\n"
9701 " Lists all known IAX2 peers.\n"
9702 " Optional 'registered' argument lists only peers with known addresses.\n"
9703 " Optional regular expression pattern is used to filter the peer list.\n";
9705 static char show_firmware_usage
[] =
9706 "Usage: iax2 list firmware\n"
9707 " Lists all known IAX firmware images.\n";
9709 static char show_reg_usage
[] =
9710 "Usage: iax2 list registry\n"
9711 " Lists all registration requests and status.\n";
9713 static char debug_usage
[] =
9714 "Usage: iax2 debug\n"
9715 " Enables dumping of IAX packets for debugging purposes\n";
9717 static char no_debug_usage
[] =
9718 "Usage: iax2 nodebug\n"
9719 " Disables dumping of IAX packets for debugging purposes\n";
9721 static char debug_trunk_usage
[] =
9722 "Usage: iax2 debug trunk\n"
9723 " Requests current status of IAX trunking\n";
9725 static char no_debug_trunk_usage
[] =
9726 "Usage: iax2 nodebug trunk\n"
9727 " Requests current status of IAX trunking\n";
9729 static char debug_jb_usage
[] =
9730 "Usage: iax2 debug jb\n"
9731 " Enables jitterbuffer debugging information\n";
9733 static char no_debug_jb_usage
[] =
9734 "Usage: iax2 nodebug jb\n"
9735 " Disables jitterbuffer debugging information\n";
9737 static char iax2_test_losspct_usage
[] =
9738 "Usage: iax2 test losspct <percentage>\n"
9739 " For testing, throws away <percentage> percent of incoming packets\n";
9742 static char iax2_test_late_usage
[] =
9743 "Usage: iax2 test late <ms>\n"
9744 " For testing, count the next frame as <ms> ms late\n";
9746 static char iax2_test_resync_usage
[] =
9747 "Usage: iax2 test resync <ms>\n"
9748 " For testing, adjust all future frames by <ms> ms\n";
9750 static char iax2_test_jitter_usage
[] =
9751 "Usage: iax2 test jitter <ms> <pct>\n"
9752 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
9753 #endif /* IAXTESTS */
9755 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated
= {
9756 { "iax2", "trunk", "debug", NULL
},
9757 iax2_do_trunk_debug
, NULL
,
9760 static struct ast_cli_entry cli_iax2_jb_debug_deprecated
= {
9761 { "iax2", "jb", "debug", NULL
},
9762 iax2_do_jb_debug
, NULL
,
9765 static struct ast_cli_entry cli_iax2_no_debug_deprecated
= {
9766 { "iax2", "no", "debug", NULL
},
9767 iax2_no_debug_deprecated
, NULL
,
9770 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated
= {
9771 { "iax2", "no", "trunk", "debug", NULL
},
9772 iax2_no_trunk_debug_deprecated
, NULL
,
9775 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated
= {
9776 { "iax2", "no", "jb", "debug", NULL
},
9777 iax2_no_jb_debug_deprecated
, NULL
,
9780 static struct ast_cli_entry cli_iax2_show_cache_deprecated
= {
9781 { "iax2", "show", "cache", NULL
},
9782 iax2_show_cache
, NULL
,
9785 static struct ast_cli_entry cli_iax2_show_peers_deprecated
= {
9786 { "iax2", "show", "peers", NULL
},
9787 iax2_show_peers
, NULL
,
9790 static struct ast_cli_entry cli_iax2_show_stats_deprecated
= {
9791 { "iax2", "show", "stats", NULL
},
9792 iax2_show_stats
, NULL
};
9794 static struct ast_cli_entry cli_iax2_show_firmware_deprecated
= {
9795 { "iax2", "show", "firmware", NULL
},
9796 iax2_show_firmware
, NULL
,
9799 static struct ast_cli_entry cli_iax2_show_channels_deprecated
= {
9800 { "iax2", "show", "channels", NULL
},
9801 iax2_show_channels
, NULL
,
9804 static struct ast_cli_entry cli_iax2_show_netstats_deprecated
= {
9805 { "iax2", "show", "netstats", NULL
},
9806 iax2_show_netstats
, NULL
,
9809 static struct ast_cli_entry cli_iax2_show_users_deprecated
= {
9810 { "iax2", "show", "users", NULL
},
9811 iax2_show_users
, NULL
,
9814 static struct ast_cli_entry cli_iax2_show_threads_deprecated
= {
9815 { "iax2", "show", "threads", NULL
},
9816 iax2_show_threads
, NULL
,
9819 static struct ast_cli_entry cli_iax2_show_registry_deprecated
= {
9820 { "iax2", "show", "registry", NULL
},
9821 iax2_show_registry
, "Show IAX registration status",
9824 static struct ast_cli_entry cli_iax2
[] = {
9825 { { "iax2", "list", "cache", NULL
},
9826 iax2_show_cache
, "Display IAX cached dialplan",
9827 show_cache_usage
, NULL
, &cli_iax2_show_cache_deprecated
},
9829 { { "iax2", "list", "channels", NULL
},
9830 iax2_show_channels
, "List active IAX channels",
9831 show_channels_usage
, NULL
, &cli_iax2_show_channels_deprecated
},
9833 { { "iax2", "list", "firmware", NULL
},
9834 iax2_show_firmware
, "List available IAX firmwares",
9835 show_firmware_usage
, NULL
, &cli_iax2_show_firmware_deprecated
},
9837 { { "iax2", "list", "netstats", NULL
},
9838 iax2_show_netstats
, "List active IAX channel netstats",
9839 show_netstats_usage
, NULL
, &cli_iax2_show_netstats_deprecated
},
9841 { { "iax2", "list", "peers", NULL
},
9842 iax2_show_peers
, "List defined IAX peers",
9843 show_peers_usage
, NULL
, &cli_iax2_show_peers_deprecated
},
9845 { { "iax2", "list", "registry", NULL
},
9846 iax2_show_registry
, "Display IAX registration status",
9847 show_reg_usage
, NULL
, &cli_iax2_show_registry_deprecated
},
9849 { { "iax2", "list", "stats", NULL
},
9850 iax2_show_stats
, "Display IAX statistics",
9851 show_stats_usage
, NULL
, &cli_iax2_show_stats_deprecated
},
9853 { { "iax2", "list", "threads", NULL
},
9854 iax2_show_threads
, "Display IAX helper thread info",
9855 show_threads_usage
, NULL
, &cli_iax2_show_threads_deprecated
},
9857 { { "iax2", "list", "users", NULL
},
9858 iax2_show_users
, "List defined IAX users",
9859 show_users_usage
, NULL
, &cli_iax2_show_users_deprecated
},
9861 { { "iax2", "prune", "realtime", NULL
},
9862 iax2_prune_realtime
, "Prune a cached realtime lookup",
9863 prune_realtime_usage
, complete_iax2_show_peer
},
9865 { { "iax2", "reload", NULL
},
9866 iax2_reload
, "Reload IAX configuration",
9867 iax2_reload_usage
},
9869 { { "iax2", "show", "peer", NULL
},
9870 iax2_show_peer
, "Show details on specific IAX peer",
9871 show_peer_usage
, complete_iax2_show_peer
},
9873 { { "iax2", "debug", NULL
},
9874 iax2_do_debug
, "Enable IAX debugging",
9877 { { "iax2", "debug", "trunk", NULL
},
9878 iax2_do_trunk_debug
, "Enable IAX trunk debugging",
9879 debug_trunk_usage
, NULL
, &cli_iax2_trunk_debug_deprecated
},
9881 { { "iax2", "debug", "jb", NULL
},
9882 iax2_do_jb_debug
, "Enable IAX jitterbuffer debugging",
9883 debug_jb_usage
, NULL
, &cli_iax2_jb_debug_deprecated
},
9885 { { "iax2", "nodebug", NULL
},
9886 iax2_no_debug
, "Disable IAX debugging",
9887 no_debug_usage
, NULL
, &cli_iax2_no_debug_deprecated
},
9889 { { "iax2", "nodebug", "trunk", NULL
},
9890 iax2_no_trunk_debug
, "Disable IAX trunk debugging",
9891 no_debug_trunk_usage
, NULL
, &cli_iax2_no_trunk_debug_deprecated
},
9893 { { "iax2", "nodebug", "jb", NULL
},
9894 iax2_no_jb_debug
, "Disable IAX jitterbuffer debugging",
9895 no_debug_jb_usage
, NULL
, &cli_iax2_no_jb_debug_deprecated
},
9897 { { "iax2", "test", "losspct", NULL
},
9898 iax2_test_losspct
, "Set IAX2 incoming frame loss percentage",
9899 iax2_test_losspct_usage
},
9901 { { "iax2", "provision", NULL
},
9902 iax2_prov_cmd
, "Provision an IAX device",
9903 show_prov_usage
, iax2_prov_complete_template_3rd
},
9906 { { "iax2", "test", "late", NULL
},
9907 iax2_test_late
, "Test the receipt of a late frame",
9908 iax2_test_late_usage
},
9910 { { "iax2", "test", "resync", NULL
},
9911 iax2_test_resync
, "Test a resync in received timestamps",
9912 iax2_test_resync_usage
},
9914 { { "iax2", "test", "jitter", NULL
},
9915 iax2_test_jitter
, "Simulates jitter for testing",
9916 iax2_test_jitter_usage
},
9917 #endif /* IAXTESTS */
9920 static int __unload_module(void)
9922 pthread_t threadid
= AST_PTHREADT_NULL
;
9923 struct iax2_thread
*thread
= NULL
;
9926 /* Cancel the network thread, close the net socket */
9927 if (netthreadid
!= AST_PTHREADT_NULL
) {
9928 pthread_cancel(netthreadid
);
9929 pthread_join(netthreadid
, NULL
);
9931 if (schedthreadid
!= AST_PTHREADT_NULL
) {
9932 pthread_cancel(schedthreadid
);
9933 ast_mutex_lock(&sched_lock
);
9935 ast_cond_signal(&sched_cond
);
9936 ast_mutex_unlock(&sched_lock
);
9937 pthread_join(schedthreadid
, NULL
);
9940 /* Call for all threads to halt */
9941 AST_LIST_LOCK(&idle_list
);
9942 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list
, thread
, list
) {
9943 AST_LIST_REMOVE_CURRENT(&idle_list
, list
);
9944 threadid
= thread
->threadid
;
9946 signal_condition(&thread
->lock
, &thread
->cond
);
9947 pthread_join(threadid
, NULL
);
9949 AST_LIST_TRAVERSE_SAFE_END
9950 AST_LIST_UNLOCK(&idle_list
);
9952 AST_LIST_LOCK(&active_list
);
9953 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list
, thread
, list
) {
9954 AST_LIST_REMOVE_CURRENT(&active_list
, list
);
9955 threadid
= thread
->threadid
;
9957 signal_condition(&thread
->lock
, &thread
->cond
);
9958 pthread_join(threadid
, NULL
);
9960 AST_LIST_TRAVERSE_SAFE_END
9961 AST_LIST_UNLOCK(&active_list
);
9963 AST_LIST_LOCK(&dynamic_list
);
9964 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list
, thread
, list
) {
9965 AST_LIST_REMOVE_CURRENT(&dynamic_list
, list
);
9966 threadid
= thread
->threadid
;
9968 signal_condition(&thread
->lock
, &thread
->cond
);
9969 pthread_join(threadid
, NULL
);
9971 AST_LIST_TRAVERSE_SAFE_END
9972 AST_LIST_UNLOCK(&dynamic_list
);
9974 ast_netsock_release(netsock
);
9975 for (x
=0;x
<IAX_MAX_CALLS
;x
++)
9978 ast_manager_unregister( "IAXpeers" );
9979 ast_manager_unregister( "IAXnetstats" );
9980 ast_unregister_application(papp
);
9981 ast_cli_unregister_multiple(cli_iax2
, sizeof(cli_iax2
) / sizeof(struct ast_cli_entry
));
9982 ast_unregister_switch(&iax2_switch
);
9983 ast_channel_unregister(&iax2_tech
);
9985 iax_provision_unload();
9986 sched_context_destroy(sched
);
9990 static int unload_module(void)
9992 ast_mutex_destroy(&waresl
.lock
);
9993 ast_custom_function_unregister(&iaxpeer_function
);
9994 return __unload_module();
9998 /*! \brief Load IAX2 module, load configuraiton ---*/
9999 static int load_module(void)
10001 char *config
= "iax.conf";
10004 struct iax2_registry
*reg
= NULL
;
10005 struct iax2_peer
*peer
= NULL
;
10007 ast_custom_function_register(&iaxpeer_function
);
10009 iax_set_output(iax_debug_output
);
10010 iax_set_error(iax_error_output
);
10011 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
10015 timingfd
= open("/dev/zap/timer", O_RDWR
);
10018 timingfd
= open("/dev/zap/pseudo", O_RDWR
);
10020 ast_log(LOG_WARNING
, "Unable to open IAX timing interface: %s\n", strerror(errno
));
10023 memset(iaxs
, 0, sizeof(iaxs
));
10025 for (x
=0;x
<IAX_MAX_CALLS
;x
++)
10026 ast_mutex_init(&iaxsl
[x
]);
10028 io
= io_context_create();
10029 sched
= sched_context_create();
10031 if (!io
|| !sched
) {
10032 ast_log(LOG_ERROR
, "Out of memory\n");
10036 netsock
= ast_netsock_list_alloc();
10038 ast_log(LOG_ERROR
, "Could not allocate netsock list.\n");
10041 ast_netsock_init(netsock
);
10043 ast_mutex_init(&waresl
.lock
);
10045 ast_cli_register_multiple(cli_iax2
, sizeof(cli_iax2
) / sizeof(struct ast_cli_entry
));
10047 ast_register_application(papp
, iax2_prov_app
, psyn
, pdescrip
);
10049 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers
, "List IAX Peers" );
10050 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats
, "Show IAX Netstats" );
10052 if(set_config(config
, 0) == -1)
10053 return AST_MODULE_LOAD_DECLINE
;
10055 if (ast_channel_register(&iax2_tech
)) {
10056 ast_log(LOG_ERROR
, "Unable to register channel class %s\n", "IAX2");
10061 if (ast_register_switch(&iax2_switch
))
10062 ast_log(LOG_ERROR
, "Unable to register IAX switch\n");
10064 res
= start_network_thread();
10066 if (option_verbose
> 1)
10067 ast_verbose(VERBOSE_PREFIX_2
"IAX Ready and Listening\n");
10069 ast_log(LOG_ERROR
, "Unable to start network thread\n");
10070 ast_netsock_release(netsock
);
10073 for (reg
= registrations
; reg
; reg
= reg
->next
)
10074 iax2_do_register(reg
);
10075 AST_LIST_LOCK(&peers
);
10076 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
10077 if (peer
->sockfd
< 0)
10078 peer
->sockfd
= defaultsockfd
;
10079 iax2_poke_peer(peer
, 0);
10081 AST_LIST_UNLOCK(&peers
);
10083 iax_provision_reload();
10087 AST_MODULE_INFO(ASTERISK_GPL_KEY
, AST_MODFLAG_DEFAULT
, "Inter Asterisk eXchange (Ver 2)",
10088 .load
= load_module
,
10089 .unload
= unload_module
,