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 struct ast_netsock_list
*outsock
; /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
175 static int defaultsockfd
= -1;
177 int (*iax2_regfunk
)(const char *username
, int onoff
) = NULL
;
180 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
182 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
183 ~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 ast_cond_t sched_cond
;
234 IAX_STATE_STARTED
= (1 << 0),
235 IAX_STATE_AUTHENTICATED
= (1 << 1),
236 IAX_STATE_TBD
= (1 << 2),
237 IAX_STATE_UNCHANGED
= (1 << 3),
240 struct iax2_context
{
241 char context
[AST_MAX_CONTEXT
];
242 struct iax2_context
*next
;
246 IAX_HASCALLERID
= (1 << 0), /*!< CallerID has been specified */
247 IAX_DELME
= (1 << 1), /*!< Needs to be deleted */
248 IAX_TEMPONLY
= (1 << 2), /*!< Temporary (realtime) */
249 IAX_TRUNK
= (1 << 3), /*!< Treat as a trunk */
250 IAX_NOTRANSFER
= (1 << 4), /*!< Don't native bridge */
251 IAX_USEJITTERBUF
= (1 << 5), /*!< Use jitter buffer */
252 IAX_DYNAMIC
= (1 << 6), /*!< dynamic peer */
253 IAX_SENDANI
= (1 << 7), /*!< Send ANI along with CallerID */
254 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
255 IAX_ALREADYGONE
= (1 << 9), /*!< Already disconnected */
256 IAX_PROVISION
= (1 << 10), /*!< This is a provisioning request */
257 IAX_QUELCH
= (1 << 11), /*!< Whether or not we quelch audio */
258 IAX_ENCRYPTED
= (1 << 12), /*!< Whether we should assume encrypted tx/rx */
259 IAX_KEYPOPULATED
= (1 << 13), /*!< Whether we have a key populated */
260 IAX_CODEC_USER_FIRST
= (1 << 14), /*!< are we willing to let the other guy choose the codec? */
261 IAX_CODEC_NOPREFS
= (1 << 15), /*!< Force old behaviour by turning off prefs */
262 IAX_CODEC_NOCAP
= (1 << 16), /*!< only consider requested format and ignore capabilities*/
263 IAX_RTCACHEFRIENDS
= (1 << 17), /*!< let realtime stay till your reload */
264 IAX_RTUPDATE
= (1 << 18), /*!< Send a realtime update */
265 IAX_RTAUTOCLEAR
= (1 << 19), /*!< erase me on expire */
266 IAX_FORCEJITTERBUF
= (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
267 IAX_RTIGNOREREGEXPIRE
= (1 << 21), /*!< When using realtime, ignore registration expiration */
268 IAX_TRUNKTIMESTAMPS
= (1 << 22), /*!< Send trunk timestamps */
269 IAX_TRANSFERMEDIA
= (1 << 23), /*!< When doing IAX2 transfers, transfer media only */
270 IAX_MAXAUTHREQ
= (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */
271 IAX_DELAYPBXSTART
= (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a
272 response, so that we've achieved a three-way handshake with
273 them before sending voice or anything else*/
276 static int global_rtautoclear
= 120;
278 static int reload_config(void);
279 static int iax2_reload(int fd
, int argc
, char *argv
[]);
283 AST_DECLARE_STRING_FIELDS(
284 AST_STRING_FIELD(name
);
285 AST_STRING_FIELD(secret
);
286 AST_STRING_FIELD(dbsecret
);
287 AST_STRING_FIELD(accountcode
);
288 AST_STRING_FIELD(mohinterpret
);
289 AST_STRING_FIELD(mohsuggest
);
290 AST_STRING_FIELD(inkeys
); /*!< Key(s) this user can use to authenticate to us */
291 AST_STRING_FIELD(language
);
292 AST_STRING_FIELD(cid_num
);
293 AST_STRING_FIELD(cid_name
);
302 int maxauthreq
; /*!< Maximum allowed outstanding AUTHREQs */
303 int curauthreq
; /*!< Current number of outstanding AUTHREQs */
304 struct ast_codec_pref prefs
;
306 struct iax2_context
*contexts
;
307 struct ast_variable
*vars
;
308 AST_LIST_ENTRY(iax2_user
) entry
;
312 AST_DECLARE_STRING_FIELDS(
313 AST_STRING_FIELD(name
);
314 AST_STRING_FIELD(username
);
315 AST_STRING_FIELD(secret
);
316 AST_STRING_FIELD(dbsecret
);
317 AST_STRING_FIELD(outkey
); /*!< What key we use to talk to this peer */
319 AST_STRING_FIELD(regexten
); /*!< Extension to register (if regcontext is used) */
320 AST_STRING_FIELD(context
); /*!< For transfers only */
321 AST_STRING_FIELD(peercontext
); /*!< Context to pass to peer */
322 AST_STRING_FIELD(mailbox
); /*!< Mailbox */
323 AST_STRING_FIELD(mohinterpret
);
324 AST_STRING_FIELD(mohsuggest
);
325 AST_STRING_FIELD(inkeys
); /*!< Key(s) this peer can use to authenticate to us */
326 /* Suggested caller id if registering */
327 AST_STRING_FIELD(cid_num
); /*!< Default context (for transfer really) */
328 AST_STRING_FIELD(cid_name
); /*!< Default context (for transfer really) */
329 AST_STRING_FIELD(zonetag
); /*!< Time Zone */
331 struct ast_codec_pref prefs
;
332 struct ast_dnsmgr_entry
*dnsmgr
; /*!< DNS refresh manager */
333 struct sockaddr_in addr
;
335 int sockfd
; /*!< Socket to use for transmission */
340 /* Dynamic Registration fields */
341 struct sockaddr_in defaddr
; /*!< Default address if there is one */
342 int authmethods
; /*!< Authentication methods (IAX_AUTH_*) */
343 int encmethods
; /*!< Encryption methods (IAX_ENCRYPT_*) */
345 int expire
; /*!< Schedule entry for expiry */
346 int expiry
; /*!< How soon to expire */
347 int capability
; /*!< Capability */
350 int callno
; /*!< Call number of POKE request */
351 int pokeexpire
; /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
352 int lastms
; /*!< How long last response took (in ms), or -1 for no response */
353 int maxms
; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
355 int pokefreqok
; /*!< How often to check if the host is up */
356 int pokefreqnotok
; /*!< How often to check when the host has been determined to be down */
357 int historicms
; /*!< How long recent average responses took */
358 int smoothing
; /*!< Sample over how many units to determine historic ms */
361 AST_LIST_ENTRY(iax2_peer
) entry
;
364 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
366 static struct iax2_trunk_peer
{
369 struct sockaddr_in addr
;
370 struct timeval txtrunktime
; /*!< Transmit trunktime */
371 struct timeval rxtrunktime
; /*!< Receive trunktime */
372 struct timeval lasttxtime
; /*!< Last transmitted trunktime */
373 struct timeval trunkact
; /*!< Last trunk activity */
374 unsigned int lastsent
; /*!< Last sent time */
375 /* Trunk data and length */
376 unsigned char *trunkdata
;
377 unsigned int trunkdatalen
;
378 unsigned int trunkdataalloc
;
379 struct iax2_trunk_peer
*next
;
384 AST_MUTEX_DEFINE_STATIC(tpeerlock
);
386 struct iax_firmware
{
387 struct iax_firmware
*next
;
391 struct ast_iax2_firmware_header
*fwh
;
396 REG_STATE_UNREGISTERED
= 0,
399 REG_STATE_REGISTERED
,
405 enum iax_transfer_state
{
410 TRANSFER_PASSTHROUGH
,
414 TRANSFER_MPASSTHROUGH
,
419 struct iax2_registry
{
420 struct sockaddr_in addr
; /*!< Who we connect to for registration purposes */
422 char secret
[80]; /*!< Password or key name in []'s */
424 int expire
; /*!< Sched ID of expiration */
425 int refresh
; /*!< How often to refresh */
426 enum iax_reg_state regstate
;
427 int messages
; /*!< Message count, low 8 bits = new, high 8 bits = old */
428 int callno
; /*!< Associated call number if applicable */
429 struct sockaddr_in us
; /*!< Who the server thinks we are */
430 struct ast_dnsmgr_entry
*dnsmgr
; /*!< DNS refresh manager */
431 AST_LIST_ENTRY(iax2_registry
) entry
;
434 static AST_LIST_HEAD_STATIC(registrations
, iax2_registry
);
436 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
437 #define MIN_RETRY_TIME 100
438 #define MAX_RETRY_TIME 10000
440 #define MAX_JITTER_BUFFER 50
441 #define MIN_JITTER_BUFFER 10
443 #define DEFAULT_TRUNKDATA 640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
444 #define MAX_TRUNKDATA 640 * 200 /*!< 40ms, uncompressed linear * 200 channels */
446 #define MAX_TIMESTAMP_SKEW 160 /*!< maximum difference between actual and predicted ts for sending */
448 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
449 #define TS_GAP_FOR_JB_RESYNC 5000
451 static int iaxthreadcount
= DEFAULT_THREAD_COUNT
;
452 static int iaxmaxthreadcount
= DEFAULT_MAX_THREAD_COUNT
;
453 static int iaxdynamicthreadcount
= 0;
454 static int iaxactivethreadcount
= 0;
466 struct chan_iax2_pvt
{
467 /*! Socket to send/receive on for this call */
469 /*! Last received voice format */
471 /*! Last received video format */
473 /*! Last sent voice format */
475 /*! Last sent video format */
477 /*! What we are capable of sending */
479 /*! Last received timestamp */
481 /*! Last sent timestamp - never send the same timestamp twice in a single call */
482 unsigned int lastsent
;
483 /*! Next outgoing timestamp if everything is good */
484 unsigned int nextpred
;
485 /*! True if the last voice we transmitted was not silence/CNG */
488 unsigned int pingtime
;
489 /*! Max time for initial response */
492 struct sockaddr_in addr
;
493 /*! Actual used codec preferences */
494 struct ast_codec_pref prefs
;
495 /*! Requested codec preferences */
496 struct ast_codec_pref rprefs
;
497 /*! Our call number */
498 unsigned short callno
;
500 unsigned short peercallno
;
501 /*! Peer selected format */
503 /*! Peer capability */
505 /*! timeval that we base our transmission on */
506 struct timeval offset
;
507 /*! timeval that we base our delivery on */
508 struct timeval rxcore
;
509 /*! The jitterbuffer */
511 /*! active jb read scheduler id */
515 /*! Error, as discovered by the manager */
517 /*! Owner if we have one */
518 struct ast_channel
*owner
;
519 /*! What's our state? */
520 struct ast_flags state
;
521 /*! Expiry (optional) */
523 /*! Next outgoing sequence number */
524 unsigned char oseqno
;
525 /*! Next sequence number they have not yet acknowledged */
526 unsigned char rseqno
;
527 /*! Next incoming sequence number */
528 unsigned char iseqno
;
529 /*! Last incoming sequence number we have acknowledged */
530 unsigned char aseqno
;
532 AST_DECLARE_STRING_FIELDS(
534 AST_STRING_FIELD(peer
);
535 /*! Default Context */
536 AST_STRING_FIELD(context
);
537 /*! Caller ID if available */
538 AST_STRING_FIELD(cid_num
);
539 AST_STRING_FIELD(cid_name
);
540 /*! Hidden Caller ID (i.e. ANI) if appropriate */
541 AST_STRING_FIELD(ani
);
543 AST_STRING_FIELD(dnid
);
545 AST_STRING_FIELD(rdnis
);
546 /*! Requested Extension */
547 AST_STRING_FIELD(exten
);
548 /*! Expected Username */
549 AST_STRING_FIELD(username
);
550 /*! Expected Secret */
551 AST_STRING_FIELD(secret
);
553 AST_STRING_FIELD(challenge
);
554 /*! Public keys permitted keys for incoming authentication */
555 AST_STRING_FIELD(inkeys
);
556 /*! Private key for outgoing authentication */
557 AST_STRING_FIELD(outkey
);
558 /*! Preferred language */
559 AST_STRING_FIELD(language
);
560 /*! Hostname/peername for naming purposes */
561 AST_STRING_FIELD(host
);
563 AST_STRING_FIELD(dproot
);
564 AST_STRING_FIELD(accountcode
);
565 AST_STRING_FIELD(mohinterpret
);
566 AST_STRING_FIELD(mohsuggest
);
569 /*! permitted authentication methods */
571 /*! permitted encryption methods */
573 /*! Encryption AES-128 Key */
575 /*! Decryption AES-128 Key */
577 /*! 32 bytes of semi-random data */
578 unsigned char semirand
[32];
579 /*! Associated registry */
580 struct iax2_registry
*reg
;
581 /*! Associated peer for poking */
582 struct iax2_peer
*peerpoke
;
587 /*! Transferring status */
588 enum iax_transfer_state transferring
;
589 /*! Transfer identifier */
591 /*! Who we are IAX transfering to */
592 struct sockaddr_in transfer
;
593 /*! What's the new call number for the transfer */
594 unsigned short transfercallno
;
595 /*! Transfer decrypt AES-128 Key */
596 aes_encrypt_ctx tdcx
;
598 /*! Status of knowledge of peer ADSI capability */
601 /*! Who we are bridged to */
602 unsigned short bridgecallno
;
604 int pingid
; /*!< Transmit PING request */
605 int lagid
; /*!< Retransmit lag request */
606 int autoid
; /*!< Auto hangup for Dialplan requestor */
607 int authid
; /*!< Authentication rejection ID */
608 int authfail
; /*!< Reason to report failure */
609 int initid
; /*!< Initial peer auto-congest ID (based on qualified peers) */
614 struct iax2_dpcache
*dpentries
;
615 struct ast_variable
*vars
;
616 /*! last received remote rr */
617 struct iax_rr remote_rr
;
618 /*! Current base time: (just for stats) */
620 /*! Dropped frame count: (just for stats) */
622 /*! received frame count: (just for stats) */
626 static struct ast_iax2_queue
{
627 AST_LIST_HEAD(, iax_frame
) queue
;
631 static AST_LIST_HEAD_STATIC(users
, iax2_user
);
633 static AST_LIST_HEAD_STATIC(peers
, iax2_peer
);
635 static struct ast_firmware_list
{
636 struct iax_firmware
*wares
;
640 /*! Extension exists */
641 #define CACHE_FLAG_EXISTS (1 << 0)
642 /*! Extension is nonexistent */
643 #define CACHE_FLAG_NONEXISTENT (1 << 1)
644 /*! Extension can exist */
645 #define CACHE_FLAG_CANEXIST (1 << 2)
646 /*! Waiting to hear back response */
647 #define CACHE_FLAG_PENDING (1 << 3)
649 #define CACHE_FLAG_TIMEOUT (1 << 4)
650 /*! Request transmitted */
651 #define CACHE_FLAG_TRANSMITTED (1 << 5)
653 #define CACHE_FLAG_UNKNOWN (1 << 6)
655 #define CACHE_FLAG_MATCHMORE (1 << 7)
657 static struct iax2_dpcache
{
658 char peercontext
[AST_MAX_CONTEXT
];
659 char exten
[AST_MAX_EXTENSION
];
661 struct timeval expiry
;
663 unsigned short callno
;
665 struct iax2_dpcache
*next
;
666 struct iax2_dpcache
*peer
; /*!< For linking in peers */
669 AST_MUTEX_DEFINE_STATIC(dpcache_lock
);
671 static void reg_source_db(struct iax2_peer
*p
);
672 static struct iax2_peer
*realtime_peer(const char *peername
, struct sockaddr_in
*sin
);
674 static void destroy_peer(struct iax2_peer
*peer
);
675 static int ast_cli_netstats(struct mansession
*s
, int fd
, int limit_fmt
);
677 #define IAX_IOSTATE_IDLE 0
678 #define IAX_IOSTATE_READY 1
679 #define IAX_IOSTATE_PROCESSING 2
680 #define IAX_IOSTATE_SCHEDREADY 3
682 #define IAX_TYPE_POOL 1
683 #define IAX_TYPE_DYNAMIC 2
686 AST_LIST_ENTRY(iax2_thread
) list
;
689 #ifdef SCHED_MULTITHREADED
690 void (*schedfunc
)(void *);
693 #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
, unsigned int duration
);
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 void insert_idle_thread(struct iax2_thread
*thread
)
834 if (thread
->type
== IAX_TYPE_DYNAMIC
) {
835 AST_LIST_LOCK(&dynamic_list
);
836 AST_LIST_INSERT_TAIL(&dynamic_list
, thread
, list
);
837 AST_LIST_UNLOCK(&dynamic_list
);
839 AST_LIST_LOCK(&idle_list
);
840 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
841 AST_LIST_UNLOCK(&idle_list
);
847 static struct iax2_thread
*find_idle_thread(void)
850 struct iax2_thread
*thread
= NULL
;
852 /* Pop the head of the list off */
853 AST_LIST_LOCK(&idle_list
);
854 thread
= AST_LIST_REMOVE_HEAD(&idle_list
, list
);
855 AST_LIST_UNLOCK(&idle_list
);
857 /* If no idle thread is available from the regular list, try dynamic */
858 if (thread
== NULL
) {
859 AST_LIST_LOCK(&dynamic_list
);
860 thread
= AST_LIST_REMOVE_HEAD(&dynamic_list
, list
);
861 /* Make sure we absolutely have a thread... if not, try to make one if allowed */
862 if (thread
== NULL
&& iaxmaxthreadcount
> iaxdynamicthreadcount
) {
863 /* We need to MAKE a thread! */
864 if ((thread
= ast_calloc(1, sizeof(*thread
)))) {
865 thread
->threadnum
= iaxdynamicthreadcount
;
866 thread
->type
= IAX_TYPE_DYNAMIC
;
867 ast_mutex_init(&thread
->lock
);
868 ast_cond_init(&thread
->cond
, NULL
);
869 pthread_attr_init(&attr
);
870 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
871 if (ast_pthread_create(&thread
->threadid
, &attr
, iax2_process_thread
, thread
)) {
875 /* All went well and the thread is up, so increment our count */
876 iaxdynamicthreadcount
++;
880 AST_LIST_UNLOCK(&dynamic_list
);
886 #ifdef SCHED_MULTITHREADED
887 static int __schedule_action(void (*func
)(void *data
), void *data
, const char *funcname
)
889 struct iax2_thread
*thread
= NULL
;
890 static time_t lasterror
;
893 thread
= find_idle_thread();
895 if (thread
!= NULL
) {
896 thread
->schedfunc
= func
;
897 thread
->scheddata
= data
;
898 thread
->iostate
= IAX_IOSTATE_SCHEDREADY
;
899 #ifdef DEBUG_SCHED_MULTITHREAD
900 ast_copy_string(thread
->curfunc
, funcname
, sizeof(thread
->curfunc
));
902 signal_condition(&thread
->lock
, &thread
->cond
);
907 ast_log(LOG_NOTICE
, "Out of idle IAX2 threads for scheduling!\n");
912 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
915 static int send_ping(void *data
);
917 static void __send_ping(void *data
)
919 int callno
= (long)data
;
920 ast_mutex_lock(&iaxsl
[callno
]);
921 if (iaxs
[callno
] && iaxs
[callno
]->pingid
!= -1) {
922 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_PING
, 0, NULL
, 0, -1);
923 iaxs
[callno
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, data
);
925 ast_mutex_unlock(&iaxsl
[callno
]);
928 static int send_ping(void *data
)
930 #ifdef SCHED_MULTITHREADED
931 if (schedule_action(__send_ping
, data
))
937 static int get_encrypt_methods(const char *s
)
940 if (!strcasecmp(s
, "aes128"))
941 e
= IAX_ENCRYPT_AES128
;
942 else if (ast_true(s
))
943 e
= IAX_ENCRYPT_AES128
;
949 static int send_lagrq(void *data
);
951 static void __send_lagrq(void *data
)
953 int callno
= (long)data
;
954 /* Ping only if it's real not if it's bridged */
955 ast_mutex_lock(&iaxsl
[callno
]);
956 if (iaxs
[callno
] && iaxs
[callno
]->lagid
!= -1) {
957 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_LAGRQ
, 0, NULL
, 0, -1);
958 iaxs
[callno
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, data
);
960 ast_mutex_unlock(&iaxsl
[callno
]);
963 static int send_lagrq(void *data
)
965 #ifdef SCHED_MULTITHREADED
966 if (schedule_action(__send_lagrq
, data
))
972 static unsigned char compress_subclass(int subclass
)
976 /* If it's 128 or smaller, just return it */
977 if (subclass
< IAX_FLAG_SC_LOG
)
979 /* Otherwise find its power */
980 for (x
= 0; x
< IAX_MAX_SHIFT
; x
++) {
981 if (subclass
& (1 << x
)) {
983 ast_log(LOG_WARNING
, "Can't compress subclass %d\n", subclass
);
989 return power
| IAX_FLAG_SC_LOG
;
992 static int uncompress_subclass(unsigned char csub
)
994 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
995 if (csub
& IAX_FLAG_SC_LOG
) {
996 /* special case for 'compressed' -1 */
1000 return 1 << (csub
& ~IAX_FLAG_SC_LOG
& IAX_MAX_SHIFT
);
1006 static struct iax2_peer
*find_peer(const char *name
, int realtime
)
1008 struct iax2_peer
*peer
= NULL
;
1010 /* Grab peer from linked list */
1011 AST_LIST_LOCK(&peers
);
1012 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
1013 if (!strcasecmp(peer
->name
, name
)) {
1017 AST_LIST_UNLOCK(&peers
);
1019 /* Now go for realtime if applicable */
1020 if(!peer
&& realtime
)
1021 peer
= realtime_peer(name
, NULL
);
1025 static int iax2_getpeername(struct sockaddr_in sin
, char *host
, int len
, int lockpeer
)
1027 struct iax2_peer
*peer
= NULL
;
1031 AST_LIST_LOCK(&peers
);
1032 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
1033 if ((peer
->addr
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
) &&
1034 (peer
->addr
.sin_port
== sin
.sin_port
)) {
1035 ast_copy_string(host
, peer
->name
, len
);
1041 AST_LIST_UNLOCK(&peers
);
1043 peer
= realtime_peer(NULL
, &sin
);
1045 ast_copy_string(host
, peer
->name
, len
);
1046 if (ast_test_flag(peer
, IAX_TEMPONLY
))
1055 static struct chan_iax2_pvt
*new_iax(struct sockaddr_in
*sin
, int lockpeer
, const char *host
)
1057 struct chan_iax2_pvt
*tmp
;
1060 if (!(tmp
= ast_calloc(1, sizeof(*tmp
))))
1063 if (ast_string_field_init(tmp
, 32)) {
1071 tmp
->peercallno
= 0;
1072 tmp
->transfercallno
= 0;
1073 tmp
->bridgecallno
= 0;
1080 ast_string_field_set(tmp
,exten
, "s");
1081 ast_string_field_set(tmp
,host
, host
);
1085 jbconf
.max_jitterbuf
= maxjitterbuffer
;
1086 jbconf
.resync_threshold
= resyncthreshold
;
1087 jbconf
.max_contig_interp
= maxjitterinterps
;
1088 jb_setconf(tmp
->jb
,&jbconf
);
1093 static struct iax_frame
*iaxfrdup2(struct iax_frame
*fr
)
1095 struct iax_frame
*new = iax_frame_new(DIRECTION_INGRESS
, fr
->af
.datalen
, fr
->cacheable
);
1097 size_t mallocd_datalen
= new->mallocd_datalen
;
1098 memcpy(new, fr
, sizeof(*new));
1099 iax_frame_wrap(new, &fr
->af
);
1100 new->mallocd_datalen
= mallocd_datalen
;
1103 new->direction
= DIRECTION_INGRESS
;
1109 #define NEW_PREVENT 0
1113 static int match(struct sockaddr_in
*sin
, unsigned short callno
, unsigned short dcallno
, struct chan_iax2_pvt
*cur
)
1115 if ((cur
->addr
.sin_addr
.s_addr
== sin
->sin_addr
.s_addr
) &&
1116 (cur
->addr
.sin_port
== sin
->sin_port
)) {
1117 /* This is the main host */
1118 if ((cur
->peercallno
== callno
) ||
1119 ((dcallno
== cur
->callno
) && !cur
->peercallno
)) {
1120 /* That's us. Be sure we keep track of the peer call number */
1124 if ((cur
->transfer
.sin_addr
.s_addr
== sin
->sin_addr
.s_addr
) &&
1125 (cur
->transfer
.sin_port
== sin
->sin_port
) && (cur
->transferring
)) {
1126 /* We're transferring */
1127 if (dcallno
== cur
->callno
)
1133 static void update_max_trunk(void)
1135 int max
= TRUNK_CALL_START
;
1137 /* XXX Prolly don't need locks here XXX */
1138 for (x
=TRUNK_CALL_START
;x
<IAX_MAX_CALLS
- 1; x
++) {
1143 if (option_debug
&& iaxdebug
)
1144 ast_log(LOG_DEBUG
, "New max trunk callno is %d\n", max
);
1147 static void update_max_nontrunk(void)
1151 /* XXX Prolly don't need locks here XXX */
1152 for (x
=1;x
<TRUNK_CALL_START
- 1; x
++) {
1156 maxnontrunkcall
= max
;
1157 if (option_debug
&& iaxdebug
)
1158 ast_log(LOG_DEBUG
, "New max nontrunk callno is %d\n", max
);
1161 static int make_trunk(unsigned short callno
, int locked
)
1166 if (iaxs
[callno
]->oseqno
) {
1167 ast_log(LOG_WARNING
, "Can't make trunk once a call has started!\n");
1170 if (callno
& TRUNK_CALL_START
) {
1171 ast_log(LOG_WARNING
, "Call %d is already a trunk\n", callno
);
1174 gettimeofday(&now
, NULL
);
1175 for (x
=TRUNK_CALL_START
;x
<IAX_MAX_CALLS
- 1; x
++) {
1176 ast_mutex_lock(&iaxsl
[x
]);
1177 if (!iaxs
[x
] && ((now
.tv_sec
- lastused
[x
].tv_sec
) > MIN_REUSE_TIME
)) {
1178 iaxs
[x
] = iaxs
[callno
];
1179 iaxs
[x
]->callno
= x
;
1180 iaxs
[callno
] = NULL
;
1181 /* Update the two timers that should have been started */
1182 if (iaxs
[x
]->pingid
> -1)
1183 ast_sched_del(sched
, iaxs
[x
]->pingid
);
1184 if (iaxs
[x
]->lagid
> -1)
1185 ast_sched_del(sched
, iaxs
[x
]->lagid
);
1186 iaxs
[x
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, (void *)(long)x
);
1187 iaxs
[x
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, (void *)(long)x
);
1189 ast_mutex_unlock(&iaxsl
[callno
]);
1192 ast_mutex_unlock(&iaxsl
[x
]);
1195 ast_mutex_unlock(&iaxsl
[x
]);
1197 if (x
>= IAX_MAX_CALLS
- 1) {
1198 ast_log(LOG_WARNING
, "Unable to trunk call: Insufficient space\n");
1201 ast_log(LOG_DEBUG
, "Made call %d into trunk call %d\n", callno
, x
);
1202 /* We move this call from a non-trunked to a trunked call */
1204 update_max_nontrunk();
1208 static int find_callno(unsigned short callno
, unsigned short dcallno
, struct sockaddr_in
*sin
, int new, int lockpeer
, int sockfd
)
1214 if (new <= NEW_ALLOW
) {
1215 /* Look for an existing connection first */
1216 for (x
=1;(res
< 1) && (x
<maxnontrunkcall
);x
++) {
1217 ast_mutex_lock(&iaxsl
[x
]);
1219 /* Look for an exact match */
1220 if (match(sin
, callno
, dcallno
, iaxs
[x
])) {
1224 ast_mutex_unlock(&iaxsl
[x
]);
1226 for (x
=TRUNK_CALL_START
;(res
< 1) && (x
<maxtrunkcall
);x
++) {
1227 ast_mutex_lock(&iaxsl
[x
]);
1229 /* Look for an exact match */
1230 if (match(sin
, callno
, dcallno
, iaxs
[x
])) {
1234 ast_mutex_unlock(&iaxsl
[x
]);
1237 if ((res
< 1) && (new >= NEW_ALLOW
)) {
1238 /* It may seem odd that we look through the peer list for a name for
1239 * this *incoming* call. Well, it is weird. However, users don't
1240 * have an IP address/port number that we can match against. So,
1241 * this is just checking for a peer that has that IP/port and
1242 * assuming that we have a user of the same name. This isn't always
1243 * correct, but it will be changed if needed after authentication. */
1244 if (!iax2_getpeername(*sin
, host
, sizeof(host
), lockpeer
))
1245 snprintf(host
, sizeof(host
), "%s:%d", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
1246 gettimeofday(&now
, NULL
);
1247 for (x
=1;x
<TRUNK_CALL_START
;x
++) {
1248 /* Find first unused call number that hasn't been used in a while */
1249 ast_mutex_lock(&iaxsl
[x
]);
1250 if (!iaxs
[x
] && ((now
.tv_sec
- lastused
[x
].tv_sec
) > MIN_REUSE_TIME
)) break;
1251 ast_mutex_unlock(&iaxsl
[x
]);
1253 /* We've still got lock held if we found a spot */
1254 if (x
>= TRUNK_CALL_START
) {
1255 ast_log(LOG_WARNING
, "No more space\n");
1258 iaxs
[x
] = new_iax(sin
, lockpeer
, host
);
1259 update_max_nontrunk();
1261 if (option_debug
&& iaxdebug
)
1262 ast_log(LOG_DEBUG
, "Creating new call structure %d\n", x
);
1263 iaxs
[x
]->sockfd
= sockfd
;
1264 iaxs
[x
]->addr
.sin_port
= sin
->sin_port
;
1265 iaxs
[x
]->addr
.sin_family
= sin
->sin_family
;
1266 iaxs
[x
]->addr
.sin_addr
.s_addr
= sin
->sin_addr
.s_addr
;
1267 iaxs
[x
]->peercallno
= callno
;
1268 iaxs
[x
]->callno
= x
;
1269 iaxs
[x
]->pingtime
= DEFAULT_RETRY_TIME
;
1270 iaxs
[x
]->expiry
= min_reg_expire
;
1271 iaxs
[x
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, (void *)(long)x
);
1272 iaxs
[x
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, (void *)(long)x
);
1273 iaxs
[x
]->amaflags
= amaflags
;
1274 ast_copy_flags(iaxs
[x
], (&globalflags
), IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
1276 ast_string_field_set(iaxs
[x
], accountcode
, accountcode
);
1277 ast_string_field_set(iaxs
[x
], mohinterpret
, mohinterpret
);
1278 ast_string_field_set(iaxs
[x
], mohsuggest
, mohsuggest
);
1280 ast_log(LOG_WARNING
, "Out of resources\n");
1281 ast_mutex_unlock(&iaxsl
[x
]);
1284 ast_mutex_unlock(&iaxsl
[x
]);
1290 static void iax2_frame_free(struct iax_frame
*fr
)
1292 if (fr
->retrans
> -1)
1293 ast_sched_del(sched
, fr
->retrans
);
1297 static int iax2_queue_frame(int callno
, struct ast_frame
*f
)
1299 /* Assumes lock for callno is already held... */
1301 if (iaxs
[callno
] && iaxs
[callno
]->owner
) {
1302 if (ast_mutex_trylock(&iaxs
[callno
]->owner
->lock
)) {
1303 /* Avoid deadlock by pausing and trying again */
1304 ast_mutex_unlock(&iaxsl
[callno
]);
1306 ast_mutex_lock(&iaxsl
[callno
]);
1308 ast_queue_frame(iaxs
[callno
]->owner
, f
);
1309 ast_mutex_unlock(&iaxs
[callno
]->owner
->lock
);
1318 static void destroy_firmware(struct iax_firmware
*cur
)
1320 /* Close firmware */
1322 munmap(cur
->fwh
, ntohl(cur
->fwh
->datalen
) + sizeof(*(cur
->fwh
)));
1328 static int try_firmware(char *s
)
1331 struct iax_firmware
*cur
;
1336 struct ast_iax2_firmware_header
*fwh
, fwh2
;
1337 struct MD5Context md5
;
1338 unsigned char sum
[16];
1339 unsigned char buf
[1024];
1343 s2
= alloca(strlen(s
) + 100);
1345 ast_log(LOG_WARNING
, "Alloca failed!\n");
1348 last
= strrchr(s
, '/');
1353 snprintf(s2
, strlen(s
) + 100, "/var/tmp/%s-%ld", last
, (unsigned long)ast_random());
1354 res
= stat(s
, &stbuf
);
1356 ast_log(LOG_WARNING
, "Failed to stat '%s': %s\n", s
, strerror(errno
));
1359 /* Make sure it's not a directory */
1360 if (S_ISDIR(stbuf
.st_mode
))
1362 ifd
= open(s
, O_RDONLY
);
1364 ast_log(LOG_WARNING
, "Cannot open '%s': %s\n", s
, strerror(errno
));
1367 fd
= open(s2
, O_RDWR
| O_CREAT
| O_EXCL
);
1369 ast_log(LOG_WARNING
, "Cannot open '%s' for writing: %s\n", s2
, strerror(errno
));
1373 /* Unlink our newly created file */
1376 /* Now copy the firmware into it */
1377 len
= stbuf
.st_size
;
1380 if (chunk
> sizeof(buf
))
1381 chunk
= sizeof(buf
);
1382 res
= read(ifd
, buf
, chunk
);
1384 ast_log(LOG_WARNING
, "Only read %d of %d bytes of data :(: %s\n", res
, chunk
, strerror(errno
));
1389 res
= write(fd
, buf
, chunk
);
1391 ast_log(LOG_WARNING
, "Only write %d of %d bytes of data :(: %s\n", res
, chunk
, strerror(errno
));
1399 /* Return to the beginning */
1400 lseek(fd
, 0, SEEK_SET
);
1401 if ((res
= read(fd
, &fwh2
, sizeof(fwh2
))) != sizeof(fwh2
)) {
1402 ast_log(LOG_WARNING
, "Unable to read firmware header in '%s'\n", s
);
1406 if (ntohl(fwh2
.magic
) != IAX_FIRMWARE_MAGIC
) {
1407 ast_log(LOG_WARNING
, "'%s' is not a valid firmware file\n", s
);
1411 if (ntohl(fwh2
.datalen
) != (stbuf
.st_size
- sizeof(fwh2
))) {
1412 ast_log(LOG_WARNING
, "Invalid data length in firmware '%s'\n", s
);
1416 if (fwh2
.devname
[sizeof(fwh2
.devname
) - 1] || ast_strlen_zero((char *)fwh2
.devname
)) {
1417 ast_log(LOG_WARNING
, "No or invalid device type specified for '%s'\n", s
);
1421 fwh
= mmap(NULL
, stbuf
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
1422 if (fwh
== (void *) -1) {
1423 ast_log(LOG_WARNING
, "mmap failed: %s\n", strerror(errno
));
1428 MD5Update(&md5
, fwh
->data
, ntohl(fwh
->datalen
));
1429 MD5Final(sum
, &md5
);
1430 if (memcmp(sum
, fwh
->chksum
, sizeof(sum
))) {
1431 ast_log(LOG_WARNING
, "Firmware file '%s' fails checksum\n", s
);
1432 munmap(fwh
, stbuf
.st_size
);
1438 if (!strcmp((char *)cur
->fwh
->devname
, (char *)fwh
->devname
)) {
1439 /* Found a candidate */
1440 if (cur
->dead
|| (ntohs(cur
->fwh
->version
) < ntohs(fwh
->version
)))
1441 /* The version we have on loaded is older, load this one instead */
1443 /* This version is no newer than what we have. Don't worry about it.
1444 We'll consider it a proper load anyhow though */
1445 munmap(fwh
, stbuf
.st_size
);
1452 /* Allocate a new one and link it */
1453 if ((cur
= ast_calloc(1, sizeof(*cur
)))) {
1455 cur
->next
= waresl
.wares
;
1461 munmap(cur
->fwh
, cur
->mmaplen
);
1467 cur
->mmaplen
= stbuf
.st_size
;
1473 static int iax_check_version(char *dev
)
1476 struct iax_firmware
*cur
;
1477 if (!ast_strlen_zero(dev
)) {
1478 ast_mutex_lock(&waresl
.lock
);
1481 if (!strcmp(dev
, (char *)cur
->fwh
->devname
)) {
1482 res
= ntohs(cur
->fwh
->version
);
1487 ast_mutex_unlock(&waresl
.lock
);
1492 static int iax_firmware_append(struct iax_ie_data
*ied
, const unsigned char *dev
, unsigned int desc
)
1495 unsigned int bs
= desc
& 0xff;
1496 unsigned int start
= (desc
>> 8) & 0xffffff;
1498 struct iax_firmware
*cur
;
1499 if (!ast_strlen_zero((char *)dev
) && bs
) {
1501 ast_mutex_lock(&waresl
.lock
);
1504 if (!strcmp((char *)dev
, (char *)cur
->fwh
->devname
)) {
1505 iax_ie_append_int(ied
, IAX_IE_FWBLOCKDESC
, desc
);
1506 if (start
< ntohl(cur
->fwh
->datalen
)) {
1507 bytes
= ntohl(cur
->fwh
->datalen
) - start
;
1510 iax_ie_append_raw(ied
, IAX_IE_FWBLOCKDATA
, cur
->fwh
->data
+ start
, bytes
);
1513 iax_ie_append(ied
, IAX_IE_FWBLOCKDATA
);
1523 ast_mutex_unlock(&waresl
.lock
);
1529 static void reload_firmware(void)
1531 struct iax_firmware
*cur
, *curl
, *curp
;
1536 /* Mark all as dead */
1537 ast_mutex_lock(&waresl
.lock
);
1543 /* Now that we've freed them, load the new ones */
1544 snprintf(dir
, sizeof(dir
), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR
);
1547 while((de
= readdir(fwd
))) {
1548 if (de
->d_name
[0] != '.') {
1549 snprintf(fn
, sizeof(fn
), "%s/%s", dir
, de
->d_name
);
1550 if (!try_firmware(fn
)) {
1551 if (option_verbose
> 1)
1552 ast_verbose(VERBOSE_PREFIX_2
"Loaded firmware '%s'\n", de
->d_name
);
1558 ast_log(LOG_WARNING
, "Error opening firmware directory '%s': %s\n", dir
, strerror(errno
));
1560 /* Clean up leftovers */
1572 destroy_firmware(curl
);
1577 ast_mutex_unlock(&waresl
.lock
);
1580 static int __do_deliver(void *data
)
1582 /* Just deliver the packet by using queueing. This is called by
1583 the IAX thread with the iaxsl lock held. */
1584 struct iax_frame
*fr
= data
;
1586 fr
->af
.has_timing_info
= 0;
1587 if (iaxs
[fr
->callno
] && !ast_test_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
))
1588 iax2_queue_frame(fr
->callno
, &fr
->af
);
1589 /* Free our iax frame */
1590 iax2_frame_free(fr
);
1591 /* And don't run again */
1595 static int handle_error(void)
1597 /* XXX Ideally we should figure out why an error occured and then abort those
1598 rather than continuing to try. Unfortunately, the published interface does
1599 not seem to work XXX */
1601 struct sockaddr_in
*sin
;
1604 struct sock_extended_err e
;
1609 m
.msg_controllen
= sizeof(e
);
1611 res
= recvmsg(netsocket
, &m
, MSG_ERRQUEUE
);
1613 ast_log(LOG_WARNING
, "Error detected, but unable to read error: %s\n", strerror(errno
));
1615 if (m
.msg_controllen
) {
1616 sin
= (struct sockaddr_in
*)SO_EE_OFFENDER(&e
);
1618 ast_log(LOG_WARNING
, "Receive error from %s\n", ast_inet_ntoa(sin
->sin_addr
));
1620 ast_log(LOG_WARNING
, "No address detected??\n");
1622 ast_log(LOG_WARNING
, "Local error: %s\n", strerror(e
.ee_errno
));
1629 static int transmit_trunk(struct iax_frame
*f
, struct sockaddr_in
*sin
, int sockfd
)
1632 res
= sendto(sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)sin
,
1636 ast_log(LOG_DEBUG
, "Received error: %s\n", strerror(errno
));
1643 static int send_packet(struct iax_frame
*f
)
1646 int callno
= f
->callno
;
1648 /* Don't send if there was an error, but return error instead */
1649 if (!callno
|| !iaxs
[callno
] || iaxs
[callno
]->error
)
1652 /* Called with iaxsl held */
1653 if (option_debug
> 2 && iaxdebug
)
1654 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
));
1657 iax_showframe(f
, NULL
, 0, &iaxs
[callno
]->transfer
, f
->datalen
- sizeof(struct ast_iax2_full_hdr
));
1658 res
= sendto(iaxs
[callno
]->sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)&iaxs
[callno
]->transfer
,
1659 sizeof(iaxs
[callno
]->transfer
));
1662 iax_showframe(f
, NULL
, 0, &iaxs
[callno
]->addr
, f
->datalen
- sizeof(struct ast_iax2_full_hdr
));
1663 res
= sendto(iaxs
[callno
]->sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)&iaxs
[callno
]->addr
,
1664 sizeof(iaxs
[callno
]->addr
));
1667 if (option_debug
&& iaxdebug
)
1668 ast_log(LOG_DEBUG
, "Received error: %s\n", strerror(errno
));
1675 static void iax2_destroy_helper(struct chan_iax2_pvt
*pvt
)
1677 struct iax2_user
*user
= NULL
;
1679 /* Decrement AUTHREQ count if needed */
1680 if (ast_test_flag(pvt
, IAX_MAXAUTHREQ
)) {
1681 AST_LIST_LOCK(&users
);
1682 AST_LIST_TRAVERSE(&users
, user
, entry
) {
1683 if (!strcmp(user
->name
, pvt
->username
)) {
1688 AST_LIST_UNLOCK(&users
);
1689 ast_clear_flag(pvt
, IAX_MAXAUTHREQ
);
1691 /* No more pings or lagrq's */
1692 if (pvt
->pingid
> -1)
1693 ast_sched_del(sched
, pvt
->pingid
);
1695 if (pvt
->lagid
> -1)
1696 ast_sched_del(sched
, pvt
->lagid
);
1698 if (pvt
->autoid
> -1)
1699 ast_sched_del(sched
, pvt
->autoid
);
1701 if (pvt
->authid
> -1)
1702 ast_sched_del(sched
, pvt
->authid
);
1704 if (pvt
->initid
> -1)
1705 ast_sched_del(sched
, pvt
->initid
);
1708 ast_sched_del(sched
, pvt
->jbid
);
1712 static int iax2_predestroy(int callno
)
1714 struct ast_channel
*c
;
1715 struct chan_iax2_pvt
*pvt
= iaxs
[callno
];
1719 if (!ast_test_flag(pvt
, IAX_ALREADYGONE
)) {
1720 iax2_destroy_helper(pvt
);
1721 ast_set_flag(pvt
, IAX_ALREADYGONE
);
1725 c
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1727 ast_queue_hangup(c
);
1729 ast_module_unref(ast_module_info
->self
);
1734 static void iax2_destroy(int callno
)
1736 struct chan_iax2_pvt
*pvt
;
1737 struct iax_frame
*cur
;
1738 struct ast_channel
*owner
;
1742 gettimeofday(&lastused
[callno
], NULL
);
1744 owner
= pvt
? pvt
->owner
: NULL
;
1747 if (ast_mutex_trylock(&owner
->lock
)) {
1748 ast_log(LOG_NOTICE
, "Avoiding IAX destroy deadlock\n");
1749 ast_mutex_unlock(&iaxsl
[callno
]);
1751 ast_mutex_lock(&iaxsl
[callno
]);
1756 iaxs
[callno
] = NULL
;
1760 iax2_destroy_helper(pvt
);
1763 ast_set_flag(pvt
, IAX_ALREADYGONE
);
1766 /* If there's an owner, prod it to give up */
1767 owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1768 ast_queue_hangup(owner
);
1771 AST_LIST_LOCK(&iaxq
.queue
);
1772 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
1773 /* Cancel any pending transmissions */
1774 if (cur
->callno
== pvt
->callno
)
1777 AST_LIST_UNLOCK(&iaxq
.queue
);
1780 pvt
->reg
->callno
= 0;
1784 ast_variables_destroy(pvt
->vars
);
1788 while (jb_getall(pvt
->jb
, &frame
) == JB_OK
)
1789 iax2_frame_free(frame
.data
);
1790 jb_destroy(pvt
->jb
);
1791 /* gotta free up the stringfields */
1792 ast_string_field_free_pools(pvt
);
1797 ast_mutex_unlock(&owner
->lock
);
1799 if (callno
& 0x4000)
1803 static int update_packet(struct iax_frame
*f
)
1805 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
1806 struct ast_iax2_full_hdr
*fh
= f
->data
;
1807 /* Mark this as a retransmission */
1808 fh
->dcallno
= ntohs(IAX_FLAG_RETRANS
| f
->dcallno
);
1810 f
->iseqno
= iaxs
[f
->callno
]->iseqno
;
1811 fh
->iseqno
= f
->iseqno
;
1815 static int attempt_transmit(void *data
);
1816 static void __attempt_transmit(void *data
)
1818 /* Attempt to transmit the frame to the remote peer...
1819 Called without iaxsl held. */
1820 struct iax_frame
*f
= data
;
1822 int callno
= f
->callno
;
1823 /* Make sure this call is still active */
1825 ast_mutex_lock(&iaxsl
[callno
]);
1826 if (callno
&& iaxs
[callno
]) {
1827 if ((f
->retries
< 0) /* Already ACK'd */ ||
1828 (f
->retries
>= max_retries
) /* Too many attempts */) {
1829 /* Record an error if we've transmitted too many times */
1830 if (f
->retries
>= max_retries
) {
1832 /* Transfer timeout */
1833 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREJ
, 0, NULL
, 0, -1);
1834 } else if (f
->final
) {
1836 iax2_destroy(callno
);
1838 if (iaxs
[callno
]->owner
)
1839 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
);
1840 iaxs
[callno
]->error
= ETIMEDOUT
;
1841 if (iaxs
[callno
]->owner
) {
1842 struct ast_frame fr
= { 0, };
1844 fr
.frametype
= AST_FRAME_CONTROL
;
1845 fr
.subclass
= AST_CONTROL_HANGUP
;
1846 iax2_queue_frame(callno
, &fr
);
1847 /* Remember, owner could disappear */
1848 if (iaxs
[callno
]->owner
)
1849 iaxs
[callno
]->owner
->hangupcause
= AST_CAUSE_DESTINATION_OUT_OF_ORDER
;
1851 if (iaxs
[callno
]->reg
) {
1852 memset(&iaxs
[callno
]->reg
->us
, 0, sizeof(iaxs
[callno
]->reg
->us
));
1853 iaxs
[callno
]->reg
->regstate
= REG_STATE_TIMEOUT
;
1854 iaxs
[callno
]->reg
->refresh
= IAX_DEFAULT_REG_EXPIRE
;
1856 iax2_destroy(callno
);
1863 /* Update it if it needs it */
1865 /* Attempt transmission */
1868 /* Try again later after 10 times as long */
1870 if (f
->retrytime
> MAX_RETRY_TIME
)
1871 f
->retrytime
= MAX_RETRY_TIME
;
1872 /* Transfer messages max out at one second */
1873 if (f
->transfer
&& (f
->retrytime
> 1000))
1874 f
->retrytime
= 1000;
1875 f
->retrans
= ast_sched_add(sched
, f
->retrytime
, attempt_transmit
, f
);
1878 /* Make sure it gets freed */
1883 ast_mutex_unlock(&iaxsl
[callno
]);
1884 /* Do not try again */
1886 /* Don't attempt delivery, just remove it from the queue */
1887 AST_LIST_LOCK(&iaxq
.queue
);
1888 AST_LIST_REMOVE(&iaxq
.queue
, f
, list
);
1890 AST_LIST_UNLOCK(&iaxq
.queue
);
1892 /* Free the IAX frame */
1897 static int attempt_transmit(void *data
)
1899 #ifdef SCHED_MULTITHREADED
1900 if (schedule_action(__attempt_transmit
, data
))
1902 __attempt_transmit(data
);
1906 static int iax2_prune_realtime(int fd
, int argc
, char *argv
[])
1908 struct iax2_peer
*peer
;
1911 return RESULT_SHOWUSAGE
;
1912 if (!strcmp(argv
[3],"all")) {
1914 ast_cli(fd
, "OK cache is flushed.\n");
1915 } else if ((peer
= find_peer(argv
[3], 0))) {
1916 if(ast_test_flag(peer
, IAX_RTCACHEFRIENDS
)) {
1917 ast_set_flag(peer
, IAX_RTAUTOCLEAR
);
1918 expire_registry((void*)peer
->name
);
1919 ast_cli(fd
, "OK peer %s was removed from the cache.\n", argv
[3]);
1921 ast_cli(fd
, "SORRY peer %s is not eligible for this operation.\n", argv
[3]);
1924 ast_cli(fd
, "SORRY peer %s was not found in the cache.\n", argv
[3]);
1927 return RESULT_SUCCESS
;
1930 static int iax2_test_losspct(int fd
, int argc
, char *argv
[])
1933 return RESULT_SHOWUSAGE
;
1935 test_losspct
= atoi(argv
[3]);
1937 return RESULT_SUCCESS
;
1941 static int iax2_test_late(int fd
, int argc
, char *argv
[])
1944 return RESULT_SHOWUSAGE
;
1946 test_late
= atoi(argv
[3]);
1948 return RESULT_SUCCESS
;
1951 static int iax2_test_resync(int fd
, int argc
, char *argv
[])
1954 return RESULT_SHOWUSAGE
;
1956 test_resync
= atoi(argv
[3]);
1958 return RESULT_SUCCESS
;
1961 static int iax2_test_jitter(int fd
, int argc
, char *argv
[])
1963 if (argc
< 4 || argc
> 5)
1964 return RESULT_SHOWUSAGE
;
1966 test_jit
= atoi(argv
[3]);
1968 test_jitpct
= atoi(argv
[4]);
1970 return RESULT_SUCCESS
;
1972 #endif /* IAXTESTS */
1974 /*! \brief peer_status: Report Peer status in character string */
1975 /* returns 1 if peer is online, -1 if unmonitored */
1976 static int peer_status(struct iax2_peer
*peer
, char *status
, int statuslen
)
1980 if (peer
->lastms
< 0) {
1981 ast_copy_string(status
, "UNREACHABLE", statuslen
);
1982 } else if (peer
->lastms
> peer
->maxms
) {
1983 snprintf(status
, statuslen
, "LAGGED (%d ms)", peer
->lastms
);
1985 } else if (peer
->lastms
) {
1986 snprintf(status
, statuslen
, "OK (%d ms)", peer
->lastms
);
1989 ast_copy_string(status
, "UNKNOWN", statuslen
);
1992 ast_copy_string(status
, "Unmonitored", statuslen
);
1998 /*! \brief Show one peer in detail */
1999 static int iax2_show_peer(int fd
, int argc
, char *argv
[])
2003 struct iax2_peer
*peer
;
2004 char codec_buf
[512];
2005 int x
= 0, codec
= 0, load_realtime
= 0;
2008 return RESULT_SHOWUSAGE
;
2010 load_realtime
= (argc
== 5 && !strcmp(argv
[4], "load")) ? 1 : 0;
2012 peer
= find_peer(argv
[3], load_realtime
);
2015 ast_cli(fd
, " * Name : %s\n", peer
->name
);
2016 ast_cli(fd
, " Secret : %s\n", ast_strlen_zero(peer
->secret
)?"<Not set>":"<Set>");
2017 ast_cli(fd
, " Context : %s\n", peer
->context
);
2018 ast_cli(fd
, " Mailbox : %s\n", peer
->mailbox
);
2019 ast_cli(fd
, " Dynamic : %s\n", ast_test_flag(peer
, IAX_DYNAMIC
) ? "Yes":"No");
2020 ast_cli(fd
, " Callerid : %s\n", ast_callerid_merge(cbuf
, sizeof(cbuf
), peer
->cid_name
, peer
->cid_num
, "<unspecified>"));
2021 ast_cli(fd
, " Expire : %d\n", peer
->expire
);
2022 ast_cli(fd
, " ACL : %s\n", (peer
->ha
?"Yes":"No"));
2023 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
));
2024 ast_cli(fd
, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer
->defaddr
.sin_addr
), ntohs(peer
->defaddr
.sin_port
));
2025 ast_cli(fd
, " Username : %s\n", peer
->username
);
2026 ast_cli(fd
, " Codecs : ");
2027 ast_getformatname_multiple(codec_buf
, sizeof(codec_buf
) -1, peer
->capability
);
2028 ast_cli(fd
, "%s\n", codec_buf
);
2030 ast_cli(fd
, " Codec Order : (");
2031 for(x
= 0; x
< 32 ; x
++) {
2032 codec
= ast_codec_pref_index(&peer
->prefs
,x
);
2035 ast_cli(fd
, "%s", ast_getformatname(codec
));
2036 if(x
< 31 && ast_codec_pref_index(&peer
->prefs
,x
+1))
2041 ast_cli(fd
, "none");
2044 ast_cli(fd
, " Status : ");
2045 peer_status(peer
, status
, sizeof(status
));
2046 ast_cli(fd
, "%s\n",status
);
2047 ast_cli(fd
, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer
->pokefreqok
, peer
->pokefreqnotok
, peer
->smoothing
? "On" : "Off");
2049 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2052 ast_cli(fd
,"Peer %s not found.\n", argv
[3]);
2056 return RESULT_SUCCESS
;
2059 static char *complete_iax2_show_peer(const char *line
, const char *word
, int pos
, int state
)
2062 struct iax2_peer
*p
= NULL
;
2064 int wordlen
= strlen(word
);
2066 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
2068 AST_LIST_LOCK(&peers
);
2069 AST_LIST_TRAVERSE(&peers
, p
, entry
) {
2070 if (!strncasecmp(p
->name
, word
, wordlen
) && ++which
> state
) {
2071 res
= ast_strdup(p
->name
);
2075 AST_LIST_UNLOCK(&peers
);
2081 static int iax2_show_stats(int fd
, int argc
, char *argv
[])
2083 struct iax_frame
*cur
;
2084 int cnt
= 0, dead
=0, final
=0;
2087 return RESULT_SHOWUSAGE
;
2089 AST_LIST_LOCK(&iaxq
.queue
);
2090 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
2091 if (cur
->retries
< 0)
2097 AST_LIST_UNLOCK(&iaxq
.queue
);
2099 ast_cli(fd
, " IAX Statistics\n");
2100 ast_cli(fd
, "---------------------\n");
2101 ast_cli(fd
, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
2102 ast_cli(fd
, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead
, final
, cnt
);
2104 return RESULT_SUCCESS
;
2107 static int iax2_show_cache(int fd
, int argc
, char *argv
[])
2109 struct iax2_dpcache
*dp
;
2110 char tmp
[1024], *pc
;
2114 gettimeofday(&tv
, NULL
);
2115 ast_mutex_lock(&dpcache_lock
);
2117 ast_cli(fd
, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
2119 s
= dp
->expiry
.tv_sec
- tv
.tv_sec
;
2121 if (dp
->flags
& CACHE_FLAG_EXISTS
)
2122 strncat(tmp
, "EXISTS|", sizeof(tmp
) - strlen(tmp
) - 1);
2123 if (dp
->flags
& CACHE_FLAG_NONEXISTENT
)
2124 strncat(tmp
, "NONEXISTENT|", sizeof(tmp
) - strlen(tmp
) - 1);
2125 if (dp
->flags
& CACHE_FLAG_CANEXIST
)
2126 strncat(tmp
, "CANEXIST|", sizeof(tmp
) - strlen(tmp
) - 1);
2127 if (dp
->flags
& CACHE_FLAG_PENDING
)
2128 strncat(tmp
, "PENDING|", sizeof(tmp
) - strlen(tmp
) - 1);
2129 if (dp
->flags
& CACHE_FLAG_TIMEOUT
)
2130 strncat(tmp
, "TIMEOUT|", sizeof(tmp
) - strlen(tmp
) - 1);
2131 if (dp
->flags
& CACHE_FLAG_TRANSMITTED
)
2132 strncat(tmp
, "TRANSMITTED|", sizeof(tmp
) - strlen(tmp
) - 1);
2133 if (dp
->flags
& CACHE_FLAG_MATCHMORE
)
2134 strncat(tmp
, "MATCHMORE|", sizeof(tmp
) - strlen(tmp
) - 1);
2135 if (dp
->flags
& CACHE_FLAG_UNKNOWN
)
2136 strncat(tmp
, "UNKNOWN|", sizeof(tmp
) - strlen(tmp
) - 1);
2137 /* Trim trailing pipe */
2138 if (!ast_strlen_zero(tmp
))
2139 tmp
[strlen(tmp
) - 1] = '\0';
2141 ast_copy_string(tmp
, "(none)", sizeof(tmp
));
2143 pc
= strchr(dp
->peercontext
, '@');
2145 pc
= dp
->peercontext
;
2148 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
2149 if (dp
->waiters
[x
] > -1)
2152 ast_cli(fd
, "%-20.20s %-12.12s %-9d %-8d %s\n", pc
, dp
->exten
, s
, y
, tmp
);
2154 ast_cli(fd
, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc
, dp
->exten
, "(expired)", y
, tmp
);
2157 ast_mutex_unlock(&dpcache_lock
);
2158 return RESULT_SUCCESS
;
2161 static unsigned int calc_rxstamp(struct chan_iax2_pvt
*p
, unsigned int offset
);
2163 static void unwrap_timestamp(struct iax_frame
*fr
)
2167 if ( (fr
->ts
& 0xFFFF0000) == (iaxs
[fr
->callno
]->last
& 0xFFFF0000) ) {
2168 x
= fr
->ts
- iaxs
[fr
->callno
]->last
;
2170 /* Sudden big jump backwards in timestamp:
2171 What likely happened here is that miniframe timestamp has circled but we haven't
2172 gotten the update from the main packet. We'll just pretend that we did, and
2173 update the timestamp appropriately. */
2174 fr
->ts
= ( (iaxs
[fr
->callno
]->last
& 0xFFFF0000) + 0x10000) | (fr
->ts
& 0xFFFF);
2175 if (option_debug
&& iaxdebug
)
2176 ast_log(LOG_DEBUG
, "schedule_delivery: pushed forward timestamp\n");
2179 /* Sudden apparent big jump forwards in timestamp:
2180 What's likely happened is this is an old miniframe belonging to the previous
2181 top-16-bit timestamp that has turned up out of order.
2182 Adjust the timestamp appropriately. */
2183 fr
->ts
= ( (iaxs
[fr
->callno
]->last
& 0xFFFF0000) - 0x10000) | (fr
->ts
& 0xFFFF);
2184 if (option_debug
&& iaxdebug
)
2185 ast_log(LOG_DEBUG
, "schedule_delivery: pushed back timestamp\n");
2190 static int get_from_jb(void *p
);
2192 static void update_jbsched(struct chan_iax2_pvt
*pvt
)
2196 when
= ast_tvdiff_ms(ast_tvnow(), pvt
->rxcore
);
2198 when
= jb_next(pvt
->jb
) - when
;
2200 if(pvt
->jbid
> -1) ast_sched_del(sched
, pvt
->jbid
);
2203 /* XXX should really just empty until when > 0.. */
2207 pvt
->jbid
= ast_sched_add(sched
, when
, get_from_jb
, CALLNO_TO_PTR(pvt
->callno
));
2209 /* Signal scheduler thread */
2210 signal_condition(&sched_lock
, &sched_cond
);
2213 static void __get_from_jb(void *p
)
2215 int callno
= PTR_TO_CALLNO(p
);
2216 struct chan_iax2_pvt
*pvt
= NULL
;
2217 struct iax_frame
*fr
;
2224 /* Make sure we have a valid private structure before going on */
2225 ast_mutex_lock(&iaxsl
[callno
]);
2229 ast_mutex_unlock(&iaxsl
[callno
]);
2235 gettimeofday(&tv
,NULL
);
2236 /* round up a millisecond since ast_sched_runq does; */
2237 /* prevents us from spinning while waiting for our now */
2238 /* to catch up with runq's now */
2241 now
= ast_tvdiff_ms(tv
, pvt
->rxcore
);
2243 if(now
>= (next
= jb_next(pvt
->jb
))) {
2244 ret
= jb_get(pvt
->jb
,&frame
,now
,ast_codec_interp_len(pvt
->voiceformat
));
2252 struct ast_frame af
= { 0, };
2254 /* create an interpolation frame */
2255 af
.frametype
= AST_FRAME_VOICE
;
2256 af
.subclass
= pvt
->voiceformat
;
2257 af
.samples
= frame
.ms
* 8;
2258 af
.src
= "IAX2 JB interpolation";
2259 af
.delivery
= ast_tvadd(pvt
->rxcore
, ast_samp2tv(next
, 1000));
2260 af
.offset
= AST_FRIENDLY_OFFSET
;
2262 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
2263 * which we'd need to malloc, and then it would free it. That seems like a drag */
2264 if (!ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
))
2265 iax2_queue_frame(callno
, &af
);
2269 iax2_frame_free(frame
.data
);
2276 /* shouldn't happen */
2280 update_jbsched(pvt
);
2281 ast_mutex_unlock(&iaxsl
[callno
]);
2284 static int get_from_jb(void *data
)
2286 #ifdef SCHED_MULTITHREADED
2287 if (schedule_action(__get_from_jb
, data
))
2289 __get_from_jb(data
);
2293 static int schedule_delivery(struct iax_frame
*fr
, int updatehistory
, int fromtrunk
, unsigned int *tsout
)
2299 /* Attempt to recover wrapped timestamps */
2300 unwrap_timestamp(fr
);
2303 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
2304 if ( !fromtrunk
&& !ast_tvzero(iaxs
[fr
->callno
]->rxcore
))
2305 fr
->af
.delivery
= ast_tvadd(iaxs
[fr
->callno
]->rxcore
, ast_samp2tv(fr
->ts
, 1000));
2308 ast_log(LOG_DEBUG
, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
2310 fr
->af
.delivery
= ast_tv(0,0);
2313 type
= JB_TYPE_CONTROL
;
2316 if(fr
->af
.frametype
== AST_FRAME_VOICE
) {
2317 type
= JB_TYPE_VOICE
;
2318 len
= ast_codec_get_samples(&fr
->af
) / 8;
2319 } else if(fr
->af
.frametype
== AST_FRAME_CNG
) {
2320 type
= JB_TYPE_SILENCE
;
2323 if ( (!ast_test_flag(iaxs
[fr
->callno
], IAX_USEJITTERBUF
)) ) {
2330 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
2331 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
2332 if( (!ast_test_flag(iaxs
[fr
->callno
], IAX_FORCEJITTERBUF
)) &&
2333 iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
) &&
2334 (ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->tech
->properties
& AST_CHAN_TP_WANTSJITTER
)) {
2337 /* deliver any frames in the jb */
2338 while(jb_getall(iaxs
[fr
->callno
]->jb
,&frame
) == JB_OK
)
2339 __do_deliver(frame
.data
);
2341 jb_reset(iaxs
[fr
->callno
]->jb
);
2343 if (iaxs
[fr
->callno
]->jbid
> -1)
2344 ast_sched_del(sched
, iaxs
[fr
->callno
]->jbid
);
2346 iaxs
[fr
->callno
]->jbid
= -1;
2348 /* deliver this frame now */
2355 /* insert into jitterbuffer */
2356 /* TODO: Perhaps we could act immediately if it's not droppable and late */
2357 ret
= jb_put(iaxs
[fr
->callno
]->jb
, fr
, type
, len
, fr
->ts
,
2358 calc_rxstamp(iaxs
[fr
->callno
],fr
->ts
));
2359 if (ret
== JB_DROP
) {
2361 } else if (ret
== JB_SCHED
) {
2362 update_jbsched(iaxs
[fr
->callno
]);
2367 /* Free our iax frame */
2368 iax2_frame_free(fr
);
2374 static int iax2_transmit(struct iax_frame
*fr
)
2376 /* Lock the queue and place this packet at the end */
2377 /* By setting this to 0, the network thread will send it for us, and
2378 queue retransmission if necessary */
2380 AST_LIST_LOCK(&iaxq
.queue
);
2381 AST_LIST_INSERT_TAIL(&iaxq
.queue
, fr
, list
);
2383 AST_LIST_UNLOCK(&iaxq
.queue
);
2384 /* Wake up the network and scheduler thread */
2385 if (netthreadid
!= AST_PTHREADT_NULL
)
2386 pthread_kill(netthreadid
, SIGURG
);
2387 signal_condition(&sched_lock
, &sched_cond
);
2393 static int iax2_digit_begin(struct ast_channel
*c
, char digit
)
2395 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_DTMF_BEGIN
, digit
, 0, NULL
, 0, -1);
2398 static int iax2_digit_end(struct ast_channel
*c
, char digit
, unsigned int duration
)
2400 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_DTMF_END
, digit
, 0, NULL
, 0, -1);
2403 static int iax2_sendtext(struct ast_channel
*c
, const char *text
)
2406 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_TEXT
,
2407 0, 0, (unsigned char *)text
, strlen(text
) + 1, -1);
2410 static int iax2_sendimage(struct ast_channel
*c
, struct ast_frame
*img
)
2412 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_IMAGE
, img
->subclass
, 0, img
->data
, img
->datalen
, -1);
2415 static int iax2_sendhtml(struct ast_channel
*c
, int subclass
, const char *data
, int datalen
)
2417 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_HTML
, subclass
, 0, (unsigned char *)data
, datalen
, -1);
2420 static int iax2_fixup(struct ast_channel
*oldchannel
, struct ast_channel
*newchan
)
2422 unsigned short callno
= PTR_TO_CALLNO(newchan
->tech_pvt
);
2423 ast_mutex_lock(&iaxsl
[callno
]);
2425 iaxs
[callno
]->owner
= newchan
;
2427 ast_log(LOG_WARNING
, "Uh, this isn't a good sign...\n");
2428 ast_mutex_unlock(&iaxsl
[callno
]);
2432 static struct iax2_peer
*realtime_peer(const char *peername
, struct sockaddr_in
*sin
)
2434 struct ast_variable
*var
;
2435 struct ast_variable
*tmp
;
2436 struct iax2_peer
*peer
=NULL
;
2437 time_t regseconds
= 0, nowtime
;
2441 var
= ast_load_realtime("iaxpeers", "name", peername
, NULL
);
2444 sprintf(porta
, "%d", ntohs(sin
->sin_port
));
2445 var
= ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin
->sin_addr
), "port", porta
, NULL
);
2447 /* We'll need the peer name in order to build the structure! */
2448 for (tmp
= var
; tmp
; tmp
= tmp
->next
) {
2449 if (!strcasecmp(tmp
->name
, "name"))
2450 peername
= tmp
->value
;
2457 peer
= build_peer(peername
, var
, NULL
, ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
) ? 0 : 1);
2460 ast_variables_destroy(var
);
2464 for (tmp
= var
; tmp
; tmp
= tmp
->next
) {
2465 /* Make sure it's not a user only... */
2466 if (!strcasecmp(tmp
->name
, "type")) {
2467 if (strcasecmp(tmp
->value
, "friend") &&
2468 strcasecmp(tmp
->value
, "peer")) {
2469 /* Whoops, we weren't supposed to exist! */
2474 } else if (!strcasecmp(tmp
->name
, "regseconds")) {
2475 ast_get_time_t(tmp
->value
, ®seconds
, 0, NULL
);
2476 } else if (!strcasecmp(tmp
->name
, "ipaddr")) {
2477 inet_aton(tmp
->value
, &(peer
->addr
.sin_addr
));
2478 } else if (!strcasecmp(tmp
->name
, "port")) {
2479 peer
->addr
.sin_port
= htons(atoi(tmp
->value
));
2480 } else if (!strcasecmp(tmp
->name
, "host")) {
2481 if (!strcasecmp(tmp
->value
, "dynamic"))
2486 ast_variables_destroy(var
);
2491 if (ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
)) {
2492 ast_copy_flags(peer
, &globalflags
, IAX_RTAUTOCLEAR
|IAX_RTCACHEFRIENDS
);
2493 if (ast_test_flag(peer
, IAX_RTAUTOCLEAR
)) {
2494 if (peer
->expire
> -1)
2495 ast_sched_del(sched
, peer
->expire
);
2496 peer
->expire
= ast_sched_add(sched
, (global_rtautoclear
) * 1000, expire_registry
, (void*)peer
->name
);
2498 AST_LIST_LOCK(&peers
);
2499 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
2500 AST_LIST_UNLOCK(&peers
);
2501 if (ast_test_flag(peer
, IAX_DYNAMIC
))
2502 reg_source_db(peer
);
2504 ast_set_flag(peer
, IAX_TEMPONLY
);
2507 if (!ast_test_flag(&globalflags
, IAX_RTIGNOREREGEXPIRE
) && dynamic
) {
2509 if ((nowtime
- regseconds
) > IAX_DEFAULT_REG_EXPIRE
) {
2510 memset(&peer
->addr
, 0, sizeof(peer
->addr
));
2511 realtime_update_peer(peer
->name
, &peer
->addr
, 0);
2513 ast_log(LOG_DEBUG
, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
2514 peername
, (int)(nowtime
- regseconds
), (int)regseconds
, (int)nowtime
);
2518 ast_log(LOG_DEBUG
, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
2519 peername
, (int)(nowtime
- regseconds
), (int)regseconds
, (int)nowtime
);
2526 static struct iax2_user
*realtime_user(const char *username
)
2528 struct ast_variable
*var
;
2529 struct ast_variable
*tmp
;
2530 struct iax2_user
*user
=NULL
;
2532 var
= ast_load_realtime("iaxusers", "name", username
, NULL
);
2538 /* Make sure it's not a peer only... */
2539 if (!strcasecmp(tmp
->name
, "type")) {
2540 if (strcasecmp(tmp
->value
, "friend") &&
2541 strcasecmp(tmp
->value
, "user")) {
2548 user
= build_user(username
, var
, NULL
, !ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
));
2550 ast_variables_destroy(var
);
2555 if (ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
)) {
2556 ast_set_flag(user
, IAX_RTCACHEFRIENDS
);
2557 AST_LIST_LOCK(&users
);
2558 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
2559 AST_LIST_UNLOCK(&users
);
2561 ast_set_flag(user
, IAX_TEMPONLY
);
2567 static void realtime_update_peer(const char *peername
, struct sockaddr_in
*sin
, time_t regtime
)
2570 char regseconds
[20];
2572 snprintf(regseconds
, sizeof(regseconds
), "%d", (int)regtime
);
2573 snprintf(port
, sizeof(port
), "%d", ntohs(sin
->sin_port
));
2574 ast_update_realtime("iaxpeers", "name", peername
,
2575 "ipaddr", ast_inet_ntoa(sin
->sin_addr
), "port", port
,
2576 "regseconds", regseconds
, NULL
);
2579 struct create_addr_info
{
2592 char context
[AST_MAX_CONTEXT
];
2593 char peercontext
[AST_MAX_CONTEXT
];
2594 char mohinterpret
[MAX_MUSICCLASS
];
2595 char mohsuggest
[MAX_MUSICCLASS
];
2598 static int create_addr(const char *peername
, struct sockaddr_in
*sin
, struct create_addr_info
*cai
)
2600 struct ast_hostent ahp
;
2602 struct iax2_peer
*peer
;
2604 ast_clear_flag(cai
, IAX_SENDANI
| IAX_TRUNK
);
2605 cai
->sockfd
= defaultsockfd
;
2607 sin
->sin_family
= AF_INET
;
2609 if (!(peer
= find_peer(peername
, 1))) {
2612 hp
= ast_gethostbyname(peername
, &ahp
);
2614 memcpy(&sin
->sin_addr
, hp
->h_addr
, sizeof(sin
->sin_addr
));
2615 sin
->sin_port
= htons(IAX_DEFAULT_PORTNO
);
2616 /* use global iax prefs for unknown peer/user */
2617 ast_codec_pref_convert(&prefs
, cai
->prefs
, sizeof(cai
->prefs
), 1);
2620 ast_log(LOG_WARNING
, "No such host: %s\n", peername
);
2627 /* if the peer has no address (current or default), return failure */
2628 if (!(peer
->addr
.sin_addr
.s_addr
|| peer
->defaddr
.sin_addr
.s_addr
)) {
2629 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2634 /* if the peer is being monitored and is currently unreachable, return failure */
2635 if (peer
->maxms
&& ((peer
->lastms
> peer
->maxms
) || (peer
->lastms
< 0))) {
2636 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2641 ast_copy_flags(cai
, peer
, IAX_SENDANI
| IAX_TRUNK
| IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
2642 cai
->maxtime
= peer
->maxms
;
2643 cai
->capability
= peer
->capability
;
2644 cai
->encmethods
= peer
->encmethods
;
2645 cai
->sockfd
= peer
->sockfd
;
2646 cai
->adsi
= peer
->adsi
;
2647 ast_codec_pref_convert(&peer
->prefs
, cai
->prefs
, sizeof(cai
->prefs
), 1);
2648 ast_copy_string(cai
->context
, peer
->context
, sizeof(cai
->context
));
2649 ast_copy_string(cai
->peercontext
, peer
->peercontext
, sizeof(cai
->peercontext
));
2650 ast_copy_string(cai
->username
, peer
->username
, sizeof(cai
->username
));
2651 ast_copy_string(cai
->timezone
, peer
->zonetag
, sizeof(cai
->timezone
));
2652 ast_copy_string(cai
->outkey
, peer
->outkey
, sizeof(cai
->outkey
));
2653 ast_copy_string(cai
->mohinterpret
, peer
->mohinterpret
, sizeof(cai
->mohinterpret
));
2654 ast_copy_string(cai
->mohsuggest
, peer
->mohsuggest
, sizeof(cai
->mohsuggest
));
2655 if (ast_strlen_zero(peer
->dbsecret
)) {
2656 ast_copy_string(cai
->secret
, peer
->secret
, sizeof(cai
->secret
));
2661 family
= ast_strdupa(peer
->dbsecret
);
2662 key
= strchr(family
, '/');
2665 if (!key
|| ast_db_get(family
, key
, cai
->secret
, sizeof(cai
->secret
))) {
2666 ast_log(LOG_WARNING
, "Unable to retrieve database password for family/key '%s'!\n", peer
->dbsecret
);
2667 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2673 if (peer
->addr
.sin_addr
.s_addr
) {
2674 sin
->sin_addr
= peer
->addr
.sin_addr
;
2675 sin
->sin_port
= peer
->addr
.sin_port
;
2677 sin
->sin_addr
= peer
->defaddr
.sin_addr
;
2678 sin
->sin_port
= peer
->defaddr
.sin_port
;
2681 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2687 static void __auto_congest(void *nothing
)
2689 int callno
= PTR_TO_CALLNO(nothing
);
2690 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_CONGESTION
};
2691 ast_mutex_lock(&iaxsl
[callno
]);
2693 iaxs
[callno
]->initid
= -1;
2694 iax2_queue_frame(callno
, &f
);
2695 ast_log(LOG_NOTICE
, "Auto-congesting call due to slow response\n");
2697 ast_mutex_unlock(&iaxsl
[callno
]);
2700 static int auto_congest(void *data
)
2702 #ifdef SCHED_MULTITHREADED
2703 if (schedule_action(__auto_congest
, data
))
2705 __auto_congest(data
);
2709 static unsigned int iax2_datetime(const char *tz
)
2715 localtime_r(&t
, &tm
);
2716 if (!ast_strlen_zero(tz
))
2717 ast_localtime(&t
, &tm
, tz
);
2718 tmp
= (tm
.tm_sec
>> 1) & 0x1f; /* 5 bits of seconds */
2719 tmp
|= (tm
.tm_min
& 0x3f) << 5; /* 6 bits of minutes */
2720 tmp
|= (tm
.tm_hour
& 0x1f) << 11; /* 5 bits of hours */
2721 tmp
|= (tm
.tm_mday
& 0x1f) << 16; /* 5 bits of day of month */
2722 tmp
|= ((tm
.tm_mon
+ 1) & 0xf) << 21; /* 4 bits of month */
2723 tmp
|= ((tm
.tm_year
- 100) & 0x7f) << 25; /* 7 bits of year */
2727 struct parsed_dial_string
{
2739 * \brief Parses an IAX dial string into its component parts.
2740 * \param data the string to be parsed
2741 * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
2744 * This function parses the string and fills the structure
2745 * with pointers to its component parts. The input string
2748 * \note This function supports both plaintext passwords and RSA
2749 * key names; if the password string is formatted as '[keyname]',
2750 * then the keyname will be placed into the key field, and the
2751 * password field will be set to NULL.
2753 * \note The dial string format is:
2754 * [username[:password]@]peer[:port][/exten[@@context]][/options]
2756 static void parse_dial_string(char *data
, struct parsed_dial_string
*pds
)
2758 if (ast_strlen_zero(data
))
2761 pds
->peer
= strsep(&data
, "/");
2762 pds
->exten
= strsep(&data
, "/");
2763 pds
->options
= data
;
2767 pds
->exten
= strsep(&data
, "@");
2768 pds
->context
= data
;
2771 if (strchr(pds
->peer
, '@')) {
2773 pds
->username
= strsep(&data
, "@");
2777 if (pds
->username
) {
2778 data
= pds
->username
;
2779 pds
->username
= strsep(&data
, ":");
2780 pds
->password
= data
;
2784 pds
->peer
= strsep(&data
, ":");
2787 /* check for a key name wrapped in [] in the secret position, if found,
2788 move it to the key field instead
2790 if (pds
->password
&& (pds
->password
[0] == '[')) {
2791 pds
->key
= ast_strip_quoted(pds
->password
, "[", "]");
2792 pds
->password
= NULL
;
2796 static int iax2_call(struct ast_channel
*c
, char *dest
, int timeout
)
2798 struct sockaddr_in sin
;
2799 char *l
=NULL
, *n
=NULL
, *tmpstr
;
2800 struct iax_ie_data ied
;
2801 char *defaultrdest
= "s";
2802 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
2803 struct parsed_dial_string pds
;
2804 struct create_addr_info cai
;
2806 if ((c
->_state
!= AST_STATE_DOWN
) && (c
->_state
!= AST_STATE_RESERVED
)) {
2807 ast_log(LOG_WARNING
, "Channel is already in use (%s)?\n", c
->name
);
2811 memset(&cai
, 0, sizeof(cai
));
2812 cai
.encmethods
= iax2_encryption
;
2814 memset(&pds
, 0, sizeof(pds
));
2815 tmpstr
= ast_strdupa(dest
);
2816 parse_dial_string(tmpstr
, &pds
);
2819 pds
.exten
= defaultrdest
;
2821 if (create_addr(pds
.peer
, &sin
, &cai
)) {
2822 ast_log(LOG_WARNING
, "No address associated with '%s'\n", pds
.peer
);
2826 if (!pds
.username
&& !ast_strlen_zero(cai
.username
))
2827 pds
.username
= cai
.username
;
2828 if (!pds
.password
&& !ast_strlen_zero(cai
.secret
))
2829 pds
.password
= cai
.secret
;
2830 if (!pds
.key
&& !ast_strlen_zero(cai
.outkey
))
2831 pds
.key
= cai
.outkey
;
2832 if (!pds
.context
&& !ast_strlen_zero(cai
.peercontext
))
2833 pds
.context
= cai
.peercontext
;
2835 /* Keep track of the context for outgoing calls too */
2836 ast_copy_string(c
->context
, cai
.context
, sizeof(c
->context
));
2839 sin
.sin_port
= htons(atoi(pds
.port
));
2842 n
= c
->cid
.cid_name
;
2844 /* Now build request */
2845 memset(&ied
, 0, sizeof(ied
));
2847 /* On new call, first IE MUST be IAX version of caller */
2848 iax_ie_append_short(&ied
, IAX_IE_VERSION
, IAX_PROTO_VERSION
);
2849 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, pds
.exten
);
2850 if (pds
.options
&& strchr(pds
.options
, 'a')) {
2851 /* Request auto answer */
2852 iax_ie_append(&ied
, IAX_IE_AUTOANSWER
);
2855 iax_ie_append_str(&ied
, IAX_IE_CODEC_PREFS
, cai
.prefs
);
2858 iax_ie_append_str(&ied
, IAX_IE_CALLING_NUMBER
, l
);
2859 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, c
->cid
.cid_pres
);
2862 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, c
->cid
.cid_pres
);
2864 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, AST_PRES_NUMBER_NOT_AVAILABLE
);
2867 iax_ie_append_byte(&ied
, IAX_IE_CALLINGTON
, c
->cid
.cid_ton
);
2868 iax_ie_append_short(&ied
, IAX_IE_CALLINGTNS
, c
->cid
.cid_tns
);
2871 iax_ie_append_str(&ied
, IAX_IE_CALLING_NAME
, n
);
2872 if (ast_test_flag(iaxs
[callno
], IAX_SENDANI
) && c
->cid
.cid_ani
)
2873 iax_ie_append_str(&ied
, IAX_IE_CALLING_ANI
, c
->cid
.cid_ani
);
2875 if (!ast_strlen_zero(c
->language
))
2876 iax_ie_append_str(&ied
, IAX_IE_LANGUAGE
, c
->language
);
2877 if (!ast_strlen_zero(c
->cid
.cid_dnid
))
2878 iax_ie_append_str(&ied
, IAX_IE_DNID
, c
->cid
.cid_dnid
);
2879 if (!ast_strlen_zero(c
->cid
.cid_rdnis
))
2880 iax_ie_append_str(&ied
, IAX_IE_RDNIS
, c
->cid
.cid_rdnis
);
2883 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, pds
.context
);
2886 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, pds
.username
);
2889 iax_ie_append_short(&ied
, IAX_IE_ENCRYPTION
, cai
.encmethods
);
2891 ast_mutex_lock(&iaxsl
[callno
]);
2893 if (!ast_strlen_zero(c
->context
))
2894 ast_string_field_set(iaxs
[callno
], context
, c
->context
);
2897 ast_string_field_set(iaxs
[callno
], username
, pds
.username
);
2899 iaxs
[callno
]->encmethods
= cai
.encmethods
;
2901 iaxs
[callno
]->adsi
= cai
.adsi
;
2903 ast_string_field_set(iaxs
[callno
], mohinterpret
, cai
.mohinterpret
);
2904 ast_string_field_set(iaxs
[callno
], mohsuggest
, cai
.mohsuggest
);
2907 ast_string_field_set(iaxs
[callno
], outkey
, pds
.key
);
2909 ast_string_field_set(iaxs
[callno
], secret
, pds
.password
);
2911 iax_ie_append_int(&ied
, IAX_IE_FORMAT
, c
->nativeformats
);
2912 iax_ie_append_int(&ied
, IAX_IE_CAPABILITY
, iaxs
[callno
]->capability
);
2913 iax_ie_append_short(&ied
, IAX_IE_ADSICPE
, c
->adsicpe
);
2914 iax_ie_append_int(&ied
, IAX_IE_DATETIME
, iax2_datetime(cai
.timezone
));
2916 if (iaxs
[callno
]->maxtime
) {
2917 /* Initialize pingtime and auto-congest time */
2918 iaxs
[callno
]->pingtime
= iaxs
[callno
]->maxtime
/ 2;
2919 iaxs
[callno
]->initid
= ast_sched_add(sched
, iaxs
[callno
]->maxtime
* 2, auto_congest
, CALLNO_TO_PTR(callno
));
2920 } else if (autokill
) {
2921 iaxs
[callno
]->pingtime
= autokill
/ 2;
2922 iaxs
[callno
]->initid
= ast_sched_add(sched
, autokill
* 2, auto_congest
, CALLNO_TO_PTR(callno
));
2925 /* send the command using the appropriate socket for this peer */
2926 iaxs
[callno
]->sockfd
= cai
.sockfd
;
2928 /* Transmit the string in a "NEW" request */
2929 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_NEW
, 0, ied
.buf
, ied
.pos
, -1);
2931 ast_mutex_unlock(&iaxsl
[callno
]);
2932 ast_setstate(c
, AST_STATE_RINGING
);
2937 static int iax2_hangup(struct ast_channel
*c
)
2939 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
2941 struct iax_ie_data ied
;
2942 memset(&ied
, 0, sizeof(ied
));
2943 ast_mutex_lock(&iaxsl
[callno
]);
2944 if (callno
&& iaxs
[callno
]) {
2945 ast_log(LOG_DEBUG
, "We're hanging up %s now...\n", c
->name
);
2946 alreadygone
= ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
);
2947 /* Send the hangup unless we have had a transmission error or are already gone */
2948 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, (unsigned char)c
->hangupcause
);
2949 if (!iaxs
[callno
]->error
&& !alreadygone
)
2950 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_HANGUP
, 0, ied
.buf
, ied
.pos
, -1);
2951 /* Explicitly predestroy it */
2952 iax2_predestroy(callno
);
2953 /* If we were already gone to begin with, destroy us now */
2955 ast_log(LOG_DEBUG
, "Really destroying %s now...\n", c
->name
);
2956 iax2_destroy(callno
);
2959 ast_mutex_unlock(&iaxsl
[callno
]);
2960 if (option_verbose
> 2)
2961 ast_verbose(VERBOSE_PREFIX_3
"Hungup '%s'\n", c
->name
);
2965 static int iax2_setoption(struct ast_channel
*c
, int option
, void *data
, int datalen
)
2967 struct ast_option_header
*h
;
2971 case AST_OPTION_TXGAIN
:
2972 case AST_OPTION_RXGAIN
:
2973 /* these two cannot be sent, because they require a result */
2977 if (!(h
= ast_malloc(datalen
+ sizeof(*h
))))
2980 h
->flag
= AST_OPTION_FLAG_REQUEST
;
2981 h
->option
= htons(option
);
2982 memcpy(h
->data
, data
, datalen
);
2983 res
= send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_CONTROL
,
2984 AST_CONTROL_OPTION
, 0, (unsigned char *) h
,
2985 datalen
+ sizeof(*h
), -1);
2991 static struct ast_frame
*iax2_read(struct ast_channel
*c
)
2993 ast_log(LOG_NOTICE
, "I should never be called!\n");
2994 return &ast_null_frame
;
2997 static int iax2_start_transfer(unsigned short callno0
, unsigned short callno1
, int mediaonly
)
3000 struct iax_ie_data ied0
;
3001 struct iax_ie_data ied1
;
3002 unsigned int transferid
= (unsigned int)ast_random();
3003 memset(&ied0
, 0, sizeof(ied0
));
3004 iax_ie_append_addr(&ied0
, IAX_IE_APPARENT_ADDR
, &iaxs
[callno1
]->addr
);
3005 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[callno1
]->peercallno
);
3006 iax_ie_append_int(&ied0
, IAX_IE_TRANSFERID
, transferid
);
3008 memset(&ied1
, 0, sizeof(ied1
));
3009 iax_ie_append_addr(&ied1
, IAX_IE_APPARENT_ADDR
, &iaxs
[callno0
]->addr
);
3010 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[callno0
]->peercallno
);
3011 iax_ie_append_int(&ied1
, IAX_IE_TRANSFERID
, transferid
);
3013 res
= send_command(iaxs
[callno0
], AST_FRAME_IAX
, IAX_COMMAND_TXREQ
, 0, ied0
.buf
, ied0
.pos
, -1);
3016 res
= send_command(iaxs
[callno1
], AST_FRAME_IAX
, IAX_COMMAND_TXREQ
, 0, ied1
.buf
, ied1
.pos
, -1);
3019 iaxs
[callno0
]->transferring
= mediaonly
? TRANSFER_MBEGIN
: TRANSFER_BEGIN
;
3020 iaxs
[callno1
]->transferring
= mediaonly
? TRANSFER_MBEGIN
: TRANSFER_BEGIN
;
3024 static void lock_both(unsigned short callno0
, unsigned short callno1
)
3026 ast_mutex_lock(&iaxsl
[callno0
]);
3027 while (ast_mutex_trylock(&iaxsl
[callno1
])) {
3028 ast_mutex_unlock(&iaxsl
[callno0
]);
3030 ast_mutex_lock(&iaxsl
[callno0
]);
3034 static void unlock_both(unsigned short callno0
, unsigned short callno1
)
3036 ast_mutex_unlock(&iaxsl
[callno1
]);
3037 ast_mutex_unlock(&iaxsl
[callno0
]);
3040 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
)
3042 struct ast_channel
*cs
[3];
3043 struct ast_channel
*who
, *other
;
3046 int transferstarted
=0;
3047 struct ast_frame
*f
;
3048 unsigned short callno0
= PTR_TO_CALLNO(c0
->tech_pvt
);
3049 unsigned short callno1
= PTR_TO_CALLNO(c1
->tech_pvt
);
3050 struct timeval waittimer
= {0, 0}, tv
;
3052 lock_both(callno0
, callno1
);
3053 /* Put them in native bridge mode */
3054 if (!flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
)) {
3055 iaxs
[callno0
]->bridgecallno
= callno1
;
3056 iaxs
[callno1
]->bridgecallno
= callno0
;
3058 unlock_both(callno0
, callno1
);
3060 /* If not, try to bridge until we can execute a transfer, if we can */
3063 for (/* ever */;;) {
3064 /* Check in case we got masqueraded into */
3065 if ((c0
->tech
!= &iax2_tech
) || (c1
->tech
!= &iax2_tech
)) {
3066 if (option_verbose
> 2)
3067 ast_verbose(VERBOSE_PREFIX_3
"Can't masquerade, we're different...\n");
3068 /* Remove from native mode */
3069 if (c0
->tech
== &iax2_tech
) {
3070 ast_mutex_lock(&iaxsl
[callno0
]);
3071 iaxs
[callno0
]->bridgecallno
= 0;
3072 ast_mutex_unlock(&iaxsl
[callno0
]);
3074 if (c1
->tech
== &iax2_tech
) {
3075 ast_mutex_lock(&iaxsl
[callno1
]);
3076 iaxs
[callno1
]->bridgecallno
= 0;
3077 ast_mutex_unlock(&iaxsl
[callno1
]);
3079 return AST_BRIDGE_FAILED_NOWARN
;
3081 if (c0
->nativeformats
!= c1
->nativeformats
) {
3082 if (option_verbose
> 2) {
3085 ast_getformatname_multiple(buf0
, sizeof(buf0
) -1, c0
->nativeformats
);
3086 ast_getformatname_multiple(buf1
, sizeof(buf1
) -1, c1
->nativeformats
);
3087 ast_verbose(VERBOSE_PREFIX_3
"Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0
->nativeformats
, buf0
, c1
->nativeformats
, buf1
);
3089 /* Remove from native mode */
3090 lock_both(callno0
, callno1
);
3091 iaxs
[callno0
]->bridgecallno
= 0;
3092 iaxs
[callno1
]->bridgecallno
= 0;
3093 unlock_both(callno0
, callno1
);
3094 return AST_BRIDGE_FAILED_NOWARN
;
3096 /* check if transfered and if we really want native bridging */
3097 if (!transferstarted
&& !ast_test_flag(iaxs
[callno0
], IAX_NOTRANSFER
) && !ast_test_flag(iaxs
[callno1
], IAX_NOTRANSFER
)) {
3098 /* Try the transfer */
3099 if (iax2_start_transfer(callno0
, callno1
, (flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
)) ||
3100 ast_test_flag(iaxs
[callno0
], IAX_TRANSFERMEDIA
) | ast_test_flag(iaxs
[callno1
], IAX_TRANSFERMEDIA
)))
3101 ast_log(LOG_WARNING
, "Unable to start the transfer\n");
3102 transferstarted
= 1;
3104 if ((iaxs
[callno0
]->transferring
== TRANSFER_RELEASED
) && (iaxs
[callno1
]->transferring
== TRANSFER_RELEASED
)) {
3105 /* Call has been transferred. We're no longer involved */
3106 gettimeofday(&tv
, NULL
);
3107 if (ast_tvzero(waittimer
)) {
3109 } else if (tv
.tv_sec
- waittimer
.tv_sec
> IAX_LINGER_TIMEOUT
) {
3110 c0
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3111 c1
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3114 res
= AST_BRIDGE_COMPLETE
;
3119 who
= ast_waitfor_n(cs
, 2, &to
);
3120 if (timeoutms
> -1) {
3121 timeoutms
-= (1000 - to
);
3127 res
= AST_BRIDGE_RETRY
;
3130 if (ast_check_hangup(c0
) || ast_check_hangup(c1
)) {
3131 res
= AST_BRIDGE_FAILED
;
3140 res
= AST_BRIDGE_COMPLETE
;
3143 if ((f
->frametype
== AST_FRAME_CONTROL
) && !(flags
& AST_BRIDGE_IGNORE_SIGS
)) {
3146 res
= AST_BRIDGE_COMPLETE
;
3149 other
= (who
== c0
) ? c1
: c0
; /* the 'other' channel */
3150 if ((f
->frametype
== AST_FRAME_VOICE
) ||
3151 (f
->frametype
== AST_FRAME_TEXT
) ||
3152 (f
->frametype
== AST_FRAME_VIDEO
) ||
3153 (f
->frametype
== AST_FRAME_IMAGE
) ||
3154 (f
->frametype
== AST_FRAME_DTMF
)) {
3155 /* monitored dtmf take out of the bridge.
3156 * check if we monitor the specific source.
3158 int monitored_source
= (who
== c0
) ? AST_BRIDGE_DTMF_CHANNEL_0
: AST_BRIDGE_DTMF_CHANNEL_1
;
3159 if (f
->frametype
== AST_FRAME_DTMF
&& (flags
& monitored_source
)) {
3162 res
= AST_BRIDGE_COMPLETE
;
3163 /* Remove from native mode */
3166 /* everything else goes to the other side */
3167 ast_write(other
, f
);
3170 /* Swap who gets priority */
3175 lock_both(callno0
, callno1
);
3177 iaxs
[callno0
]->bridgecallno
= 0;
3179 iaxs
[callno1
]->bridgecallno
= 0;
3180 unlock_both(callno0
, callno1
);
3184 static int iax2_answer(struct ast_channel
*c
)
3186 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3188 ast_log(LOG_DEBUG
, "Answering IAX2 call\n");
3189 return send_command_locked(callno
, AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
, 0, NULL
, 0, -1);
3192 static int iax2_indicate(struct ast_channel
*c
, int condition
, const void *data
, size_t datalen
)
3194 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3195 struct chan_iax2_pvt
*pvt
;
3198 if (option_debug
&& iaxdebug
)
3199 ast_log(LOG_DEBUG
, "Indicating condition %d\n", condition
);
3201 ast_mutex_lock(&iaxsl
[callno
]);
3203 if (!strcasecmp(pvt
->mohinterpret
, "passthrough")) {
3204 res
= send_command(pvt
, AST_FRAME_CONTROL
, condition
, 0, data
, datalen
, -1);
3205 ast_mutex_unlock(&iaxsl
[callno
]);
3209 switch (condition
) {
3210 case AST_CONTROL_HOLD
:
3211 ast_moh_start(c
, data
, pvt
->mohinterpret
);
3213 case AST_CONTROL_UNHOLD
:
3217 res
= send_command(pvt
, AST_FRAME_CONTROL
, condition
, 0, data
, datalen
, -1);
3220 ast_mutex_unlock(&iaxsl
[callno
]);
3225 static int iax2_transfer(struct ast_channel
*c
, const char *dest
)
3227 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3228 struct iax_ie_data ied
;
3229 char tmp
[256], *context
;
3230 ast_copy_string(tmp
, dest
, sizeof(tmp
));
3231 context
= strchr(tmp
, '@');
3236 memset(&ied
, 0, sizeof(ied
));
3237 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, tmp
);
3239 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, context
);
3241 ast_log(LOG_DEBUG
, "Transferring '%s' to '%s'\n", c
->name
, dest
);
3242 return send_command_locked(callno
, AST_FRAME_IAX
, IAX_COMMAND_TRANSFER
, 0, ied
.buf
, ied
.pos
, -1);
3245 static int iax2_getpeertrunk(struct sockaddr_in sin
)
3247 struct iax2_peer
*peer
= NULL
;
3250 AST_LIST_LOCK(&peers
);
3251 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
3252 if ((peer
->addr
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
) &&
3253 (peer
->addr
.sin_port
== sin
.sin_port
)) {
3254 res
= ast_test_flag(peer
, IAX_TRUNK
);
3258 AST_LIST_UNLOCK(&peers
);
3263 /*! \brief Create new call, interface with the PBX core */
3264 static struct ast_channel
*ast_iax2_new(int callno
, int state
, int capability
, unsigned int delaypbx
)
3266 struct ast_channel
*tmp
;
3267 struct chan_iax2_pvt
*i
;
3268 struct ast_variable
*v
= NULL
;
3270 if (!(i
= iaxs
[callno
])) {
3271 ast_log(LOG_WARNING
, "No IAX2 pvt found for callno '%d' !\n", callno
);
3275 /* Don't hold call lock */
3276 ast_mutex_unlock(&iaxsl
[callno
]);
3277 tmp
= ast_channel_alloc(1, state
, i
->cid_num
, i
->cid_name
, i
->accountcode
, i
->exten
, i
->context
, i
->amaflags
, "IAX2/%s-%d", i
->host
, i
->callno
);
3278 ast_mutex_lock(&iaxsl
[callno
]);
3281 tmp
->tech
= &iax2_tech
;
3282 /* We can support any format by default, until we get restricted */
3283 tmp
->nativeformats
= capability
;
3284 tmp
->readformat
= ast_best_codec(capability
);
3285 tmp
->writeformat
= ast_best_codec(capability
);
3286 tmp
->tech_pvt
= CALLNO_TO_PTR(i
->callno
);
3288 /* Don't use ast_set_callerid() here because it will
3289 * generate a NewCallerID event before the NewChannel event */
3290 tmp
->cid
.cid_num
= ast_strdup(i
->cid_num
);
3291 tmp
->cid
.cid_name
= ast_strdup(i
->cid_name
);
3292 if (!ast_strlen_zero(i
->ani
))
3293 tmp
->cid
.cid_ani
= ast_strdup(i
->ani
);
3295 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_num
);
3296 tmp
->cid
.cid_dnid
= ast_strdup(i
->dnid
);
3297 tmp
->cid
.cid_rdnis
= ast_strdup(i
->rdnis
);
3298 tmp
->cid
.cid_pres
= i
->calling_pres
;
3299 tmp
->cid
.cid_ton
= i
->calling_ton
;
3300 tmp
->cid
.cid_tns
= i
->calling_tns
;
3301 if (!ast_strlen_zero(i
->language
))
3302 ast_string_field_set(tmp
, language
, i
->language
);
3303 if (!ast_strlen_zero(i
->accountcode
))
3304 ast_string_field_set(tmp
, accountcode
, i
->accountcode
);
3306 tmp
->amaflags
= i
->amaflags
;
3307 ast_copy_string(tmp
->context
, i
->context
, sizeof(tmp
->context
));
3308 ast_copy_string(tmp
->exten
, i
->exten
, sizeof(tmp
->exten
));
3310 tmp
->adsicpe
= i
->peeradsicpe
;
3312 tmp
->adsicpe
= AST_ADSI_UNAVAILABLE
;
3314 i
->capability
= capability
;
3316 for (v
= i
->vars
; v
; v
= v
->next
)
3317 pbx_builtin_setvar_helper(tmp
, v
->name
, v
->value
);
3320 ast_set_flag(i
, IAX_DELAYPBXSTART
);
3321 } else if (state
!= AST_STATE_DOWN
) {
3322 if (ast_pbx_start(tmp
)) {
3323 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", tmp
->name
);
3330 ast_module_ref(ast_module_info
->self
);
3335 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer
*tpeer
, int sampms
, struct timeval
*tv
)
3337 unsigned long int mssincetx
; /* unsigned to handle overflows */
3340 tpeer
->trunkact
= *tv
;
3341 mssincetx
= ast_tvdiff_ms(*tv
, tpeer
->lasttxtime
);
3342 if (mssincetx
> 5000 || ast_tvzero(tpeer
->txtrunktime
)) {
3343 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
3344 tpeer
->txtrunktime
= *tv
;
3345 tpeer
->lastsent
= 999999;
3347 /* Update last transmit time now */
3348 tpeer
->lasttxtime
= *tv
;
3350 /* Calculate ms offset */
3351 ms
= ast_tvdiff_ms(*tv
, tpeer
->txtrunktime
);
3352 /* Predict from last value */
3353 pred
= tpeer
->lastsent
+ sampms
;
3354 if (abs(ms
- pred
) < MAX_TIMESTAMP_SKEW
)
3357 /* We never send the same timestamp twice, so fudge a little if we must */
3358 if (ms
== tpeer
->lastsent
)
3359 ms
= tpeer
->lastsent
+ 1;
3360 tpeer
->lastsent
= ms
;
3364 static unsigned int fix_peerts(struct timeval
*tv
, int callno
, unsigned int ts
)
3366 long ms
; /* NOT unsigned */
3367 if (ast_tvzero(iaxs
[callno
]->rxcore
)) {
3368 /* Initialize rxcore time if appropriate */
3369 gettimeofday(&iaxs
[callno
]->rxcore
, NULL
);
3370 /* Round to nearest 20ms so traces look pretty */
3371 iaxs
[callno
]->rxcore
.tv_usec
-= iaxs
[callno
]->rxcore
.tv_usec
% 20000;
3373 /* Calculate difference between trunk and channel */
3374 ms
= ast_tvdiff_ms(*tv
, iaxs
[callno
]->rxcore
);
3375 /* Return as the sum of trunk time and the difference between trunk and real time */
3379 static unsigned int calc_timestamp(struct chan_iax2_pvt
*p
, unsigned int ts
, struct ast_frame
*f
)
3385 struct timeval
*delivery
= NULL
;
3388 /* What sort of frame do we have?: voice is self-explanatory
3389 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
3390 non-genuine frames are CONTROL frames [ringing etc], DTMF
3391 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
3392 the others need a timestamp slaved to the voice frames so that they go in sequence
3395 if (f
->frametype
== AST_FRAME_VOICE
) {
3397 delivery
= &f
->delivery
;
3398 } else if (f
->frametype
== AST_FRAME_IAX
) {
3400 } else if (f
->frametype
== AST_FRAME_CNG
) {
3404 if (ast_tvzero(p
->offset
)) {
3405 gettimeofday(&p
->offset
, NULL
);
3406 /* Round to nearest 20ms for nice looking traces */
3407 p
->offset
.tv_usec
-= p
->offset
.tv_usec
% 20000;
3409 /* If the timestamp is specified, just send it as is */
3412 /* If we have a time that the frame arrived, always use it to make our timestamp */
3413 if (delivery
&& !ast_tvzero(*delivery
)) {
3414 ms
= ast_tvdiff_ms(*delivery
, p
->offset
);
3415 if (option_debug
> 2 && iaxdebug
)
3416 ast_log(LOG_DEBUG
, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p
->callno
, iaxs
[p
->callno
]->peercallno
);
3418 ms
= ast_tvdiff_ms(ast_tvnow(), p
->offset
);
3422 /* On a voice frame, use predicted values if appropriate */
3423 if (p
->notsilenttx
&& abs(ms
- p
->nextpred
) <= MAX_TIMESTAMP_SKEW
) {
3424 /* Adjust our txcore, keeping voice and non-voice synchronized */
3426 When we send voice, we usually send "calculated" timestamps worked out
3427 on the basis of the number of samples sent. When we send other frames,
3428 we usually send timestamps worked out from the real clock.
3429 The problem is that they can tend to drift out of step because the
3430 source channel's clock and our clock may not be exactly at the same rate.
3431 We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
3432 for this call. Moving it adjusts timestamps for non-voice frames.
3433 We make the adjustment in the style of a moving average. Each time we
3434 adjust p->offset by 10% of the difference between our clock-derived
3435 timestamp and the predicted timestamp. That's why you see "10000"
3436 below even though IAX2 timestamps are in milliseconds.
3437 The use of a moving average avoids offset moving too radically.
3438 Generally, "adjust" roams back and forth around 0, with offset hardly
3439 changing at all. But if a consistent different starts to develop it
3440 will be eliminated over the course of 10 frames (200-300msecs)
3442 adjust
= (ms
- p
->nextpred
);
3444 p
->offset
= ast_tvsub(p
->offset
, ast_samp2tv(abs(adjust
), 10000));
3445 else if (adjust
> 0)
3446 p
->offset
= ast_tvadd(p
->offset
, ast_samp2tv(adjust
, 10000));
3449 p
->nextpred
= ms
; /*f->samples / 8;*/
3450 if (p
->nextpred
<= p
->lastsent
)
3451 p
->nextpred
= p
->lastsent
+ 3;
3455 /* in this case, just use the actual
3456 * time, since we're either way off
3457 * (shouldn't happen), or we're ending a
3458 * silent period -- and seed the next
3459 * predicted time. Also, round ms to the
3460 * next multiple of frame size (so our
3461 * silent periods are multiples of
3462 * frame size too) */
3464 if (iaxdebug
&& abs(ms
- p
->nextpred
) > MAX_TIMESTAMP_SKEW
)
3465 ast_log(LOG_DEBUG
, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
3466 abs(ms
- p
->nextpred
), MAX_TIMESTAMP_SKEW
);
3468 if (f
->samples
>= 8) /* check to make sure we dont core dump */
3470 int diff
= ms
% (f
->samples
/ 8);
3472 ms
+= f
->samples
/8 - diff
;
3479 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
3480 it's a genuine frame */
3482 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
3483 if (ms
<= p
->lastsent
)
3484 ms
= p
->lastsent
+ 3;
3485 } else if (abs(ms
- p
->lastsent
) <= MAX_TIMESTAMP_SKEW
) {
3486 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
3487 ms
= p
->lastsent
+ 3;
3493 p
->nextpred
= p
->nextpred
+ f
->samples
/ 8;
3497 static unsigned int calc_rxstamp(struct chan_iax2_pvt
*p
, unsigned int offset
)
3499 /* Returns where in "receive time" we are. That is, how many ms
3500 since we received (or would have received) the frame with timestamp 0 */
3504 #endif /* IAXTESTS */
3505 /* Setup rxcore if necessary */
3506 if (ast_tvzero(p
->rxcore
)) {
3507 p
->rxcore
= ast_tvnow();
3508 if (option_debug
&& iaxdebug
)
3509 ast_log(LOG_DEBUG
, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
3510 p
->callno
, (int)(p
->rxcore
.tv_sec
), (int)(p
->rxcore
.tv_usec
), offset
);
3511 p
->rxcore
= ast_tvsub(p
->rxcore
, ast_samp2tv(offset
, 1000));
3513 if (option_debug
&& iaxdebug
)
3514 ast_log(LOG_DEBUG
, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
3515 p
->callno
, (int)(p
->rxcore
.tv_sec
),(int)( p
->rxcore
.tv_usec
));
3519 ms
= ast_tvdiff_ms(ast_tvnow(), p
->rxcore
);
3522 if (!test_jitpct
|| ((100.0 * ast_random() / (RAND_MAX
+ 1.0)) < test_jitpct
)) {
3523 jit
= (int)((float)test_jit
* ast_random() / (RAND_MAX
+ 1.0));
3524 if ((int)(2.0 * ast_random() / (RAND_MAX
+ 1.0)))
3533 #endif /* IAXTESTS */
3537 static struct iax2_trunk_peer
*find_tpeer(struct sockaddr_in
*sin
, int fd
)
3539 struct iax2_trunk_peer
*tpeer
;
3541 /* Finds and locks trunk peer */
3542 ast_mutex_lock(&tpeerlock
);
3543 for (tpeer
= tpeers
; tpeer
; tpeer
= tpeer
->next
) {
3544 /* We don't lock here because tpeer->addr *never* changes */
3545 if (!inaddrcmp(&tpeer
->addr
, sin
)) {
3546 ast_mutex_lock(&tpeer
->lock
);
3551 if ((tpeer
= ast_calloc(1, sizeof(*tpeer
)))) {
3552 ast_mutex_init(&tpeer
->lock
);
3553 tpeer
->lastsent
= 9999;
3554 memcpy(&tpeer
->addr
, sin
, sizeof(tpeer
->addr
));
3555 tpeer
->trunkact
= ast_tvnow();
3556 ast_mutex_lock(&tpeer
->lock
);
3557 tpeer
->next
= tpeers
;
3561 setsockopt(tpeer
->sockfd
, SOL_SOCKET
, SO_NO_CHECK
, &nochecksums
, sizeof(nochecksums
));
3563 ast_log(LOG_DEBUG
, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer
->addr
.sin_addr
), ntohs(tpeer
->addr
.sin_port
));
3566 ast_mutex_unlock(&tpeerlock
);
3570 static int iax2_trunk_queue(struct chan_iax2_pvt
*pvt
, struct iax_frame
*fr
)
3572 struct ast_frame
*f
;
3573 struct iax2_trunk_peer
*tpeer
;
3575 struct ast_iax2_meta_trunk_entry
*met
;
3576 struct ast_iax2_meta_trunk_mini
*mtm
;
3579 tpeer
= find_tpeer(&pvt
->addr
, pvt
->sockfd
);
3581 if (tpeer
->trunkdatalen
+ f
->datalen
+ 4 >= tpeer
->trunkdataalloc
) {
3582 /* Need to reallocate space */
3583 if (tpeer
->trunkdataalloc
< MAX_TRUNKDATA
) {
3584 if (!(tmp
= ast_realloc(tpeer
->trunkdata
, tpeer
->trunkdataalloc
+ DEFAULT_TRUNKDATA
+ IAX2_TRUNK_PREFACE
))) {
3585 ast_mutex_unlock(&tpeer
->lock
);
3589 tpeer
->trunkdataalloc
+= DEFAULT_TRUNKDATA
;
3590 tpeer
->trunkdata
= tmp
;
3591 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
);
3593 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
));
3594 ast_mutex_unlock(&tpeer
->lock
);
3599 /* Append to meta frame */
3600 ptr
= tpeer
->trunkdata
+ IAX2_TRUNK_PREFACE
+ tpeer
->trunkdatalen
;
3601 if (ast_test_flag(&globalflags
, IAX_TRUNKTIMESTAMPS
)) {
3602 mtm
= (struct ast_iax2_meta_trunk_mini
*)ptr
;
3603 mtm
->len
= htons(f
->datalen
);
3604 mtm
->mini
.callno
= htons(pvt
->callno
);
3605 mtm
->mini
.ts
= htons(0xffff & fr
->ts
);
3606 ptr
+= sizeof(struct ast_iax2_meta_trunk_mini
);
3607 tpeer
->trunkdatalen
+= sizeof(struct ast_iax2_meta_trunk_mini
);
3609 met
= (struct ast_iax2_meta_trunk_entry
*)ptr
;
3610 /* Store call number and length in meta header */
3611 met
->callno
= htons(pvt
->callno
);
3612 met
->len
= htons(f
->datalen
);
3613 /* Advance pointers/decrease length past trunk entry header */
3614 ptr
+= sizeof(struct ast_iax2_meta_trunk_entry
);
3615 tpeer
->trunkdatalen
+= sizeof(struct ast_iax2_meta_trunk_entry
);
3617 /* Copy actual trunk data */
3618 memcpy(ptr
, f
->data
, f
->datalen
);
3619 tpeer
->trunkdatalen
+= f
->datalen
;
3622 ast_mutex_unlock(&tpeer
->lock
);
3627 static void build_enc_keys(const unsigned char *digest
, aes_encrypt_ctx
*ecx
, aes_decrypt_ctx
*dcx
)
3629 aes_encrypt_key128(digest
, ecx
);
3630 aes_decrypt_key128(digest
, dcx
);
3633 static void memcpy_decrypt(unsigned char *dst
, const unsigned char *src
, int len
, aes_decrypt_ctx
*dcx
)
3636 /* Debug with "fake encryption" */
3639 ast_log(LOG_WARNING
, "len should be multiple of 16, not %d!\n", len
);
3641 dst
[x
] = src
[x
] ^ 0xff;
3643 unsigned char lastblock
[16] = { 0 };
3646 aes_decrypt(src
, dst
, dcx
);
3648 dst
[x
] ^= lastblock
[x
];
3649 memcpy(lastblock
, src
, sizeof(lastblock
));
3657 static void memcpy_encrypt(unsigned char *dst
, const unsigned char *src
, int len
, aes_encrypt_ctx
*ecx
)
3660 /* Debug with "fake encryption" */
3663 ast_log(LOG_WARNING
, "len should be multiple of 16, not %d!\n", len
);
3665 dst
[x
] = src
[x
] ^ 0xff;
3667 unsigned char curblock
[16] = { 0 };
3671 curblock
[x
] ^= src
[x
];
3672 aes_encrypt(curblock
, dst
, ecx
);
3673 memcpy(curblock
, dst
, sizeof(curblock
));
3681 static int decode_frame(aes_decrypt_ctx
*dcx
, struct ast_iax2_full_hdr
*fh
, struct ast_frame
*f
, int *datalen
)
3684 unsigned char *workspace
;
3686 workspace
= alloca(*datalen
);
3687 memset(f
, 0, sizeof(*f
));
3688 if (ntohs(fh
->scallno
) & IAX_FLAG_FULL
) {
3689 struct ast_iax2_full_enc_hdr
*efh
= (struct ast_iax2_full_enc_hdr
*)fh
;
3690 if (*datalen
< 16 + sizeof(struct ast_iax2_full_hdr
))
3693 memcpy_decrypt(workspace
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
), dcx
);
3695 padding
= 16 + (workspace
[15] & 0xf);
3696 if (option_debug
&& iaxdebug
)
3697 ast_log(LOG_DEBUG
, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen
, padding
, workspace
[15]);
3698 if (*datalen
< padding
+ sizeof(struct ast_iax2_full_hdr
))
3701 *datalen
-= padding
;
3702 memcpy(efh
->encdata
, workspace
+ padding
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
));
3703 f
->frametype
= fh
->type
;
3704 if (f
->frametype
== AST_FRAME_VIDEO
) {
3705 f
->subclass
= uncompress_subclass(fh
->csub
& ~0x40) | ((fh
->csub
>> 6) & 0x1);
3707 f
->subclass
= uncompress_subclass(fh
->csub
);
3710 struct ast_iax2_mini_enc_hdr
*efh
= (struct ast_iax2_mini_enc_hdr
*)fh
;
3711 if (option_debug
&& iaxdebug
)
3712 ast_log(LOG_DEBUG
, "Decoding mini with length %d\n", *datalen
);
3713 if (*datalen
< 16 + sizeof(struct ast_iax2_mini_hdr
))
3716 memcpy_decrypt(workspace
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
), dcx
);
3717 padding
= 16 + (workspace
[15] & 0x0f);
3718 if (*datalen
< padding
+ sizeof(struct ast_iax2_mini_hdr
))
3720 *datalen
-= padding
;
3721 memcpy(efh
->encdata
, workspace
+ padding
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
));
3726 static int encrypt_frame(aes_encrypt_ctx
*ecx
, struct ast_iax2_full_hdr
*fh
, unsigned char *poo
, int *datalen
)
3729 unsigned char *workspace
;
3730 workspace
= alloca(*datalen
+ 32);
3733 if (ntohs(fh
->scallno
) & IAX_FLAG_FULL
) {
3734 struct ast_iax2_full_enc_hdr
*efh
= (struct ast_iax2_full_enc_hdr
*)fh
;
3735 if (option_debug
&& iaxdebug
)
3736 ast_log(LOG_DEBUG
, "Encoding full frame %d/%d with length %d\n", fh
->type
, fh
->csub
, *datalen
);
3737 padding
= 16 - ((*datalen
- sizeof(struct ast_iax2_full_enc_hdr
)) % 16);
3738 padding
= 16 + (padding
& 0xf);
3739 memcpy(workspace
, poo
, padding
);
3740 memcpy(workspace
+ padding
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
));
3741 workspace
[15] &= 0xf0;
3742 workspace
[15] |= (padding
& 0xf);
3743 if (option_debug
&& iaxdebug
)
3744 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]);
3745 *datalen
+= padding
;
3746 memcpy_encrypt(efh
->encdata
, workspace
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
), ecx
);
3747 if (*datalen
>= 32 + sizeof(struct ast_iax2_full_enc_hdr
))
3748 memcpy(poo
, workspace
+ *datalen
- 32, 32);
3750 struct ast_iax2_mini_enc_hdr
*efh
= (struct ast_iax2_mini_enc_hdr
*)fh
;
3751 if (option_debug
&& iaxdebug
)
3752 ast_log(LOG_DEBUG
, "Encoding mini frame with length %d\n", *datalen
);
3753 padding
= 16 - ((*datalen
- sizeof(struct ast_iax2_mini_enc_hdr
)) % 16);
3754 padding
= 16 + (padding
& 0xf);
3755 memcpy(workspace
, poo
, padding
);
3756 memcpy(workspace
+ padding
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
));
3757 workspace
[15] &= 0xf0;
3758 workspace
[15] |= (padding
& 0x0f);
3759 *datalen
+= padding
;
3760 memcpy_encrypt(efh
->encdata
, workspace
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
), ecx
);
3761 if (*datalen
>= 32 + sizeof(struct ast_iax2_mini_enc_hdr
))
3762 memcpy(poo
, workspace
+ *datalen
- 32, 32);
3767 static int decrypt_frame(int callno
, struct ast_iax2_full_hdr
*fh
, struct ast_frame
*f
, int *datalen
)
3770 if (!ast_test_flag(iaxs
[callno
], IAX_KEYPOPULATED
)) {
3771 /* Search for possible keys, given secrets */
3772 struct MD5Context md5
;
3773 unsigned char digest
[16];
3774 char *tmppw
, *stringp
;
3776 tmppw
= ast_strdupa(iaxs
[callno
]->secret
);
3778 while ((tmppw
= strsep(&stringp
, ";"))) {
3780 MD5Update(&md5
, (unsigned char *)iaxs
[callno
]->challenge
, strlen(iaxs
[callno
]->challenge
));
3781 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
3782 MD5Final(digest
, &md5
);
3783 build_enc_keys(digest
, &iaxs
[callno
]->ecx
, &iaxs
[callno
]->dcx
);
3784 res
= decode_frame(&iaxs
[callno
]->dcx
, fh
, f
, datalen
);
3786 ast_set_flag(iaxs
[callno
], IAX_KEYPOPULATED
);
3791 res
= decode_frame(&iaxs
[callno
]->dcx
, fh
, f
, datalen
);
3795 static int iax2_send(struct chan_iax2_pvt
*pvt
, struct ast_frame
*f
, unsigned int ts
, int seqno
, int now
, int transfer
, int final
)
3797 /* Queue a packet for delivery on a given private structure. Use "ts" for
3798 timestamp, or calculate if ts is 0. Send immediately without retransmission
3799 or delayed, with retransmission */
3800 struct ast_iax2_full_hdr
*fh
;
3801 struct ast_iax2_mini_hdr
*mh
;
3802 struct ast_iax2_video_hdr
*vh
;
3804 struct iax_frame fr2
;
3805 unsigned char buffer
[4096];
3807 struct iax_frame
*fr
;
3810 unsigned int lastsent
;
3814 ast_log(LOG_WARNING
, "No private structure for packet?\n");
3818 lastsent
= pvt
->lastsent
;
3820 /* Calculate actual timestamp */
3821 fts
= calc_timestamp(pvt
, ts
, f
);
3823 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
3824 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
3825 * increment the "predicted timestamps" for voice, if we're predecting */
3826 if(f
->frametype
== AST_FRAME_VOICE
&& f
->datalen
== 0)
3830 if ((ast_test_flag(pvt
, IAX_TRUNK
) ||
3831 (((fts
& 0xFFFF0000L
) == (lastsent
& 0xFFFF0000L
)) ||
3832 ((fts
& 0xFFFF0000L
) == ((lastsent
+ 0x10000) & 0xFFFF0000L
))))
3833 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
3834 (f
->frametype
== AST_FRAME_VOICE
)
3835 /* is a voice frame */ &&
3836 (f
->subclass
== pvt
->svoiceformat
)
3837 /* is the same type */ ) {
3838 /* Force immediate rather than delayed transmission */
3840 /* Mark that mini-style frame is appropriate */
3843 if (((fts
& 0xFFFF8000L
) == (lastsent
& 0xFFFF8000L
)) &&
3844 (f
->frametype
== AST_FRAME_VIDEO
) &&
3845 ((f
->subclass
& ~0x1) == pvt
->svideoformat
)) {
3849 /* Allocate an iax_frame */
3853 fr
= iax_frame_new(DIRECTION_OUTGRESS
, ast_test_flag(pvt
, IAX_ENCRYPTED
) ? f
->datalen
+ 32 : f
->datalen
, (f
->frametype
== AST_FRAME_VOICE
) || (f
->frametype
== AST_FRAME_VIDEO
));
3855 ast_log(LOG_WARNING
, "Out of memory\n");
3858 /* Copy our prospective frame into our immediate or retransmitted wrapper */
3859 iax_frame_wrap(fr
, f
);
3862 fr
->callno
= pvt
->callno
;
3863 fr
->transfer
= transfer
;
3866 /* We need a full frame */
3870 fr
->oseqno
= pvt
->oseqno
++;
3871 fr
->iseqno
= pvt
->iseqno
;
3872 fh
= (struct ast_iax2_full_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_full_hdr
));
3873 fh
->scallno
= htons(fr
->callno
| IAX_FLAG_FULL
);
3874 fh
->ts
= htonl(fr
->ts
);
3875 fh
->oseqno
= fr
->oseqno
;
3879 fh
->iseqno
= fr
->iseqno
;
3880 /* Keep track of the last thing we've acknowledged */
3882 pvt
->aseqno
= fr
->iseqno
;
3883 fh
->type
= fr
->af
.frametype
& 0xFF;
3884 if (fr
->af
.frametype
== AST_FRAME_VIDEO
)
3885 fh
->csub
= compress_subclass(fr
->af
.subclass
& ~0x1) | ((fr
->af
.subclass
& 0x1) << 6);
3887 fh
->csub
= compress_subclass(fr
->af
.subclass
);
3889 fr
->dcallno
= pvt
->transfercallno
;
3891 fr
->dcallno
= pvt
->peercallno
;
3892 fh
->dcallno
= htons(fr
->dcallno
);
3893 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_full_hdr
);
3896 /* Retry after 2x the ping time has passed */
3897 fr
->retrytime
= pvt
->pingtime
* 2;
3898 if (fr
->retrytime
< MIN_RETRY_TIME
)
3899 fr
->retrytime
= MIN_RETRY_TIME
;
3900 if (fr
->retrytime
> MAX_RETRY_TIME
)
3901 fr
->retrytime
= MAX_RETRY_TIME
;
3902 /* Acks' don't get retried */
3903 if ((f
->frametype
== AST_FRAME_IAX
) && (f
->subclass
== IAX_COMMAND_ACK
))
3905 else if (f
->frametype
== AST_FRAME_VOICE
)
3906 pvt
->svoiceformat
= f
->subclass
;
3907 else if (f
->frametype
== AST_FRAME_VIDEO
)
3908 pvt
->svideoformat
= f
->subclass
& ~0x1;
3909 if (ast_test_flag(pvt
, IAX_ENCRYPTED
)) {
3910 if (ast_test_flag(pvt
, IAX_KEYPOPULATED
)) {
3913 iax_showframe(fr
, NULL
, 2, &pvt
->transfer
, fr
->datalen
- sizeof(struct ast_iax2_full_hdr
));
3915 iax_showframe(fr
, NULL
, 2, &pvt
->addr
, fr
->datalen
- sizeof(struct ast_iax2_full_hdr
));
3917 encrypt_frame(&pvt
->ecx
, fh
, pvt
->semirand
, &fr
->datalen
);
3919 ast_log(LOG_WARNING
, "Supposed to send packet encrypted, but no key?\n");
3923 res
= send_packet(fr
);
3925 res
= iax2_transmit(fr
);
3927 if (ast_test_flag(pvt
, IAX_TRUNK
)) {
3928 iax2_trunk_queue(pvt
, fr
);
3930 } else if (fr
->af
.frametype
== AST_FRAME_VIDEO
) {
3931 /* Video frame have no sequence number */
3934 vh
= (struct ast_iax2_video_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_video_hdr
));
3936 vh
->callno
= htons(0x8000 | fr
->callno
);
3937 vh
->ts
= htons((fr
->ts
& 0x7FFF) | (fr
->af
.subclass
& 0x1 ? 0x8000 : 0));
3938 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_video_hdr
);
3941 res
= send_packet(fr
);
3943 /* Mini-frames have no sequence number */
3946 /* Mini frame will do */
3947 mh
= (struct ast_iax2_mini_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_mini_hdr
));
3948 mh
->callno
= htons(fr
->callno
);
3949 mh
->ts
= htons(fr
->ts
& 0xFFFF);
3950 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_mini_hdr
);
3953 if (pvt
->transferring
== TRANSFER_MEDIAPASS
)
3955 if (ast_test_flag(pvt
, IAX_ENCRYPTED
)) {
3956 if (ast_test_flag(pvt
, IAX_KEYPOPULATED
)) {
3957 encrypt_frame(&pvt
->ecx
, (struct ast_iax2_full_hdr
*)mh
, pvt
->semirand
, &fr
->datalen
);
3959 ast_log(LOG_WARNING
, "Supposed to send packet encrypted, but no key?\n");
3961 res
= send_packet(fr
);
3967 static int iax2_show_users(int fd
, int argc
, char *argv
[])
3970 int havepattern
= 0;
3972 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
3973 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
3975 struct iax2_user
*user
= NULL
;
3981 if (!strcasecmp(argv
[3], "like")) {
3982 if (regcomp(®exbuf
, argv
[4], REG_EXTENDED
| REG_NOSUB
))
3983 return RESULT_SHOWUSAGE
;
3986 return RESULT_SHOWUSAGE
;
3990 return RESULT_SHOWUSAGE
;
3993 ast_cli(fd
, FORMAT
, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
3994 AST_LIST_LOCK(&users
);
3995 AST_LIST_TRAVERSE(&users
, user
, entry
) {
3996 if (havepattern
&& regexec(®exbuf
, user
->name
, 0, NULL
, 0))
3999 if (!ast_strlen_zero(user
->secret
)) {
4000 ast_copy_string(auth
,user
->secret
,sizeof(auth
));
4001 } else if (!ast_strlen_zero(user
->inkeys
)) {
4002 snprintf(auth
, sizeof(auth
), "Key: %-15.15s ", user
->inkeys
);
4004 ast_copy_string(auth
, "-no secret-", sizeof(auth
));
4006 if(ast_test_flag(user
,IAX_CODEC_NOCAP
))
4008 else if(ast_test_flag(user
,IAX_CODEC_NOPREFS
))
4011 pstr
= ast_test_flag(user
,IAX_CODEC_USER_FIRST
) ? "Caller" : "Host";
4013 ast_cli(fd
, FORMAT2
, user
->name
, auth
, user
->authmethods
,
4014 user
->contexts
? user
->contexts
->context
: context
,
4015 user
->ha
? "Yes" : "No", pstr
);
4018 AST_LIST_UNLOCK(&users
);
4023 return RESULT_SUCCESS
;
4028 static int __iax2_show_peers(int manager
, int fd
, struct mansession
*s
, int argc
, char *argv
[])
4031 int havepattern
= 0;
4032 int total_peers
= 0;
4033 int online_peers
= 0;
4034 int offline_peers
= 0;
4035 int unmonitored_peers
= 0;
4037 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
4038 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
4040 struct iax2_peer
*peer
= NULL
;
4042 int registeredonly
=0;
4043 char *term
= manager
? "\r\n" : "\n";
4047 if (!strcasecmp(argv
[3], "registered"))
4050 return RESULT_SHOWUSAGE
;
4051 if (!strcasecmp(argv
[4], "like")) {
4052 if (regcomp(®exbuf
, argv
[5], REG_EXTENDED
| REG_NOSUB
))
4053 return RESULT_SHOWUSAGE
;
4056 return RESULT_SHOWUSAGE
;
4059 if (!strcasecmp(argv
[3], "like")) {
4060 if (regcomp(®exbuf
, argv
[4], REG_EXTENDED
| REG_NOSUB
))
4061 return RESULT_SHOWUSAGE
;
4064 return RESULT_SHOWUSAGE
;
4067 if (!strcasecmp(argv
[3], "registered"))
4070 return RESULT_SHOWUSAGE
;
4075 return RESULT_SHOWUSAGE
;
4080 astman_append(s
, FORMAT2
, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term
);
4082 ast_cli(fd
, FORMAT2
, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term
);
4084 AST_LIST_LOCK(&peers
);
4085 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
4091 if (registeredonly
&& !peer
->addr
.sin_addr
.s_addr
)
4093 if (havepattern
&& regexec(®exbuf
, peer
->name
, 0, NULL
, 0))
4096 if (!ast_strlen_zero(peer
->username
))
4097 snprintf(name
, sizeof(name
), "%s/%s", peer
->name
, peer
->username
);
4099 ast_copy_string(name
, peer
->name
, sizeof(name
));
4101 retstatus
= peer_status(peer
, status
, sizeof(status
));
4104 else if (!retstatus
)
4107 unmonitored_peers
++;
4109 ast_copy_string(nm
, ast_inet_ntoa(peer
->mask
), sizeof(nm
));
4111 snprintf(srch
, sizeof(srch
), FORMAT
, name
,
4112 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "(Unspecified)",
4113 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4115 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4116 peer
->encmethods
? "(E)" : " ", status
, term
);
4119 astman_append(s
, FORMAT
, name
,
4120 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa( peer
->addr
.sin_addr
) : "(Unspecified)",
4121 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4123 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4124 peer
->encmethods
? "(E)" : " ", status
, term
);
4126 ast_cli(fd
, FORMAT
, name
,
4127 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "(Unspecified)",
4128 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4130 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4131 peer
->encmethods
? "(E)" : " ", status
, term
);
4134 AST_LIST_UNLOCK(&peers
);
4137 astman_append(s
,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers
, online_peers
, offline_peers
, unmonitored_peers
, term
);
4139 ast_cli(fd
,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers
, online_peers
, offline_peers
, unmonitored_peers
, term
);
4144 return RESULT_SUCCESS
;
4149 static int iax2_show_threads(int fd
, int argc
, char *argv
[])
4151 struct iax2_thread
*thread
= NULL
;
4153 int threadcount
= 0, dynamiccount
= 0;
4157 return RESULT_SHOWUSAGE
;
4159 ast_cli(fd
, "IAX2 Thread Information\n");
4161 ast_cli(fd
, "Idle Threads:\n");
4162 AST_LIST_LOCK(&idle_list
);
4163 AST_LIST_TRAVERSE(&idle_list
, thread
, list
) {
4164 #ifdef DEBUG_SCHED_MULTITHREAD
4165 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4166 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4168 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d\n",
4169 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4173 AST_LIST_UNLOCK(&idle_list
);
4174 ast_cli(fd
, "Active Threads:\n");
4175 AST_LIST_LOCK(&active_list
);
4176 AST_LIST_TRAVERSE(&active_list
, thread
, list
) {
4177 if (thread
->type
== IAX_TYPE_DYNAMIC
)
4181 #ifdef DEBUG_SCHED_MULTITHREAD
4182 ast_cli(fd
, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
4183 type
, thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4185 ast_cli(fd
, "Thread %c%d: state=%d, update=%d, actions=%d\n",
4186 type
, thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4190 AST_LIST_UNLOCK(&active_list
);
4191 ast_cli(fd
, "Dynamic Threads:\n");
4192 AST_LIST_LOCK(&dynamic_list
);
4193 AST_LIST_TRAVERSE(&dynamic_list
, thread
, list
) {
4194 #ifdef DEBUG_SCHED_MULTITHREAD
4195 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4196 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4198 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d\n",
4199 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4203 AST_LIST_UNLOCK(&dynamic_list
);
4204 ast_cli(fd
, "%d of %d threads accounted for with %d dynamic threads\n", threadcount
, iaxthreadcount
, dynamiccount
);
4205 return RESULT_SUCCESS
;
4208 static int iax2_show_peers(int fd
, int argc
, char *argv
[])
4210 return __iax2_show_peers(0, fd
, NULL
, argc
, argv
);
4212 static int manager_iax2_show_netstats(struct mansession
*s
, const struct message
*m
)
4214 ast_cli_netstats(s
, -1, 0);
4215 astman_append(s
, "\r\n");
4216 return RESULT_SUCCESS
;
4219 static int iax2_show_firmware(int fd
, int argc
, char *argv
[])
4221 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
4222 #if !defined(__FreeBSD__)
4223 #define FORMAT "%-15.15s %-15d %-15d\n"
4224 #else /* __FreeBSD__ */
4225 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */
4226 #endif /* __FreeBSD__ */
4227 struct iax_firmware
*cur
;
4228 if ((argc
!= 3) && (argc
!= 4))
4229 return RESULT_SHOWUSAGE
;
4230 ast_mutex_lock(&waresl
.lock
);
4232 ast_cli(fd
, FORMAT2
, "Device", "Version", "Size");
4233 for (cur
= waresl
.wares
;cur
;cur
= cur
->next
) {
4234 if ((argc
== 3) || (!strcasecmp(argv
[3], (char *)cur
->fwh
->devname
)))
4235 ast_cli(fd
, FORMAT
, cur
->fwh
->devname
, ntohs(cur
->fwh
->version
),
4236 (int)ntohl(cur
->fwh
->datalen
));
4238 ast_mutex_unlock(&waresl
.lock
);
4239 return RESULT_SUCCESS
;
4244 /* JDG: callback to display iax peers in manager */
4245 static int manager_iax2_show_peers(struct mansession
*s
, const struct message
*m
)
4247 char *a
[] = { "iax2", "show", "users" };
4249 const char *id
= astman_get_header(m
,"ActionID");
4251 if (!ast_strlen_zero(id
))
4252 astman_append(s
, "ActionID: %s\r\n",id
);
4253 ret
= __iax2_show_peers(1, -1, s
, 3, a
);
4254 astman_append(s
, "\r\n\r\n" );
4258 static char *regstate2str(int regstate
)
4261 case REG_STATE_UNREGISTERED
:
4262 return "Unregistered";
4263 case REG_STATE_REGSENT
:
4264 return "Request Sent";
4265 case REG_STATE_AUTHSENT
:
4266 return "Auth. Sent";
4267 case REG_STATE_REGISTERED
:
4268 return "Registered";
4269 case REG_STATE_REJECTED
:
4271 case REG_STATE_TIMEOUT
:
4273 case REG_STATE_NOAUTH
:
4274 return "No Authentication";
4280 static int iax2_show_registry(int fd
, int argc
, char *argv
[])
4282 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
4283 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
4284 struct iax2_registry
*reg
= NULL
;
4289 return RESULT_SHOWUSAGE
;
4290 ast_cli(fd
, FORMAT2
, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
4291 AST_LIST_LOCK(®istrations
);
4292 AST_LIST_TRAVERSE(®istrations
, reg
, entry
) {
4293 snprintf(host
, sizeof(host
), "%s:%d", ast_inet_ntoa(reg
->addr
.sin_addr
), ntohs(reg
->addr
.sin_port
));
4294 if (reg
->us
.sin_addr
.s_addr
)
4295 snprintf(perceived
, sizeof(perceived
), "%s:%d", ast_inet_ntoa(reg
->us
.sin_addr
), ntohs(reg
->us
.sin_port
));
4297 ast_copy_string(perceived
, "<Unregistered>", sizeof(perceived
));
4298 ast_cli(fd
, FORMAT
, host
,
4299 (reg
->dnsmgr
) ? "Y" : "N",
4300 reg
->username
, perceived
, reg
->refresh
, regstate2str(reg
->regstate
));
4302 AST_LIST_UNLOCK(®istrations
);
4303 return RESULT_SUCCESS
;
4308 static int iax2_show_channels(int fd
, int argc
, char *argv
[])
4310 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
4311 #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"
4312 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
4317 return RESULT_SHOWUSAGE
;
4318 ast_cli(fd
, FORMAT2
, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
4319 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
4320 ast_mutex_lock(&iaxsl
[x
]);
4322 int lag
, jitter
, localdelay
;
4325 if(ast_test_flag(iaxs
[x
], IAX_USEJITTERBUF
)) {
4326 jb_getinfo(iaxs
[x
]->jb
, &jbinfo
);
4327 jitter
= jbinfo
.jitter
;
4328 localdelay
= jbinfo
.current
- jbinfo
.min
;
4333 lag
= iaxs
[x
]->remote_rr
.delay
;
4335 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4336 ast_inet_ntoa(iaxs
[x
]->addr
.sin_addr
),
4337 S_OR(iaxs
[x
]->username
, "(None)"),
4338 iaxs
[x
]->callno
, iaxs
[x
]->peercallno
,
4339 iaxs
[x
]->oseqno
, iaxs
[x
]->iseqno
,
4343 ast_getformatname(iaxs
[x
]->voiceformat
) );
4346 ast_mutex_unlock(&iaxsl
[x
]);
4348 ast_cli(fd
, "%d active IAX channel%s\n", numchans
, (numchans
!= 1) ? "s" : "");
4349 return RESULT_SUCCESS
;
4355 static int ast_cli_netstats(struct mansession
*s
, int fd
, int limit_fmt
)
4359 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
4360 ast_mutex_lock(&iaxsl
[x
]);
4362 int localjitter
, localdelay
, locallost
, locallosspct
, localdropped
, localooo
;
4366 if(ast_test_flag(iaxs
[x
], IAX_USEJITTERBUF
)) {
4367 jb_getinfo(iaxs
[x
]->jb
, &jbinfo
);
4368 localjitter
= jbinfo
.jitter
;
4369 localdelay
= jbinfo
.current
- jbinfo
.min
;
4370 locallost
= jbinfo
.frames_lost
;
4371 locallosspct
= jbinfo
.losspct
/1000;
4372 localdropped
= jbinfo
.frames_dropped
;
4373 localooo
= jbinfo
.frames_ooo
;
4383 fmt
= "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
4385 fmt
= "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
4388 astman_append(s
, fmt
,
4389 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4397 iaxs
[x
]->frames_received
/1000,
4398 iaxs
[x
]->remote_rr
.jitter
,
4399 iaxs
[x
]->remote_rr
.delay
,
4400 iaxs
[x
]->remote_rr
.losscnt
,
4401 iaxs
[x
]->remote_rr
.losspct
,
4402 iaxs
[x
]->remote_rr
.dropped
,
4403 iaxs
[x
]->remote_rr
.ooo
,
4404 iaxs
[x
]->remote_rr
.packets
/1000);
4407 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4415 iaxs
[x
]->frames_received
/1000,
4416 iaxs
[x
]->remote_rr
.jitter
,
4417 iaxs
[x
]->remote_rr
.delay
,
4418 iaxs
[x
]->remote_rr
.losscnt
,
4419 iaxs
[x
]->remote_rr
.losspct
,
4420 iaxs
[x
]->remote_rr
.dropped
,
4421 iaxs
[x
]->remote_rr
.ooo
,
4422 iaxs
[x
]->remote_rr
.packets
/1000
4426 ast_mutex_unlock(&iaxsl
[x
]);
4431 static int iax2_show_netstats(int fd
, int argc
, char *argv
[])
4435 return RESULT_SHOWUSAGE
;
4436 ast_cli(fd
, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
4437 ast_cli(fd
, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
4438 numchans
= ast_cli_netstats(NULL
, fd
, 1);
4439 ast_cli(fd
, "%d active IAX channel%s\n", numchans
, (numchans
!= 1) ? "s" : "");
4440 return RESULT_SUCCESS
;
4443 static int iax2_do_debug(int fd
, int argc
, char *argv
[])
4445 if (argc
< 2 || argc
> 3)
4446 return RESULT_SHOWUSAGE
;
4448 ast_cli(fd
, "IAX2 Debugging Enabled\n");
4449 return RESULT_SUCCESS
;
4452 static int iax2_do_trunk_debug(int fd
, int argc
, char *argv
[])
4454 if (argc
< 3 || argc
> 4)
4455 return RESULT_SHOWUSAGE
;
4457 ast_cli(fd
, "IAX2 Trunk Debug Requested\n");
4458 return RESULT_SUCCESS
;
4461 static int iax2_do_jb_debug(int fd
, int argc
, char *argv
[])
4463 if (argc
< 3 || argc
> 4)
4464 return RESULT_SHOWUSAGE
;
4465 jb_setoutput(jb_error_output
, jb_warning_output
, jb_debug_output
);
4466 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Enabled\n");
4467 return RESULT_SUCCESS
;
4470 static int iax2_no_debug(int fd
, int argc
, char *argv
[])
4472 if (argc
< 3 || argc
> 4)
4473 return RESULT_SHOWUSAGE
;
4475 ast_cli(fd
, "IAX2 Debugging Disabled\n");
4476 return RESULT_SUCCESS
;
4479 static int iax2_no_trunk_debug(int fd
, int argc
, char *argv
[])
4481 if (argc
< 4 || argc
> 5)
4482 return RESULT_SHOWUSAGE
;
4484 ast_cli(fd
, "IAX2 Trunk Debugging Disabled\n");
4485 return RESULT_SUCCESS
;
4488 static int iax2_no_jb_debug(int fd
, int argc
, char *argv
[])
4490 if (argc
< 4 || argc
> 5)
4491 return RESULT_SHOWUSAGE
;
4492 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
4493 jb_debug_output("\n");
4494 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Disabled\n");
4495 return RESULT_SUCCESS
;
4498 static int iax2_write(struct ast_channel
*c
, struct ast_frame
*f
)
4500 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
4502 ast_mutex_lock(&iaxsl
[callno
]);
4504 /* If there's an outstanding error, return failure now */
4505 if (!iaxs
[callno
]->error
) {
4506 if (ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
))
4508 /* Don't waste bandwidth sending null frames */
4509 else if (f
->frametype
== AST_FRAME_NULL
)
4511 else if ((f
->frametype
== AST_FRAME_VOICE
) && ast_test_flag(iaxs
[callno
], IAX_QUELCH
))
4513 else if (!ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_STARTED
))
4516 /* Simple, just queue for transmission */
4517 res
= iax2_send(iaxs
[callno
], f
, 0, -1, 0, 0, 0);
4519 ast_log(LOG_DEBUG
, "Write error: %s\n", strerror(errno
));
4522 /* If it's already gone, just return */
4523 ast_mutex_unlock(&iaxsl
[callno
]);
4527 static int __send_command(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
,
4528 int now
, int transfer
, int final
)
4530 struct ast_frame f
= { 0, };
4533 f
.subclass
= command
;
4534 f
.datalen
= datalen
;
4535 f
.src
= __FUNCTION__
;
4536 f
.data
= (void *) data
;
4538 return iax2_send(i
, &f
, ts
, seqno
, now
, transfer
, final
);
4541 static int send_command(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4543 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 0, 0, 0);
4546 static int send_command_locked(unsigned short callno
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4549 ast_mutex_lock(&iaxsl
[callno
]);
4550 res
= send_command(iaxs
[callno
], type
, command
, ts
, data
, datalen
, seqno
);
4551 ast_mutex_unlock(&iaxsl
[callno
]);
4555 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
)
4557 /* It is assumed that the callno has already been locked */
4558 iax2_predestroy(i
->callno
);
4559 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 0, 0, 1);
4562 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
)
4564 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 1, 0, 0);
4567 static int send_command_transfer(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
)
4569 return __send_command(i
, type
, command
, ts
, data
, datalen
, 0, 0, 1, 0);
4572 static int apply_context(struct iax2_context
*con
, const char *context
)
4575 if (!strcmp(con
->context
, context
) || !strcmp(con
->context
, "*"))
4583 static int check_access(int callno
, struct sockaddr_in
*sin
, struct iax_ies
*ies
)
4585 /* Start pessimistic */
4588 struct iax2_user
*user
= NULL
, *best
= NULL
;
4590 int gotcapability
= 0;
4591 struct ast_variable
*v
= NULL
, *tmpvar
= NULL
;
4595 if (ies
->called_number
)
4596 ast_string_field_set(iaxs
[callno
], exten
, ies
->called_number
);
4597 if (ies
->calling_number
) {
4598 ast_shrink_phone_number(ies
->calling_number
);
4599 ast_string_field_set(iaxs
[callno
], cid_num
, ies
->calling_number
);
4601 if (ies
->calling_name
)
4602 ast_string_field_set(iaxs
[callno
], cid_name
, ies
->calling_name
);
4603 if (ies
->calling_ani
)
4604 ast_string_field_set(iaxs
[callno
], ani
, ies
->calling_ani
);
4606 ast_string_field_set(iaxs
[callno
], dnid
, ies
->dnid
);
4608 ast_string_field_set(iaxs
[callno
], rdnis
, ies
->rdnis
);
4609 if (ies
->called_context
)
4610 ast_string_field_set(iaxs
[callno
], context
, ies
->called_context
);
4612 ast_string_field_set(iaxs
[callno
], language
, ies
->language
);
4614 ast_string_field_set(iaxs
[callno
], username
, ies
->username
);
4615 if (ies
->calling_ton
> -1)
4616 iaxs
[callno
]->calling_ton
= ies
->calling_ton
;
4617 if (ies
->calling_tns
> -1)
4618 iaxs
[callno
]->calling_tns
= ies
->calling_tns
;
4619 if (ies
->calling_pres
> -1)
4620 iaxs
[callno
]->calling_pres
= ies
->calling_pres
;
4622 iaxs
[callno
]->peerformat
= ies
->format
;
4624 iaxs
[callno
]->peeradsicpe
= ies
->adsicpe
;
4625 if (ies
->capability
) {
4627 iaxs
[callno
]->peercapability
= ies
->capability
;
4630 version
= ies
->version
;
4632 /* Use provided preferences until told otherwise for actual preferences */
4633 if(ies
->codec_prefs
) {
4634 ast_codec_pref_convert(&iaxs
[callno
]->rprefs
, ies
->codec_prefs
, 32, 0);
4635 ast_codec_pref_convert(&iaxs
[callno
]->prefs
, ies
->codec_prefs
, 32, 0);
4639 iaxs
[callno
]->peercapability
= iaxs
[callno
]->peerformat
;
4640 if (version
> IAX_PROTO_VERSION
) {
4641 ast_log(LOG_WARNING
, "Peer '%s' has too new a protocol version (%d) for me\n",
4642 ast_inet_ntoa(sin
->sin_addr
), version
);
4645 /* Search the userlist for a compatible entry, and fill in the rest */
4646 AST_LIST_LOCK(&users
);
4647 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4648 if ((ast_strlen_zero(iaxs
[callno
]->username
) || /* No username specified */
4649 !strcmp(iaxs
[callno
]->username
, user
->name
)) /* Or this username specified */
4650 && ast_apply_ha(user
->ha
, sin
) /* Access is permitted from this IP */
4651 && (ast_strlen_zero(iaxs
[callno
]->context
) || /* No context specified */
4652 apply_context(user
->contexts
, iaxs
[callno
]->context
))) { /* Context is permitted */
4653 if (!ast_strlen_zero(iaxs
[callno
]->username
)) {
4654 /* Exact match, stop right now. */
4657 } else if (ast_strlen_zero(user
->secret
) && ast_strlen_zero(user
->inkeys
)) {
4658 /* No required authentication */
4660 /* There was host authentication and we passed, bonus! */
4661 if (bestscore
< 4) {
4666 /* No host access, but no secret, either, not bad */
4667 if (bestscore
< 3) {
4674 /* Authentication, but host access too, eh, it's something.. */
4675 if (bestscore
< 2) {
4680 /* Authentication and no host access... This is our baseline */
4681 if (bestscore
< 1) {
4689 AST_LIST_UNLOCK(&users
);
4691 if (!user
&& !ast_strlen_zero(iaxs
[callno
]->username
)) {
4692 user
= realtime_user(iaxs
[callno
]->username
);
4693 if (user
&& !ast_strlen_zero(iaxs
[callno
]->context
) && /* No context specified */
4694 !apply_context(user
->contexts
, iaxs
[callno
]->context
)) { /* Context is permitted */
4700 /* We found our match (use the first) */
4702 for (v
= user
->vars
; v
; v
= v
->next
) {
4703 if((tmpvar
= ast_variable_new(v
->name
, v
->value
))) {
4704 tmpvar
->next
= iaxs
[callno
]->vars
;
4705 iaxs
[callno
]->vars
= tmpvar
;
4708 /* If a max AUTHREQ restriction is in place, activate it */
4709 if (user
->maxauthreq
> 0)
4710 ast_set_flag(iaxs
[callno
], IAX_MAXAUTHREQ
);
4711 iaxs
[callno
]->prefs
= user
->prefs
;
4712 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_USER_FIRST
);
4713 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_NOPREFS
);
4714 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_NOCAP
);
4715 iaxs
[callno
]->encmethods
= user
->encmethods
;
4716 /* Store the requested username if not specified */
4717 if (ast_strlen_zero(iaxs
[callno
]->username
))
4718 ast_string_field_set(iaxs
[callno
], username
, user
->name
);
4719 /* Store whether this is a trunked call, too, of course, and move if appropriate */
4720 ast_copy_flags(iaxs
[callno
], user
, IAX_TRUNK
);
4721 iaxs
[callno
]->capability
= user
->capability
;
4722 /* And use the default context */
4723 if (ast_strlen_zero(iaxs
[callno
]->context
)) {
4725 ast_string_field_set(iaxs
[callno
], context
, user
->contexts
->context
);
4727 ast_string_field_set(iaxs
[callno
], context
, context
);
4729 /* And any input keys */
4730 ast_string_field_set(iaxs
[callno
], inkeys
, user
->inkeys
);
4731 /* And the permitted authentication methods */
4732 iaxs
[callno
]->authmethods
= user
->authmethods
;
4733 iaxs
[callno
]->adsi
= user
->adsi
;
4734 /* If they have callerid, override the given caller id. Always store the ANI */
4735 if (!ast_strlen_zero(iaxs
[callno
]->cid_num
) || !ast_strlen_zero(iaxs
[callno
]->cid_name
)) {
4736 if (ast_test_flag(user
, IAX_HASCALLERID
)) {
4737 iaxs
[callno
]->calling_tns
= 0;
4738 iaxs
[callno
]->calling_ton
= 0;
4739 ast_string_field_set(iaxs
[callno
], cid_num
, user
->cid_num
);
4740 ast_string_field_set(iaxs
[callno
], cid_name
, user
->cid_name
);
4741 iaxs
[callno
]->calling_pres
= AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
;
4743 if (ast_strlen_zero(iaxs
[callno
]->ani
))
4744 ast_string_field_set(iaxs
[callno
], ani
, user
->cid_num
);
4746 iaxs
[callno
]->calling_pres
= AST_PRES_NUMBER_NOT_AVAILABLE
;
4748 if (!ast_strlen_zero(user
->accountcode
))
4749 ast_string_field_set(iaxs
[callno
], accountcode
, user
->accountcode
);
4750 if (!ast_strlen_zero(user
->mohinterpret
))
4751 ast_string_field_set(iaxs
[callno
], mohinterpret
, user
->mohinterpret
);
4752 if (!ast_strlen_zero(user
->mohsuggest
))
4753 ast_string_field_set(iaxs
[callno
], mohsuggest
, user
->mohsuggest
);
4755 iaxs
[callno
]->amaflags
= user
->amaflags
;
4756 if (!ast_strlen_zero(user
->language
))
4757 ast_string_field_set(iaxs
[callno
], language
, user
->language
);
4758 ast_copy_flags(iaxs
[callno
], user
, IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
4759 /* Keep this check last */
4760 if (!ast_strlen_zero(user
->dbsecret
)) {
4761 char *family
, *key
=NULL
;
4763 family
= ast_strdupa(user
->dbsecret
);
4764 key
= strchr(family
, '/');
4769 if (!key
|| ast_db_get(family
, key
, buf
, sizeof(buf
)))
4770 ast_log(LOG_WARNING
, "Unable to retrieve database password for family/key '%s'!\n", user
->dbsecret
);
4772 ast_string_field_set(iaxs
[callno
], secret
, buf
);
4774 ast_string_field_set(iaxs
[callno
], secret
, user
->secret
);
4775 if (ast_test_flag(user
, IAX_TEMPONLY
))
4779 ast_set2_flag(iaxs
[callno
], iax2_getpeertrunk(*sin
), IAX_TRUNK
);
4783 static int raw_hangup(struct sockaddr_in
*sin
, unsigned short src
, unsigned short dst
, int sockfd
)
4785 struct ast_iax2_full_hdr fh
;
4786 fh
.scallno
= htons(src
| IAX_FLAG_FULL
);
4787 fh
.dcallno
= htons(dst
);
4791 fh
.type
= AST_FRAME_IAX
;
4792 fh
.csub
= compress_subclass(IAX_COMMAND_INVAL
);
4794 iax_showframe(NULL
, &fh
, 0, sin
, 0);
4798 ast_log(LOG_DEBUG
, "Raw Hangup %s:%d, src=%d, dst=%d\n",
4799 ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), src
, dst
);
4800 return sendto(sockfd
, &fh
, sizeof(fh
), 0, (struct sockaddr
*)sin
, sizeof(*sin
));
4803 static void merge_encryption(struct chan_iax2_pvt
*p
, unsigned int enc
)
4805 /* Select exactly one common encryption if there are any */
4806 p
->encmethods
&= enc
;
4807 if (p
->encmethods
) {
4808 if (p
->encmethods
& IAX_ENCRYPT_AES128
)
4809 p
->encmethods
= IAX_ENCRYPT_AES128
;
4815 static int authenticate_request(struct chan_iax2_pvt
*p
)
4817 struct iax2_user
*user
= NULL
;
4818 struct iax_ie_data ied
;
4819 int res
= -1, authreq_restrict
= 0;
4822 memset(&ied
, 0, sizeof(ied
));
4824 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
4825 if (ast_test_flag(p
, IAX_MAXAUTHREQ
)) {
4826 AST_LIST_LOCK(&users
);
4827 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4828 if (!strcmp(user
->name
, p
->username
)) {
4829 if (user
->curauthreq
== user
->maxauthreq
)
4830 authreq_restrict
= 1;
4836 AST_LIST_UNLOCK(&users
);
4839 /* If the AUTHREQ limit test failed, send back an error */
4840 if (authreq_restrict
) {
4841 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Unauthenticated call limit reached");
4842 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_CALL_REJECTED
);
4843 send_command_final(p
, AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied
.buf
, ied
.pos
, -1);
4847 iax_ie_append_short(&ied
, IAX_IE_AUTHMETHODS
, p
->authmethods
);
4848 if (p
->authmethods
& (IAX_AUTH_MD5
| IAX_AUTH_RSA
)) {
4849 snprintf(challenge
, sizeof(challenge
), "%d", (int)ast_random());
4850 ast_string_field_set(p
, challenge
, challenge
);
4851 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
4852 iax_ie_append_str(&ied
, IAX_IE_CHALLENGE
, p
->challenge
);
4855 iax_ie_append_short(&ied
, IAX_IE_ENCRYPTION
, p
->encmethods
);
4857 iax_ie_append_str(&ied
,IAX_IE_USERNAME
, p
->username
);
4859 res
= send_command(p
, AST_FRAME_IAX
, IAX_COMMAND_AUTHREQ
, 0, ied
.buf
, ied
.pos
, -1);
4862 ast_set_flag(p
, IAX_ENCRYPTED
);
4867 static int authenticate_verify(struct chan_iax2_pvt
*p
, struct iax_ies
*ies
)
4869 char requeststr
[256];
4870 char md5secret
[256] = "";
4871 char secret
[256] = "";
4872 char rsasecret
[256] = "";
4875 struct iax2_user
*user
= NULL
;
4877 AST_LIST_LOCK(&users
);
4878 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4879 if (!strcmp(user
->name
, p
->username
))
4883 if (ast_test_flag(p
, IAX_MAXAUTHREQ
)) {
4885 ast_clear_flag(p
, IAX_MAXAUTHREQ
);
4887 ast_string_field_set(p
, host
, user
->name
);
4889 AST_LIST_UNLOCK(&users
);
4891 if (!ast_test_flag(&p
->state
, IAX_STATE_AUTHENTICATED
))
4894 ast_copy_string(secret
, ies
->password
, sizeof(secret
));
4895 if (ies
->md5_result
)
4896 ast_copy_string(md5secret
, ies
->md5_result
, sizeof(md5secret
));
4897 if (ies
->rsa_result
)
4898 ast_copy_string(rsasecret
, ies
->rsa_result
, sizeof(rsasecret
));
4899 if ((p
->authmethods
& IAX_AUTH_RSA
) && !ast_strlen_zero(rsasecret
) && !ast_strlen_zero(p
->inkeys
)) {
4900 struct ast_key
*key
;
4904 ast_copy_string(tmpkey
, p
->inkeys
, sizeof(tmpkey
));
4906 keyn
= strsep(&stringp
, ":");
4908 key
= ast_key_get(keyn
, AST_KEY_PUBLIC
);
4909 if (key
&& !ast_check_signature(key
, p
->challenge
, rsasecret
)) {
4913 ast_log(LOG_WARNING
, "requested inkey '%s' for RSA authentication does not exist\n", keyn
);
4914 keyn
= strsep(&stringp
, ":");
4916 } else if (p
->authmethods
& IAX_AUTH_MD5
) {
4917 struct MD5Context md5
;
4918 unsigned char digest
[16];
4919 char *tmppw
, *stringp
;
4921 tmppw
= ast_strdupa(p
->secret
);
4923 while((tmppw
= strsep(&stringp
, ";"))) {
4925 MD5Update(&md5
, (unsigned char *)p
->challenge
, strlen(p
->challenge
));
4926 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
4927 MD5Final(digest
, &md5
);
4928 /* If they support md5, authenticate with it. */
4930 sprintf(requeststr
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
4931 if (!strcasecmp(requeststr
, md5secret
)) {
4936 } else if (p
->authmethods
& IAX_AUTH_PLAINTEXT
) {
4937 if (!strcmp(secret
, p
->secret
))
4943 /*! \brief Verify inbound registration */
4944 static int register_verify(int callno
, struct sockaddr_in
*sin
, struct iax_ies
*ies
)
4946 char requeststr
[256] = "";
4947 char peer
[256] = "";
4948 char md5secret
[256] = "";
4949 char rsasecret
[256] = "";
4950 char secret
[256] = "";
4951 struct iax2_peer
*p
;
4952 struct ast_key
*key
;
4957 ast_clear_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
| IAX_STATE_UNCHANGED
);
4958 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
4960 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
4962 ast_copy_string(secret
, ies
->password
, sizeof(secret
));
4963 if (ies
->md5_result
)
4964 ast_copy_string(md5secret
, ies
->md5_result
, sizeof(md5secret
));
4965 if (ies
->rsa_result
)
4966 ast_copy_string(rsasecret
, ies
->rsa_result
, sizeof(rsasecret
));
4968 expire
= ies
->refresh
;
4970 if (ast_strlen_zero(peer
)) {
4971 ast_log(LOG_NOTICE
, "Empty registration from %s\n", ast_inet_ntoa(sin
->sin_addr
));
4975 /* SLD: first call to lookup peer during registration */
4976 p
= find_peer(peer
, 1);
4980 ast_log(LOG_NOTICE
, "No registration for peer '%s' (from %s)\n", peer
, ast_inet_ntoa(sin
->sin_addr
));
4984 if (!ast_test_flag(p
, IAX_DYNAMIC
)) {
4986 ast_log(LOG_NOTICE
, "Peer '%s' is not dynamic (from %s)\n", peer
, ast_inet_ntoa(sin
->sin_addr
));
4987 if (ast_test_flag(p
, IAX_TEMPONLY
))
4992 if (!ast_apply_ha(p
->ha
, sin
)) {
4994 ast_log(LOG_NOTICE
, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
);
4995 if (ast_test_flag(p
, IAX_TEMPONLY
))
4999 if (!inaddrcmp(&p
->addr
, sin
))
5000 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_UNCHANGED
);
5001 ast_string_field_set(iaxs
[callno
], secret
, p
->secret
);
5002 ast_string_field_set(iaxs
[callno
], inkeys
, p
->inkeys
);
5003 /* Check secret against what we have on file */
5004 if (!ast_strlen_zero(rsasecret
) && (p
->authmethods
& IAX_AUTH_RSA
) && !ast_strlen_zero(iaxs
[callno
]->challenge
)) {
5005 if (!ast_strlen_zero(p
->inkeys
)) {
5008 ast_copy_string(tmpkeys
, p
->inkeys
, sizeof(tmpkeys
));
5010 keyn
= strsep(&stringp
, ":");
5012 key
= ast_key_get(keyn
, AST_KEY_PUBLIC
);
5013 if (key
&& !ast_check_signature(key
, iaxs
[callno
]->challenge
, rsasecret
)) {
5014 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5017 ast_log(LOG_WARNING
, "requested inkey '%s' does not exist\n", keyn
);
5018 keyn
= strsep(&stringp
, ":");
5022 ast_log(LOG_NOTICE
, "Host %s failed RSA authentication with inkeys '%s'\n", peer
, p
->inkeys
);
5023 if (ast_test_flag(p
, IAX_TEMPONLY
))
5029 ast_log(LOG_NOTICE
, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer
);
5030 if (ast_test_flag(p
, IAX_TEMPONLY
))
5034 } else if (!ast_strlen_zero(md5secret
) && (p
->authmethods
& IAX_AUTH_MD5
) && !ast_strlen_zero(iaxs
[callno
]->challenge
)) {
5035 struct MD5Context md5
;
5036 unsigned char digest
[16];
5037 char *tmppw
, *stringp
;
5039 tmppw
= ast_strdupa(p
->secret
);
5041 while((tmppw
= strsep(&stringp
, ";"))) {
5043 MD5Update(&md5
, (unsigned char *)iaxs
[callno
]->challenge
, strlen(iaxs
[callno
]->challenge
));
5044 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
5045 MD5Final(digest
, &md5
);
5047 sprintf(requeststr
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
5048 if (!strcasecmp(requeststr
, md5secret
))
5052 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5055 ast_log(LOG_NOTICE
, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
, requeststr
, md5secret
);
5056 if (ast_test_flag(p
, IAX_TEMPONLY
))
5060 } else if (!ast_strlen_zero(secret
) && (p
->authmethods
& IAX_AUTH_PLAINTEXT
)) {
5061 /* They've provided a plain text password and we support that */
5062 if (strcmp(secret
, p
->secret
)) {
5064 ast_log(LOG_NOTICE
, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
);
5065 if (ast_test_flag(p
, IAX_TEMPONLY
))
5069 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5070 } else if (!ast_strlen_zero(md5secret
) || !ast_strlen_zero(secret
)) {
5072 ast_log(LOG_NOTICE
, "Inappropriate authentication received\n");
5073 if (ast_test_flag(p
, IAX_TEMPONLY
))
5077 ast_string_field_set(iaxs
[callno
], peer
, peer
);
5078 /* Choose lowest expiry number */
5079 if (expire
&& (expire
< iaxs
[callno
]->expiry
))
5080 iaxs
[callno
]->expiry
= expire
;
5082 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5084 if (ast_test_flag(p
, IAX_TEMPONLY
))
5090 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
)
5094 if (!ast_strlen_zero(keyn
)) {
5095 if (!(authmethods
& IAX_AUTH_RSA
)) {
5096 if (ast_strlen_zero(secret
))
5097 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
));
5098 } else if (ast_strlen_zero(challenge
)) {
5099 ast_log(LOG_NOTICE
, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin
->sin_addr
));
5102 struct ast_key
*key
;
5103 key
= ast_key_get(keyn
, AST_KEY_PRIVATE
);
5105 ast_log(LOG_NOTICE
, "Unable to find private key '%s'\n", keyn
);
5107 if (ast_sign(key
, (char*)challenge
, sig
)) {
5108 ast_log(LOG_NOTICE
, "Unable to sign challenge with key\n");
5111 iax_ie_append_str(ied
, IAX_IE_RSA_RESULT
, sig
);
5118 if (res
&& !ast_strlen_zero(secret
)) {
5119 if ((authmethods
& IAX_AUTH_MD5
) && !ast_strlen_zero(challenge
)) {
5120 struct MD5Context md5
;
5121 unsigned char digest
[16];
5124 MD5Update(&md5
, (unsigned char *)challenge
, strlen(challenge
));
5125 MD5Update(&md5
, (unsigned char *)secret
, strlen(secret
));
5126 MD5Final(digest
, &md5
);
5127 /* If they support md5, authenticate with it. */
5129 sprintf(digres
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
5131 build_enc_keys(digest
, ecx
, dcx
);
5132 iax_ie_append_str(ied
, IAX_IE_MD5_RESULT
, digres
);
5134 } else if (authmethods
& IAX_AUTH_PLAINTEXT
) {
5135 iax_ie_append_str(ied
, IAX_IE_PASSWORD
, secret
);
5138 ast_log(LOG_NOTICE
, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin
->sin_addr
), authmethods
);
5143 static int authenticate_reply(struct chan_iax2_pvt
*p
, struct sockaddr_in
*sin
, struct iax_ies
*ies
, const char *override
, const char *okey
)
5145 struct iax2_peer
*peer
= NULL
;
5146 /* Start pessimistic */
5148 int authmethods
= 0;
5149 struct iax_ie_data ied
;
5151 memset(&ied
, 0, sizeof(ied
));
5154 ast_string_field_set(p
, username
, ies
->username
);
5156 ast_string_field_set(p
, challenge
, ies
->challenge
);
5157 if (ies
->authmethods
)
5158 authmethods
= ies
->authmethods
;
5159 if (authmethods
& IAX_AUTH_MD5
)
5160 merge_encryption(p
, ies
->encmethods
);
5164 /* Check for override RSA authentication first */
5165 if (!ast_strlen_zero(override
) || !ast_strlen_zero(okey
)) {
5166 /* Normal password authentication */
5167 res
= authenticate(p
->challenge
, override
, okey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5169 AST_LIST_LOCK(&peers
);
5170 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
5171 if ((ast_strlen_zero(p
->peer
) || !strcmp(p
->peer
, peer
->name
))
5172 /* No peer specified at our end, or this is the peer */
5173 && (ast_strlen_zero(peer
->username
) || (!strcmp(peer
->username
, p
->username
)))
5174 /* No username specified in peer rule, or this is the right username */
5175 && (!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
)))
5176 /* No specified host, or this is our host */
5178 res
= authenticate(p
->challenge
, peer
->secret
, peer
->outkey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5183 AST_LIST_UNLOCK(&peers
);
5185 /* We checked our list and didn't find one. It's unlikely, but possible,
5186 that we're trying to authenticate *to* a realtime peer */
5187 if ((peer
= realtime_peer(p
->peer
, NULL
))) {
5188 res
= authenticate(p
->challenge
, peer
->secret
,peer
->outkey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5189 if (ast_test_flag(peer
, IAX_TEMPONLY
))
5194 if (ies
->encmethods
)
5195 ast_set_flag(p
, IAX_ENCRYPTED
| IAX_KEYPOPULATED
);
5197 res
= send_command(p
, AST_FRAME_IAX
, IAX_COMMAND_AUTHREP
, 0, ied
.buf
, ied
.pos
, -1);
5201 static int iax2_do_register(struct iax2_registry
*reg
);
5203 static void __iax2_do_register_s(void *data
)
5205 struct iax2_registry
*reg
= data
;
5207 iax2_do_register(reg
);
5210 static int iax2_do_register_s(void *data
)
5212 #ifdef SCHED_MULTITHREADED
5213 if (schedule_action(__iax2_do_register_s
, data
))
5215 __iax2_do_register_s(data
);
5219 static int try_transfer(struct chan_iax2_pvt
*pvt
, struct iax_ies
*ies
)
5223 struct iax_ie_data ied
;
5224 struct sockaddr_in
new;
5227 memset(&ied
, 0, sizeof(ied
));
5228 if (ies
->apparent_addr
)
5229 bcopy(ies
->apparent_addr
, &new, sizeof(new));
5231 newcall
= ies
->callno
;
5232 if (!newcall
|| !new.sin_addr
.s_addr
|| !new.sin_port
) {
5233 ast_log(LOG_WARNING
, "Invalid transfer request\n");
5236 pvt
->transfercallno
= newcall
;
5237 memcpy(&pvt
->transfer
, &new, sizeof(pvt
->transfer
));
5238 inet_aton(newip
, &pvt
->transfer
.sin_addr
);
5239 pvt
->transfer
.sin_family
= AF_INET
;
5240 pvt
->transferring
= TRANSFER_BEGIN
;
5241 pvt
->transferid
= ies
->transferid
;
5242 if (ies
->transferid
)
5243 iax_ie_append_int(&ied
, IAX_IE_TRANSFERID
, ies
->transferid
);
5244 send_command_transfer(pvt
, AST_FRAME_IAX
, IAX_COMMAND_TXCNT
, 0, ied
.buf
, ied
.pos
);
5248 static int complete_dpreply(struct chan_iax2_pvt
*pvt
, struct iax_ies
*ies
)
5250 char exten
[256] = "";
5251 int status
= CACHE_FLAG_UNKNOWN
;
5252 int expiry
= iaxdefaultdpcache
;
5255 struct iax2_dpcache
*dp
, *prev
;
5257 if (ies
->called_number
)
5258 ast_copy_string(exten
, ies
->called_number
, sizeof(exten
));
5260 if (ies
->dpstatus
& IAX_DPSTATUS_EXISTS
)
5261 status
= CACHE_FLAG_EXISTS
;
5262 else if (ies
->dpstatus
& IAX_DPSTATUS_CANEXIST
)
5263 status
= CACHE_FLAG_CANEXIST
;
5264 else if (ies
->dpstatus
& IAX_DPSTATUS_NONEXISTENT
)
5265 status
= CACHE_FLAG_NONEXISTENT
;
5267 if (ies
->dpstatus
& IAX_DPSTATUS_IGNOREPAT
) {
5268 /* Don't really do anything with this */
5271 expiry
= ies
->refresh
;
5272 if (ies
->dpstatus
& IAX_DPSTATUS_MATCHMORE
)
5273 matchmore
= CACHE_FLAG_MATCHMORE
;
5274 ast_mutex_lock(&dpcache_lock
);
5276 dp
= pvt
->dpentries
;
5278 if (!strcmp(dp
->exten
, exten
)) {
5281 prev
->peer
= dp
->peer
;
5283 pvt
->dpentries
= dp
->peer
;
5286 dp
->expiry
.tv_sec
= dp
->orig
.tv_sec
+ expiry
;
5287 if (dp
->flags
& CACHE_FLAG_PENDING
) {
5288 dp
->flags
&= ~CACHE_FLAG_PENDING
;
5289 dp
->flags
|= status
;
5290 dp
->flags
|= matchmore
;
5292 /* Wake up waiters */
5293 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
5294 if (dp
->waiters
[x
] > -1)
5295 write(dp
->waiters
[x
], "asdf", 4);
5300 ast_mutex_unlock(&dpcache_lock
);
5304 static int complete_transfer(int callno
, struct iax_ies
*ies
)
5307 struct chan_iax2_pvt
*pvt
= iaxs
[callno
];
5308 struct iax_frame
*cur
;
5312 peercallno
= ies
->callno
;
5314 if (peercallno
< 1) {
5315 ast_log(LOG_WARNING
, "Invalid transfer request\n");
5318 memcpy(&pvt
->addr
, &pvt
->transfer
, sizeof(pvt
->addr
));
5319 memset(&pvt
->transfer
, 0, sizeof(pvt
->transfer
));
5320 /* Reset sequence numbers */
5325 pvt
->peercallno
= peercallno
;
5326 pvt
->transferring
= TRANSFER_NONE
;
5327 pvt
->svoiceformat
= -1;
5328 pvt
->voiceformat
= 0;
5329 pvt
->svideoformat
= -1;
5330 pvt
->videoformat
= 0;
5331 pvt
->transfercallno
= -1;
5332 memset(&pvt
->rxcore
, 0, sizeof(pvt
->rxcore
));
5333 memset(&pvt
->offset
, 0, sizeof(pvt
->offset
));
5334 /* reset jitterbuffer */
5335 while(jb_getall(pvt
->jb
,&frame
) == JB_OK
)
5336 iax2_frame_free(frame
.data
);
5342 pvt
->pingtime
= DEFAULT_RETRY_TIME
;
5343 AST_LIST_LOCK(&iaxq
.queue
);
5344 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
5345 /* We must cancel any packets that would have been transmitted
5346 because now we're talking to someone new. It's okay, they
5347 were transmitted to someone that didn't care anyway. */
5348 if (callno
== cur
->callno
)
5351 AST_LIST_UNLOCK(&iaxq
.queue
);
5355 /*! \brief Acknowledgment received for OUR registration */
5356 static int iax2_ack_registry(struct iax_ies
*ies
, struct sockaddr_in
*sin
, int callno
)
5358 struct iax2_registry
*reg
;
5359 /* Start pessimistic */
5360 char peer
[256] = "";
5363 char ourip
[256] = "<Unspecified>";
5364 struct sockaddr_in oldus
;
5365 struct sockaddr_in us
;
5368 memset(&us
, 0, sizeof(us
));
5369 if (ies
->apparent_addr
)
5370 bcopy(ies
->apparent_addr
, &us
, sizeof(us
));
5372 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
5374 refresh
= ies
->refresh
;
5375 if (ies
->calling_number
) {
5376 /* We don't do anything with it really, but maybe we should */
5378 reg
= iaxs
[callno
]->reg
;
5380 ast_log(LOG_WARNING
, "Registry acknowledge on unknown registry '%s'\n", peer
);
5383 memcpy(&oldus
, ®
->us
, sizeof(oldus
));
5384 oldmsgs
= reg
->messages
;
5385 if (inaddrcmp(®
->addr
, sin
)) {
5386 ast_log(LOG_WARNING
, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin
->sin_addr
));
5389 memcpy(®
->us
, &us
, sizeof(reg
->us
));
5390 if (ies
->msgcount
>= 0)
5391 reg
->messages
= ies
->msgcount
& 0xffff; /* only low 16 bits are used in the transmission of the IE */
5392 /* always refresh the registration at the interval requested by the server
5393 we are registering to
5395 reg
->refresh
= refresh
;
5396 if (reg
->expire
> -1)
5397 ast_sched_del(sched
, reg
->expire
);
5398 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
5399 if (inaddrcmp(&oldus
, ®
->us
) || (reg
->messages
!= oldmsgs
)) {
5400 if (option_verbose
> 2) {
5401 if (reg
->messages
> 255)
5402 snprintf(msgstatus
, sizeof(msgstatus
), " with %d new and %d old messages waiting", reg
->messages
& 0xff, reg
->messages
>> 8);
5403 else if (reg
->messages
> 1)
5404 snprintf(msgstatus
, sizeof(msgstatus
), " with %d new messages waiting\n", reg
->messages
);
5405 else if (reg
->messages
> 0)
5406 snprintf(msgstatus
, sizeof(msgstatus
), " with 1 new message waiting\n");
5408 snprintf(msgstatus
, sizeof(msgstatus
), " with no messages waiting\n");
5409 snprintf(ourip
, sizeof(ourip
), "%s:%d", ast_inet_ntoa(reg
->us
.sin_addr
), ntohs(reg
->us
.sin_port
));
5410 ast_verbose(VERBOSE_PREFIX_3
"Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin
->sin_addr
), ourip
, msgstatus
);
5412 manager_event(EVENT_FLAG_SYSTEM
, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin
->sin_addr
));
5414 reg
->regstate
= REG_STATE_REGISTERED
;
5418 static int iax2_register(char *value
, int lineno
)
5420 struct iax2_registry
*reg
;
5422 char *username
, *hostname
, *secret
;
5428 ast_copy_string(copy
, value
, sizeof(copy
));
5430 username
= strsep(&stringp
, "@");
5431 hostname
= strsep(&stringp
, "@");
5433 ast_log(LOG_WARNING
, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno
);
5437 username
= strsep(&stringp
, ":");
5438 secret
= strsep(&stringp
, ":");
5440 hostname
= strsep(&stringp
, ":");
5441 porta
= strsep(&stringp
, ":");
5443 if (porta
&& !atoi(porta
)) {
5444 ast_log(LOG_WARNING
, "%s is not a valid port number at line %d\n", porta
, lineno
);
5447 if (!(reg
= ast_calloc(1, sizeof(*reg
))))
5449 if (ast_dnsmgr_lookup(hostname
, ®
->addr
.sin_addr
, ®
->dnsmgr
) < 0) {
5453 ast_copy_string(reg
->username
, username
, sizeof(reg
->username
));
5455 ast_copy_string(reg
->secret
, secret
, sizeof(reg
->secret
));
5457 reg
->refresh
= IAX_DEFAULT_REG_EXPIRE
;
5458 reg
->addr
.sin_family
= AF_INET
;
5459 reg
->addr
.sin_port
= porta
? htons(atoi(porta
)) : htons(IAX_DEFAULT_PORTNO
);
5460 AST_LIST_LOCK(®istrations
);
5461 AST_LIST_INSERT_HEAD(®istrations
, reg
, entry
);
5462 AST_LIST_UNLOCK(®istrations
);
5467 static void register_peer_exten(struct iax2_peer
*peer
, int onoff
)
5470 char *stringp
, *ext
;
5471 if (!ast_strlen_zero(regcontext
)) {
5472 ast_copy_string(multi
, S_OR(peer
->regexten
, peer
->name
), sizeof(multi
));
5474 while((ext
= strsep(&stringp
, "&"))) {
5476 if (!ast_exists_extension(NULL
, regcontext
, ext
, 1, NULL
))
5477 ast_add_extension(regcontext
, 1, ext
, 1, NULL
, NULL
,
5478 "Noop", ast_strdup(peer
->name
), ast_free
, "IAX2");
5480 ast_context_remove_extension(regcontext
, ext
, 1, NULL
);
5484 static void prune_peers(void);
5486 static void __expire_registry(void *data
)
5489 struct iax2_peer
*p
= NULL
;
5491 /* Go through and grab this peer... and if it needs to be removed... then do it */
5492 AST_LIST_LOCK(&peers
);
5493 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers
, p
, entry
) {
5494 if (!strcasecmp(p
->name
, name
)) {
5499 AST_LIST_TRAVERSE_SAFE_END
5500 AST_LIST_UNLOCK(&peers
);
5502 /* Peer is already gone for whatever reason */
5506 ast_log(LOG_DEBUG
, "Expiring registration for peer '%s'\n", p
->name
);
5507 if (ast_test_flag((&globalflags
), IAX_RTUPDATE
) && (ast_test_flag(p
, IAX_TEMPONLY
|IAX_RTCACHEFRIENDS
)))
5508 realtime_update_peer(p
->name
, &p
->addr
, 0);
5509 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p
->name
);
5510 /* Reset the address */
5511 memset(&p
->addr
, 0, sizeof(p
->addr
));
5512 /* Reset expiry value */
5513 p
->expiry
= min_reg_expire
;
5514 if (!ast_test_flag(p
, IAX_TEMPONLY
))
5515 ast_db_del("IAX/Registry", p
->name
);
5516 register_peer_exten(p
, 0);
5517 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5519 iax2_regfunk(p
->name
, 0);
5521 if (ast_test_flag(p
, IAX_RTAUTOCLEAR
)) {
5522 ast_set_flag(p
, IAX_DELME
);
5527 static int expire_registry(void *data
)
5529 #ifdef SCHED_MULTITHREADED
5530 if (schedule_action(__expire_registry
, data
))
5532 __expire_registry(data
);
5536 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
);
5538 static void reg_source_db(struct iax2_peer
*p
)
5543 if (!ast_test_flag(p
, IAX_TEMPONLY
) && (!ast_db_get("IAX/Registry", p
->name
, data
, sizeof(data
)))) {
5544 c
= strchr(data
, ':');
5548 if (inet_aton(data
, &in
)) {
5553 if (option_verbose
> 2)
5554 ast_verbose(VERBOSE_PREFIX_3
"Seeding '%s' at %s:%d for %d\n", p
->name
,
5555 ast_inet_ntoa(in
), atoi(c
), atoi(d
));
5556 iax2_poke_peer(p
, 0);
5557 p
->expiry
= atoi(d
);
5558 memset(&p
->addr
, 0, sizeof(p
->addr
));
5559 p
->addr
.sin_family
= AF_INET
;
5560 p
->addr
.sin_addr
= in
;
5561 p
->addr
.sin_port
= htons(atoi(c
));
5563 ast_sched_del(sched
, p
->expire
);
5564 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5565 p
->expire
= ast_sched_add(sched
, (p
->expiry
+ 10) * 1000, expire_registry
, (void *)p
->name
);
5567 iax2_regfunk(p
->name
, 1);
5568 register_peer_exten(p
, 1);
5576 static int update_registry(const char *name
, struct sockaddr_in
*sin
, int callno
, char *devtype
, int fd
, unsigned short refresh
)
5578 /* Called from IAX thread only, with proper iaxsl lock */
5579 struct iax_ie_data ied
;
5580 struct iax2_peer
*p
;
5585 memset(&ied
, 0, sizeof(ied
));
5587 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
5588 if (!(p
= find_peer(name
, 1))) {
5589 ast_log(LOG_WARNING
, "No such peer '%s'\n", name
);
5593 if (ast_test_flag((&globalflags
), IAX_RTUPDATE
) && (ast_test_flag(p
, IAX_TEMPONLY
|IAX_RTCACHEFRIENDS
))) {
5594 if (sin
->sin_addr
.s_addr
) {
5597 realtime_update_peer(name
, sin
, nowtime
);
5599 realtime_update_peer(name
, sin
, 0);
5602 if (inaddrcmp(&p
->addr
, sin
)) {
5604 iax2_regfunk(p
->name
, 1);
5605 /* Stash the IP address from which they registered */
5606 memcpy(&p
->addr
, sin
, sizeof(p
->addr
));
5607 snprintf(data
, sizeof(data
), "%s:%d:%d", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), p
->expiry
);
5608 if (!ast_test_flag(p
, IAX_TEMPONLY
) && sin
->sin_addr
.s_addr
) {
5609 ast_db_put("IAX/Registry", p
->name
, data
);
5610 if (option_verbose
> 2)
5611 ast_verbose(VERBOSE_PREFIX_3
"Registered IAX2 '%s' (%s) at %s:%d\n", p
->name
,
5612 ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
5613 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p
->name
);
5614 register_peer_exten(p
, 1);
5615 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5616 } else if (!ast_test_flag(p
, IAX_TEMPONLY
)) {
5617 if (option_verbose
> 2)
5618 ast_verbose(VERBOSE_PREFIX_3
"Unregistered IAX2 '%s' (%s)\n", p
->name
,
5619 ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
) ? "AUTHENTICATED" : "UNAUTHENTICATED");
5620 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p
->name
);
5621 register_peer_exten(p
, 0);
5622 ast_db_del("IAX/Registry", p
->name
);
5623 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5625 /* Update the host */
5626 /* Verify that the host is really there */
5627 iax2_poke_peer(p
, callno
);
5630 /* Make sure our call still exists, an INVAL at the right point may make it go away */
5634 /* Store socket fd */
5636 /* Setup the expiry */
5638 ast_sched_del(sched
, p
->expire
);
5639 /* treat an unspecified refresh interval as the minimum */
5641 refresh
= min_reg_expire
;
5642 if (refresh
> max_reg_expire
) {
5643 ast_log(LOG_NOTICE
, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5644 p
->name
, max_reg_expire
, refresh
);
5645 p
->expiry
= max_reg_expire
;
5646 } else if (refresh
< min_reg_expire
) {
5647 ast_log(LOG_NOTICE
, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5648 p
->name
, min_reg_expire
, refresh
);
5649 p
->expiry
= min_reg_expire
;
5651 p
->expiry
= refresh
;
5653 if (p
->expiry
&& sin
->sin_addr
.s_addr
)
5654 p
->expire
= ast_sched_add(sched
, (p
->expiry
+ 10) * 1000, expire_registry
, (void *)p
->name
);
5655 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, p
->name
);
5656 iax_ie_append_int(&ied
, IAX_IE_DATETIME
, iax2_datetime(p
->zonetag
));
5657 if (sin
->sin_addr
.s_addr
) {
5658 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, p
->expiry
);
5659 iax_ie_append_addr(&ied
, IAX_IE_APPARENT_ADDR
, &p
->addr
);
5660 if (!ast_strlen_zero(p
->mailbox
)) {
5662 ast_app_inboxcount(p
->mailbox
, &new, &old
);
5667 msgcount
= (old
<< 8) | new;
5668 iax_ie_append_short(&ied
, IAX_IE_MSGCOUNT
, msgcount
);
5670 if (ast_test_flag(p
, IAX_HASCALLERID
)) {
5671 iax_ie_append_str(&ied
, IAX_IE_CALLING_NUMBER
, p
->cid_num
);
5672 iax_ie_append_str(&ied
, IAX_IE_CALLING_NAME
, p
->cid_name
);
5675 version
= iax_check_version(devtype
);
5677 iax_ie_append_short(&ied
, IAX_IE_FIRMWAREVER
, version
);
5678 if (ast_test_flag(p
, IAX_TEMPONLY
))
5680 return send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGACK
, 0, ied
.buf
, ied
.pos
, -1);
5683 static int registry_authrequest(const char *name
, int callno
)
5685 struct iax_ie_data ied
;
5686 struct iax2_peer
*p
;
5688 /* SLD: third call to find_peer in registration */
5689 p
= find_peer(name
, 1);
5691 memset(&ied
, 0, sizeof(ied
));
5692 iax_ie_append_short(&ied
, IAX_IE_AUTHMETHODS
, p
->authmethods
);
5693 if (p
->authmethods
& (IAX_AUTH_RSA
| IAX_AUTH_MD5
)) {
5694 /* Build the challenge */
5695 snprintf(challenge
, sizeof(challenge
), "%d", (int)ast_random());
5696 ast_string_field_set(iaxs
[callno
], challenge
, challenge
);
5697 /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */
5698 iax_ie_append_str(&ied
, IAX_IE_CHALLENGE
, iaxs
[callno
]->challenge
);
5700 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, name
);
5701 if (ast_test_flag(p
, IAX_TEMPONLY
))
5703 return send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGAUTH
, 0, ied
.buf
, ied
.pos
, -1);;
5705 ast_log(LOG_WARNING
, "No such peer '%s'\n", name
);
5709 static int registry_rerequest(struct iax_ies
*ies
, int callno
, struct sockaddr_in
*sin
)
5711 struct iax2_registry
*reg
;
5712 /* Start pessimistic */
5713 struct iax_ie_data ied
;
5714 char peer
[256] = "";
5715 char challenge
[256] = "";
5717 int authmethods
= 0;
5718 if (ies
->authmethods
)
5719 authmethods
= ies
->authmethods
;
5721 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
5723 ast_copy_string(challenge
, ies
->challenge
, sizeof(challenge
));
5724 memset(&ied
, 0, sizeof(ied
));
5725 reg
= iaxs
[callno
]->reg
;
5727 if (inaddrcmp(®
->addr
, sin
)) {
5728 ast_log(LOG_WARNING
, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin
->sin_addr
));
5731 if (ast_strlen_zero(reg
->secret
)) {
5732 ast_log(LOG_NOTICE
, "No secret associated with peer '%s'\n", reg
->username
);
5733 reg
->regstate
= REG_STATE_NOAUTH
;
5736 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, reg
->username
);
5737 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, reg
->refresh
);
5738 if (reg
->secret
[0] == '[') {
5740 ast_copy_string(tmpkey
, reg
->secret
+ 1, sizeof(tmpkey
));
5741 tmpkey
[strlen(tmpkey
) - 1] = '\0';
5742 res
= authenticate(challenge
, NULL
, tmpkey
, authmethods
, &ied
, sin
, NULL
, NULL
);
5744 res
= authenticate(challenge
, reg
->secret
, NULL
, authmethods
, &ied
, sin
, NULL
, NULL
);
5746 reg
->regstate
= REG_STATE_AUTHSENT
;
5747 return send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGREQ
, 0, ied
.buf
, ied
.pos
, -1);
5750 ast_log(LOG_WARNING
, "Registry acknowledge on unknown registery '%s'\n", peer
);
5752 ast_log(LOG_NOTICE
, "Can't reregister without a reg\n");
5756 static void stop_stuff(int callno
)
5758 iax2_destroy_helper(iaxs
[callno
]);
5761 static void __auth_reject(void *nothing
)
5763 /* Called from IAX thread only, without iaxs lock */
5764 int callno
= (int)(long)(nothing
);
5765 struct iax_ie_data ied
;
5766 ast_mutex_lock(&iaxsl
[callno
]);
5768 memset(&ied
, 0, sizeof(ied
));
5769 if (iaxs
[callno
]->authfail
== IAX_COMMAND_REGREJ
) {
5770 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Registration Refused");
5771 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_REJECTED
);
5772 } else if (iaxs
[callno
]->authfail
== IAX_COMMAND_REJECT
) {
5773 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "No authority found");
5774 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_NOT_SUBSCRIBED
);
5776 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, iaxs
[callno
]->authfail
, 0, ied
.buf
, ied
.pos
, -1);
5778 ast_mutex_unlock(&iaxsl
[callno
]);
5781 static int auth_reject(void *data
)
5783 int callno
= (int)(long)(data
);
5784 ast_mutex_lock(&iaxsl
[callno
]);
5786 iaxs
[callno
]->authid
= -1;
5787 ast_mutex_unlock(&iaxsl
[callno
]);
5788 #ifdef SCHED_MULTITHREADED
5789 if (schedule_action(__auth_reject
, data
))
5791 __auth_reject(data
);
5795 static int auth_fail(int callno
, int failcode
)
5797 /* Schedule sending the authentication failure in one second, to prevent
5799 ast_mutex_lock(&iaxsl
[callno
]);
5801 iaxs
[callno
]->authfail
= failcode
;
5803 if (iaxs
[callno
]->authid
> -1)
5804 ast_sched_del(sched
, iaxs
[callno
]->authid
);
5805 iaxs
[callno
]->authid
= ast_sched_add(sched
, 1000, auth_reject
, (void *)(long)callno
);
5807 auth_reject((void *)(long)callno
);
5809 ast_mutex_unlock(&iaxsl
[callno
]);
5813 static void __auto_hangup(void *nothing
)
5815 /* Called from IAX thread only, without iaxs lock */
5816 int callno
= (int)(long)(nothing
);
5817 struct iax_ie_data ied
;
5818 ast_mutex_lock(&iaxsl
[callno
]);
5820 memset(&ied
, 0, sizeof(ied
));
5821 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Timeout");
5822 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_USER_RESPONSE
);
5823 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_HANGUP
, 0, ied
.buf
, ied
.pos
, -1);
5825 ast_mutex_unlock(&iaxsl
[callno
]);
5828 static int auto_hangup(void *data
)
5830 int callno
= (int)(long)(data
);
5831 ast_mutex_lock(&iaxsl
[callno
]);
5833 iaxs
[callno
]->autoid
= -1;
5835 ast_mutex_unlock(&iaxsl
[callno
]);
5836 #ifdef SCHED_MULTITHREADED
5837 if (schedule_action(__auto_hangup
, data
))
5839 __auto_hangup(data
);
5843 static void iax2_dprequest(struct iax2_dpcache
*dp
, int callno
)
5845 struct iax_ie_data ied
;
5846 /* Auto-hangup with 30 seconds of inactivity */
5847 if (iaxs
[callno
]->autoid
> -1)
5848 ast_sched_del(sched
, iaxs
[callno
]->autoid
);
5849 iaxs
[callno
]->autoid
= ast_sched_add(sched
, 30000, auto_hangup
, (void *)(long)callno
);
5850 memset(&ied
, 0, sizeof(ied
));
5851 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, dp
->exten
);
5852 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_DPREQ
, 0, ied
.buf
, ied
.pos
, -1);
5853 dp
->flags
|= CACHE_FLAG_TRANSMITTED
;
5856 static int iax2_vnak(int callno
)
5858 return send_command_immediate(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_VNAK
, 0, NULL
, 0, iaxs
[callno
]->iseqno
);
5861 static void vnak_retransmit(int callno
, int last
)
5863 struct iax_frame
*f
;
5865 AST_LIST_LOCK(&iaxq
.queue
);
5866 AST_LIST_TRAVERSE(&iaxq
.queue
, f
, list
) {
5867 /* Send a copy immediately */
5868 if ((f
->callno
== callno
) && iaxs
[f
->callno
] &&
5869 (f
->oseqno
>= last
)) {
5873 AST_LIST_UNLOCK(&iaxq
.queue
);
5876 static void __iax2_poke_peer_s(void *data
)
5878 struct iax2_peer
*peer
= data
;
5879 iax2_poke_peer(peer
, 0);
5882 static int iax2_poke_peer_s(void *data
)
5884 struct iax2_peer
*peer
= data
;
5885 peer
->pokeexpire
= -1;
5886 #ifdef SCHED_MULTITHREADED
5887 if (schedule_action(__iax2_poke_peer_s
, data
))
5889 __iax2_poke_peer_s(data
);
5893 static int send_trunk(struct iax2_trunk_peer
*tpeer
, struct timeval
*now
)
5896 struct iax_frame
*fr
;
5897 struct ast_iax2_meta_hdr
*meta
;
5898 struct ast_iax2_meta_trunk_hdr
*mth
;
5901 /* Point to frame */
5902 fr
= (struct iax_frame
*)tpeer
->trunkdata
;
5903 /* Point to meta data */
5904 meta
= (struct ast_iax2_meta_hdr
*)fr
->afdata
;
5905 mth
= (struct ast_iax2_meta_trunk_hdr
*)meta
->data
;
5906 if (tpeer
->trunkdatalen
) {
5907 /* We're actually sending a frame, so fill the meta trunk header and meta header */
5909 meta
->metacmd
= IAX_META_TRUNK
;
5910 if (ast_test_flag(&globalflags
, IAX_TRUNKTIMESTAMPS
))
5911 meta
->cmddata
= IAX_META_TRUNK_MINI
;
5913 meta
->cmddata
= IAX_META_TRUNK_SUPERMINI
;
5914 mth
->ts
= htonl(calc_txpeerstamp(tpeer
, trunkfreq
, now
));
5915 /* And the rest of the ast_iax2 header */
5916 fr
->direction
= DIRECTION_OUTGRESS
;
5919 /* Any appropriate call will do */
5920 fr
->data
= fr
->afdata
;
5921 fr
->datalen
= tpeer
->trunkdatalen
+ sizeof(struct ast_iax2_meta_hdr
) + sizeof(struct ast_iax2_meta_trunk_hdr
);
5922 res
= transmit_trunk(fr
, &tpeer
->addr
, tpeer
->sockfd
);
5923 calls
= tpeer
->calls
;
5925 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
));
5927 /* Reset transmit trunk side data */
5928 tpeer
->trunkdatalen
= 0;
5936 static inline int iax2_trunk_expired(struct iax2_trunk_peer
*tpeer
, struct timeval
*now
)
5938 /* Drop when trunk is about 5 seconds idle */
5939 if (now
->tv_sec
> tpeer
->trunkact
.tv_sec
+ 5)
5944 static int timing_read(int *id
, int fd
, short events
, void *cbdata
)
5948 struct iax2_trunk_peer
*tpeer
, *prev
= NULL
, *drop
=NULL
;
5956 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA
);
5957 gettimeofday(&now
, NULL
);
5958 if (events
& AST_IO_PRI
) {
5960 /* Great, this is a timing interface, just call the ioctl */
5961 if (ioctl(fd
, ZT_TIMERACK
, &x
))
5962 ast_log(LOG_WARNING
, "Unable to acknowledge zap timer\n");
5966 /* Read and ignore from the pseudo channel for timing */
5967 res
= read(fd
, buf
, sizeof(buf
));
5969 ast_log(LOG_WARNING
, "Unable to read from timing fd\n");
5973 /* For each peer that supports trunking... */
5974 ast_mutex_lock(&tpeerlock
);
5979 ast_mutex_lock(&tpeer
->lock
);
5980 /* We can drop a single tpeer per pass. That makes all this logic
5981 substantially easier */
5982 if (!drop
&& iax2_trunk_expired(tpeer
, &now
)) {
5983 /* Take it out of the list, but don't free it yet, because it
5986 prev
->next
= tpeer
->next
;
5988 tpeers
= tpeer
->next
;
5991 res
= send_trunk(tpeer
, &now
);
5993 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
);
5997 ast_mutex_unlock(&tpeer
->lock
);
5999 tpeer
= tpeer
->next
;
6001 ast_mutex_unlock(&tpeerlock
);
6003 ast_mutex_lock(&drop
->lock
);
6004 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
6005 because by the time they could get tpeerlock, we've already grabbed it */
6006 ast_log(LOG_DEBUG
, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop
->addr
.sin_addr
), ntohs(drop
->addr
.sin_port
));
6007 free(drop
->trunkdata
);
6008 ast_mutex_unlock(&drop
->lock
);
6009 ast_mutex_destroy(&drop
->lock
);
6014 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed
, totalcalls
);
6021 char context
[AST_MAX_EXTENSION
];
6022 char callednum
[AST_MAX_EXTENSION
];
6026 static void dp_lookup(int callno
, const char *context
, const char *callednum
, const char *callerid
, int skiplock
)
6028 unsigned short dpstatus
= 0;
6029 struct iax_ie_data ied1
;
6032 memset(&ied1
, 0, sizeof(ied1
));
6033 mm
= ast_matchmore_extension(NULL
, context
, callednum
, 1, callerid
);
6034 /* Must be started */
6035 if (!strcmp(callednum
, ast_parking_ext()) || ast_exists_extension(NULL
, context
, callednum
, 1, callerid
)) {
6036 dpstatus
= IAX_DPSTATUS_EXISTS
;
6037 } else if (ast_canmatch_extension(NULL
, context
, callednum
, 1, callerid
)) {
6038 dpstatus
= IAX_DPSTATUS_CANEXIST
;
6040 dpstatus
= IAX_DPSTATUS_NONEXISTENT
;
6042 if (ast_ignore_pattern(context
, callednum
))
6043 dpstatus
|= IAX_DPSTATUS_IGNOREPAT
;
6045 dpstatus
|= IAX_DPSTATUS_MATCHMORE
;
6047 ast_mutex_lock(&iaxsl
[callno
]);
6049 iax_ie_append_str(&ied1
, IAX_IE_CALLED_NUMBER
, callednum
);
6050 iax_ie_append_short(&ied1
, IAX_IE_DPSTATUS
, dpstatus
);
6051 iax_ie_append_short(&ied1
, IAX_IE_REFRESH
, iaxdefaultdpcache
);
6052 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_DPREP
, 0, ied1
.buf
, ied1
.pos
, -1);
6055 ast_mutex_unlock(&iaxsl
[callno
]);
6058 static void *dp_lookup_thread(void *data
)
6060 /* Look up for dpreq */
6061 struct dpreq_data
*dpr
= data
;
6062 dp_lookup(dpr
->callno
, dpr
->context
, dpr
->callednum
, dpr
->callerid
, 0);
6064 free(dpr
->callerid
);
6069 static void spawn_dp_lookup(int callno
, const char *context
, const char *callednum
, const char *callerid
)
6071 pthread_t newthread
;
6072 struct dpreq_data
*dpr
;
6073 pthread_attr_t attr
;
6075 if (!(dpr
= ast_calloc(1, sizeof(*dpr
))))
6078 pthread_attr_init(&attr
);
6079 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
6081 dpr
->callno
= callno
;
6082 ast_copy_string(dpr
->context
, context
, sizeof(dpr
->context
));
6083 ast_copy_string(dpr
->callednum
, callednum
, sizeof(dpr
->callednum
));
6085 dpr
->callerid
= ast_strdup(callerid
);
6086 if (ast_pthread_create(&newthread
, &attr
, dp_lookup_thread
, dpr
)) {
6087 ast_log(LOG_WARNING
, "Unable to start lookup thread!\n");
6090 pthread_attr_destroy(&attr
);
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, AST_STATE_DOWN
, 0, 0, chan2
->accountcode
, chan1
->exten
, chan1
->context
, chan1
->amaflags
, "Parking/%s", chan1
->name
);
6124 chan2m
= ast_channel_alloc(0, AST_STATE_DOWN
, 0, 0, chan2
->accountcode
, chan2
->exten
, chan2
->context
, chan2
->amaflags
, "IAXPeer/%s",chan2
->name
);
6125 if (chan2m
&& chan1m
) {
6126 /* Make formats okay */
6127 chan1m
->readformat
= chan1
->readformat
;
6128 chan1m
->writeformat
= chan1
->writeformat
;
6129 ast_channel_masquerade(chan1m
, chan1
);
6130 /* Setup the extensions and such */
6131 ast_copy_string(chan1m
->context
, chan1
->context
, sizeof(chan1m
->context
));
6132 ast_copy_string(chan1m
->exten
, chan1
->exten
, sizeof(chan1m
->exten
));
6133 chan1m
->priority
= chan1
->priority
;
6135 /* We make a clone of the peer channel too, so we can play
6136 back the announcement */
6137 /* Make formats okay */
6138 chan2m
->readformat
= chan2
->readformat
;
6139 chan2m
->writeformat
= chan2
->writeformat
;
6140 ast_channel_masquerade(chan2m
, chan2
);
6141 /* Setup the extensions and such */
6142 ast_copy_string(chan2m
->context
, chan2
->context
, sizeof(chan2m
->context
));
6143 ast_copy_string(chan2m
->exten
, chan2
->exten
, sizeof(chan2m
->exten
));
6144 chan2m
->priority
= chan2
->priority
;
6145 if (ast_do_masquerade(chan2m
)) {
6146 ast_log(LOG_WARNING
, "Masquerade failed :(\n");
6157 if ((d
= ast_calloc(1, sizeof(*d
)))) {
6158 pthread_attr_t attr
;
6160 pthread_attr_init(&attr
);
6161 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
6165 if (!ast_pthread_create_background(&th
, &attr
, iax_park_thread
, d
)) {
6166 pthread_attr_destroy(&attr
);
6169 pthread_attr_destroy(&attr
);
6176 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
);
6178 static int check_provisioning(struct sockaddr_in
*sin
, int sockfd
, char *si
, unsigned int ver
)
6180 unsigned int ourver
;
6182 snprintf(rsi
, sizeof(rsi
), "si-%s", si
);
6183 if (iax_provision_version(&ourver
, rsi
, 1))
6186 ast_log(LOG_DEBUG
, "Service identifier '%s', we think '%08x', they think '%08x'\n", si
, ourver
, ver
);
6188 iax2_provision(sin
, sockfd
, NULL
, rsi
, 1);
6192 static void construct_rr(struct chan_iax2_pvt
*pvt
, struct iax_ie_data
*iep
)
6195 jb_getinfo(pvt
->jb
, &stats
);
6197 memset(iep
, 0, sizeof(*iep
));
6199 iax_ie_append_int(iep
,IAX_IE_RR_JITTER
, stats
.jitter
);
6200 if(stats
.frames_in
== 0) stats
.frames_in
= 1;
6201 iax_ie_append_int(iep
,IAX_IE_RR_LOSS
, ((0xff & (stats
.losspct
/1000)) << 24 | (stats
.frames_lost
& 0x00ffffff)));
6202 iax_ie_append_int(iep
,IAX_IE_RR_PKTS
, stats
.frames_in
);
6203 iax_ie_append_short(iep
,IAX_IE_RR_DELAY
, stats
.current
- stats
.min
);
6204 iax_ie_append_int(iep
,IAX_IE_RR_DROPPED
, stats
.frames_dropped
);
6205 iax_ie_append_int(iep
,IAX_IE_RR_OOO
, stats
.frames_ooo
);
6208 static void save_rr(struct iax_frame
*fr
, struct iax_ies
*ies
)
6210 iaxs
[fr
->callno
]->remote_rr
.jitter
= ies
->rr_jitter
;
6211 iaxs
[fr
->callno
]->remote_rr
.losspct
= ies
->rr_loss
>> 24;
6212 iaxs
[fr
->callno
]->remote_rr
.losscnt
= ies
->rr_loss
& 0xffffff;
6213 iaxs
[fr
->callno
]->remote_rr
.packets
= ies
->rr_pkts
;
6214 iaxs
[fr
->callno
]->remote_rr
.delay
= ies
->rr_delay
;
6215 iaxs
[fr
->callno
]->remote_rr
.dropped
= ies
->rr_dropped
;
6216 iaxs
[fr
->callno
]->remote_rr
.ooo
= ies
->rr_ooo
;
6219 static int socket_read(int *id
, int fd
, short events
, void *cbdata
)
6221 struct iax2_thread
*thread
;
6224 static time_t last_errtime
=0;
6226 thread
= find_idle_thread();
6228 len
= sizeof(thread
->iosin
);
6230 thread
->iores
= recvfrom(fd
, thread
->buf
, sizeof(thread
->buf
), 0,(struct sockaddr
*) &thread
->iosin
, &len
);
6231 if (thread
->iores
< 0) {
6232 if (errno
!= ECONNREFUSED
&& errno
!= EAGAIN
)
6233 ast_log(LOG_WARNING
, "Error: %s\n", strerror(errno
));
6235 insert_idle_thread(thread
);
6238 if (test_losspct
&& ((100.0 * ast_random() / (RAND_MAX
+ 1.0)) < test_losspct
)) { /* simulate random loss condition */
6239 insert_idle_thread(thread
);
6242 /* Mark as ready and send on its way */
6243 thread
->iostate
= IAX_IOSTATE_READY
;
6244 #ifdef DEBUG_SCHED_MULTITHREAD
6245 ast_copy_string(thread
->curfunc
, "socket_process", sizeof(thread
->curfunc
));
6247 signal_condition(&thread
->lock
, &thread
->cond
);
6250 if (t
!= last_errtime
)
6251 ast_log(LOG_NOTICE
, "Out of idle IAX2 threads for I/O, pausing!\n");
6258 static int socket_process(struct iax2_thread
*thread
)
6260 struct sockaddr_in sin
;
6262 int updatehistory
=1;
6263 int new = NEW_PREVENT
;
6266 struct ast_iax2_full_hdr
*fh
= (struct ast_iax2_full_hdr
*)thread
->buf
;
6267 struct ast_iax2_mini_hdr
*mh
= (struct ast_iax2_mini_hdr
*)thread
->buf
;
6268 struct ast_iax2_meta_hdr
*meta
= (struct ast_iax2_meta_hdr
*)thread
->buf
;
6269 struct ast_iax2_video_hdr
*vh
= (struct ast_iax2_video_hdr
*)thread
->buf
;
6270 struct ast_iax2_meta_trunk_hdr
*mth
;
6271 struct ast_iax2_meta_trunk_entry
*mte
;
6272 struct ast_iax2_meta_trunk_mini
*mtm
;
6273 struct iax_frame
*fr
;
6274 struct iax_frame
*cur
;
6275 struct ast_frame f
= { 0, };
6276 struct ast_channel
*c
;
6277 struct iax2_dpcache
*dp
;
6278 struct iax2_peer
*peer
;
6279 struct iax2_trunk_peer
*tpeer
;
6280 struct timeval rxtrunktime
;
6282 struct iax_ie_data ied0
, ied1
;
6288 char empty
[32]=""; /* Safety measure */
6289 struct iax_frame
*duped_fr
;
6290 char host_pref_buf
[128];
6291 char caller_pref_buf
[128];
6292 struct ast_codec_pref pref
;
6293 char *using_prefs
= "mine";
6295 /* allocate an iax_frame with 4096 bytes of data buffer */
6296 fr
= alloca(sizeof(*fr
) + 4096);
6299 /* Copy frequently used parameters to the stack */
6300 res
= thread
->iores
;
6302 memcpy(&sin
, &thread
->iosin
, sizeof(sin
));
6304 if (res
< sizeof(*mh
)) {
6305 ast_log(LOG_WARNING
, "midget packet received (%d of %zd min)\n", res
, sizeof(*mh
));
6308 if ((vh
->zeros
== 0) && (ntohs(vh
->callno
) & 0x8000)) {
6309 if (res
< sizeof(*vh
)) {
6310 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
));
6314 /* This is a video frame, get call number */
6315 fr
->callno
= find_callno(ntohs(vh
->callno
) & ~0x8000, dcallno
, &sin
, new, 1, fd
);
6317 } else if ((meta
->zeros
== 0) && !(ntohs(meta
->metacmd
) & 0x8000)) {
6318 unsigned char metatype
;
6320 if (res
< sizeof(*meta
)) {
6321 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
));
6325 /* This is a meta header */
6326 switch(meta
->metacmd
) {
6327 case IAX_META_TRUNK
:
6328 if (res
< (sizeof(*meta
) + sizeof(*mth
))) {
6329 ast_log(LOG_WARNING
, "midget meta trunk packet received (%d of %zd min)\n", res
,
6330 sizeof(*meta
) + sizeof(*mth
));
6333 mth
= (struct ast_iax2_meta_trunk_hdr
*)(meta
->data
);
6334 ts
= ntohl(mth
->ts
);
6335 metatype
= meta
->cmddata
;
6336 res
-= (sizeof(*meta
) + sizeof(*mth
));
6338 tpeer
= find_tpeer(&sin
, fd
);
6340 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
));
6343 tpeer
->trunkact
= ast_tvnow();
6344 if (!ts
|| ast_tvzero(tpeer
->rxtrunktime
))
6345 tpeer
->rxtrunktime
= tpeer
->trunkact
;
6346 rxtrunktime
= tpeer
->rxtrunktime
;
6347 ast_mutex_unlock(&tpeer
->lock
);
6348 while(res
>= sizeof(*mte
)) {
6349 /* Process channels */
6350 unsigned short callno
, trunked_ts
, len
;
6352 if (metatype
== IAX_META_TRUNK_MINI
) {
6353 mtm
= (struct ast_iax2_meta_trunk_mini
*)ptr
;
6354 ptr
+= sizeof(*mtm
);
6355 res
-= sizeof(*mtm
);
6356 len
= ntohs(mtm
->len
);
6357 callno
= ntohs(mtm
->mini
.callno
);
6358 trunked_ts
= ntohs(mtm
->mini
.ts
);
6359 } else if (metatype
== IAX_META_TRUNK_SUPERMINI
) {
6360 mte
= (struct ast_iax2_meta_trunk_entry
*)ptr
;
6361 ptr
+= sizeof(*mte
);
6362 res
-= sizeof(*mte
);
6363 len
= ntohs(mte
->len
);
6364 callno
= ntohs(mte
->callno
);
6367 ast_log(LOG_WARNING
, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin
.sin_addr
), ntohs(sin
.sin_port
));
6370 /* Stop if we don't have enough data */
6373 fr
->callno
= find_callno(callno
& ~IAX_FLAG_FULL
, 0, &sin
, NEW_PREVENT
, 1, fd
);
6375 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6376 /* If it's a valid call, deliver the contents. If not, we
6377 drop it, since we don't have a scallno to use for an INVAL */
6378 /* Process as a mini frame */
6379 memset(&f
, 0, sizeof(f
));
6380 f
.frametype
= AST_FRAME_VOICE
;
6381 if (iaxs
[fr
->callno
]) {
6382 if (iaxs
[fr
->callno
]->voiceformat
> 0) {
6383 f
.subclass
= iaxs
[fr
->callno
]->voiceformat
;
6385 if (f
.datalen
>= 0) {
6389 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | (trunked_ts
& 0xffff);
6391 fr
->ts
= fix_peerts(&rxtrunktime
, fr
->callno
, ts
);
6392 /* Don't pass any packets until we're started */
6393 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6396 if (f
.datalen
&& (f
.frametype
== AST_FRAME_VOICE
))
6397 f
.samples
= ast_codec_get_samples(&f
);
6398 iax_frame_wrap(fr
, &f
);
6399 duped_fr
= iaxfrdup2(fr
);
6401 schedule_delivery(duped_fr
, updatehistory
, 1, &fr
->ts
);
6403 /* It is possible for the pvt structure to go away after we call schedule_delivery */
6404 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->last
< fr
->ts
) {
6405 iaxs
[fr
->callno
]->last
= fr
->ts
;
6407 if (option_debug
&& iaxdebug
)
6408 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
6413 ast_log(LOG_WARNING
, "Datalen < 0?\n");
6416 ast_log(LOG_WARNING
, "Received trunked frame before first full voice frame\n ");
6417 iax2_vnak(fr
->callno
);
6420 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6430 #ifdef DEBUG_SUPPORT
6431 if (iaxdebug
&& (res
>= sizeof(*fh
)))
6432 iax_showframe(NULL
, fh
, 1, &sin
, res
- sizeof(*fh
));
6434 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6435 if (res
< sizeof(*fh
)) {
6436 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
));
6440 /* Get the destination call number */
6441 dcallno
= ntohs(fh
->dcallno
) & ~IAX_FLAG_RETRANS
;
6442 /* Retrieve the type and subclass */
6443 f
.frametype
= fh
->type
;
6444 if (f
.frametype
== AST_FRAME_VIDEO
) {
6445 f
.subclass
= uncompress_subclass(fh
->csub
& ~0x40) | ((fh
->csub
>> 6) & 0x1);
6447 f
.subclass
= uncompress_subclass(fh
->csub
);
6449 if ((f
.frametype
== AST_FRAME_IAX
) && ((f
.subclass
== IAX_COMMAND_NEW
) || (f
.subclass
== IAX_COMMAND_REGREQ
) ||
6450 (f
.subclass
== IAX_COMMAND_POKE
) || (f
.subclass
== IAX_COMMAND_FWDOWNL
) ||
6451 (f
.subclass
== IAX_COMMAND_REGREL
)))
6454 /* Don't know anything about it yet */
6455 f
.frametype
= AST_FRAME_NULL
;
6460 fr
->callno
= find_callno(ntohs(mh
->callno
) & ~IAX_FLAG_FULL
, dcallno
, &sin
, new, 1, fd
);
6463 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6465 if (!fr
->callno
|| !iaxs
[fr
->callno
]) {
6466 /* A call arrived for a nonexistent destination. Unless it's an "inval"
6467 frame, reply with an inval */
6468 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6469 /* We can only raw hangup control frames */
6470 if (((f
.subclass
!= IAX_COMMAND_INVAL
) &&
6471 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6472 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6473 (f
.subclass
!= IAX_COMMAND_FWDOWNL
))||
6474 (f
.frametype
!= AST_FRAME_IAX
))
6475 raw_hangup(&sin
, ntohs(fh
->dcallno
) & ~IAX_FLAG_RETRANS
, ntohs(mh
->callno
) & ~IAX_FLAG_FULL
,
6479 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6482 if (ast_test_flag(iaxs
[fr
->callno
], IAX_ENCRYPTED
)) {
6483 if (decrypt_frame(fr
->callno
, fh
, &f
, &res
)) {
6484 ast_log(LOG_NOTICE
, "Packet Decrypt Failed!\n");
6485 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6488 #ifdef DEBUG_SUPPORT
6490 iax_showframe(NULL
, fh
, 3, &sin
, res
- sizeof(*fh
));
6494 /* count this frame */
6495 iaxs
[fr
->callno
]->frames_received
++;
6497 if (!inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) && !minivid
&&
6498 f
.subclass
!= IAX_COMMAND_TXCNT
&& /* for attended transfer */
6499 f
.subclass
!= IAX_COMMAND_TXACC
) /* for attended transfer */
6500 iaxs
[fr
->callno
]->peercallno
= (unsigned short)(ntohs(mh
->callno
) & ~IAX_FLAG_FULL
);
6501 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6502 if (option_debug
&& iaxdebug
)
6503 ast_log(LOG_DEBUG
, "Received packet %d, (%d, %d)\n", fh
->oseqno
, f
.frametype
, f
.subclass
);
6504 /* Check if it's out of order (and not an ACK or INVAL) */
6505 fr
->oseqno
= fh
->oseqno
;
6506 fr
->iseqno
= fh
->iseqno
;
6507 fr
->ts
= ntohl(fh
->ts
);
6511 ast_log(LOG_DEBUG
, "Simulating frame ts resync, was %u now %u\n", fr
->ts
, fr
->ts
+ test_resync
);
6512 fr
->ts
+= test_resync
;
6514 #endif /* IAXTESTS */
6516 if ( (ntohs(fh
->dcallno
) & IAX_FLAG_RETRANS
) ||
6517 ( (f
.frametype
!= AST_FRAME_VOICE
) && ! (f
.frametype
== AST_FRAME_IAX
&&
6518 (f
.subclass
== IAX_COMMAND_NEW
||
6519 f
.subclass
== IAX_COMMAND_AUTHREQ
||
6520 f
.subclass
== IAX_COMMAND_ACCEPT
||
6521 f
.subclass
== IAX_COMMAND_REJECT
)) ) )
6523 if ((ntohs(fh
->dcallno
) & IAX_FLAG_RETRANS
) || (f
.frametype
!= AST_FRAME_VOICE
))
6525 if ((iaxs
[fr
->callno
]->iseqno
!= fr
->oseqno
) &&
6526 (iaxs
[fr
->callno
]->iseqno
||
6527 ((f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6528 (f
.subclass
!= IAX_COMMAND_TXREADY
) && /* for attended transfer */
6529 (f
.subclass
!= IAX_COMMAND_TXREL
) && /* for attended transfer */
6530 (f
.subclass
!= IAX_COMMAND_UNQUELCH
) && /* for attended transfer */
6531 (f
.subclass
!= IAX_COMMAND_TXACC
)) ||
6532 (f
.frametype
!= AST_FRAME_IAX
))) {
6534 ((f
.subclass
!= IAX_COMMAND_ACK
) &&
6535 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
6536 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6537 (f
.subclass
!= IAX_COMMAND_TXREADY
) && /* for attended transfer */
6538 (f
.subclass
!= IAX_COMMAND_TXREL
) && /* for attended transfer */
6539 (f
.subclass
!= IAX_COMMAND_UNQUELCH
) && /* for attended transfer */
6540 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6541 (f
.subclass
!= IAX_COMMAND_VNAK
)) ||
6542 (f
.frametype
!= AST_FRAME_IAX
)) {
6543 /* If it's not an ACK packet, it's out of order. */
6545 ast_log(LOG_DEBUG
, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
6546 iaxs
[fr
->callno
]->iseqno
, fr
->oseqno
, f
.frametype
, f
.subclass
);
6547 if (iaxs
[fr
->callno
]->iseqno
> fr
->oseqno
) {
6548 /* If we've already seen it, ack it XXX There's a border condition here XXX */
6549 if ((f
.frametype
!= AST_FRAME_IAX
) ||
6550 ((f
.subclass
!= IAX_COMMAND_ACK
) && (f
.subclass
!= IAX_COMMAND_INVAL
))) {
6552 ast_log(LOG_DEBUG
, "Acking anyway\n");
6553 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
6554 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
6555 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6558 /* Send a VNAK requesting retransmission */
6559 iax2_vnak(fr
->callno
);
6561 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6565 /* Increment unless it's an ACK or VNAK */
6566 if (((f
.subclass
!= IAX_COMMAND_ACK
) &&
6567 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
6568 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6569 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6570 (f
.subclass
!= IAX_COMMAND_VNAK
)) ||
6571 (f
.frametype
!= AST_FRAME_IAX
))
6572 iaxs
[fr
->callno
]->iseqno
++;
6575 if (res
< sizeof(*fh
)) {
6576 ast_log(LOG_WARNING
, "midget packet received (%d of %zd min)\n", res
, sizeof(*fh
));
6577 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6580 /* Ensure text frames are NULL-terminated */
6581 if (f
.frametype
== AST_FRAME_TEXT
&& thread
->buf
[res
- 1] != '\0') {
6582 if (res
< sizeof(thread
->buf
))
6583 thread
->buf
[res
++] = '\0';
6584 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
6585 thread
->buf
[res
- 1] = '\0';
6587 f
.datalen
= res
- sizeof(*fh
);
6589 /* Handle implicit ACKing unless this is an INVAL, and only if this is
6590 from the real peer, not the transfer peer */
6591 if (!inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) &&
6592 ((f
.subclass
!= IAX_COMMAND_INVAL
) ||
6593 (f
.frametype
!= AST_FRAME_IAX
))) {
6595 /* XXX This code is not very efficient. Surely there is a better way which still
6596 properly handles boundary conditions? XXX */
6597 /* First we have to qualify that the ACKed value is within our window */
6598 for (x
=iaxs
[fr
->callno
]->rseqno
; x
!= iaxs
[fr
->callno
]->oseqno
; x
++)
6599 if (fr
->iseqno
== x
)
6601 if ((x
!= iaxs
[fr
->callno
]->oseqno
) || (iaxs
[fr
->callno
]->oseqno
== fr
->iseqno
)) {
6602 /* The acknowledgement is within our window. Time to acknowledge everything
6604 for (x
=iaxs
[fr
->callno
]->rseqno
; x
!= fr
->iseqno
; x
++) {
6605 /* Ack the packet with the given timestamp */
6606 if (option_debug
&& iaxdebug
)
6607 ast_log(LOG_DEBUG
, "Cancelling transmission of packet %d\n", x
);
6608 AST_LIST_LOCK(&iaxq
.queue
);
6609 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
6610 /* If it's our call, and our timestamp, mark -1 retries */
6611 if ((fr
->callno
== cur
->callno
) && (x
== cur
->oseqno
)) {
6613 /* Destroy call if this is the end */
6615 if (iaxdebug
&& option_debug
)
6616 ast_log(LOG_DEBUG
, "Really destroying %d, having been acked on final message\n", fr
->callno
);
6617 iax2_destroy(fr
->callno
);
6621 AST_LIST_UNLOCK(&iaxq
.queue
);
6623 /* Note how much we've received acknowledgement for */
6624 if (iaxs
[fr
->callno
])
6625 iaxs
[fr
->callno
]->rseqno
= fr
->iseqno
;
6627 /* Stop processing now */
6628 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6632 ast_log(LOG_DEBUG
, "Received iseqno %d not within window %d->%d\n", fr
->iseqno
, iaxs
[fr
->callno
]->rseqno
, iaxs
[fr
->callno
]->oseqno
);
6634 if (inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) &&
6635 ((f
.frametype
!= AST_FRAME_IAX
) ||
6636 ((f
.subclass
!= IAX_COMMAND_TXACC
) &&
6637 (f
.subclass
!= IAX_COMMAND_TXCNT
)))) {
6638 /* Only messages we accept from a transfer host are TXACC and TXCNT */
6639 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6644 if (f
.frametype
== AST_FRAME_IAX
) {
6645 if (iax_parse_ies(&ies
, thread
->buf
+ sizeof(*fh
), f
.datalen
)) {
6646 ast_log(LOG_WARNING
, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin
.sin_addr
));
6647 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6652 f
.data
= thread
->buf
+ sizeof(*fh
);
6654 if (f
.frametype
== AST_FRAME_IAX
)
6658 memset(&ies
, 0, sizeof(ies
));
6660 if (f
.frametype
== AST_FRAME_VOICE
) {
6661 if (f
.subclass
!= iaxs
[fr
->callno
]->voiceformat
) {
6662 iaxs
[fr
->callno
]->voiceformat
= f
.subclass
;
6663 ast_log(LOG_DEBUG
, "Ooh, voice format changed to %d\n", f
.subclass
);
6664 if (iaxs
[fr
->callno
]->owner
) {
6667 if (ast_mutex_trylock(&iaxs
[fr
->callno
]->owner
->lock
)) {
6668 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6670 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6671 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) goto retryowner
;
6673 if (iaxs
[fr
->callno
]) {
6674 if (iaxs
[fr
->callno
]->owner
) {
6675 orignative
= iaxs
[fr
->callno
]->owner
->nativeformats
;
6676 iaxs
[fr
->callno
]->owner
->nativeformats
= f
.subclass
;
6677 if (iaxs
[fr
->callno
]->owner
->readformat
)
6678 ast_set_read_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->readformat
);
6679 iaxs
[fr
->callno
]->owner
->nativeformats
= orignative
;
6680 ast_mutex_unlock(&iaxs
[fr
->callno
]->owner
->lock
);
6683 ast_log(LOG_DEBUG
, "Neat, somebody took away the channel at a magical time but i found it!\n");
6684 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6690 if (f
.frametype
== AST_FRAME_VIDEO
) {
6691 if (f
.subclass
!= iaxs
[fr
->callno
]->videoformat
) {
6692 ast_log(LOG_DEBUG
, "Ooh, video format changed to %d\n", f
.subclass
& ~0x1);
6693 iaxs
[fr
->callno
]->videoformat
= f
.subclass
& ~0x1;
6696 if (f
.frametype
== AST_FRAME_IAX
) {
6697 if (iaxs
[fr
->callno
]->initid
> -1) {
6698 /* Don't auto congest anymore since we've gotten something usefulb ack */
6699 ast_sched_del(sched
, iaxs
[fr
->callno
]->initid
);
6700 iaxs
[fr
->callno
]->initid
= -1;
6702 /* Handle the IAX pseudo frame itself */
6703 if (option_debug
&& iaxdebug
)
6704 ast_log(LOG_DEBUG
, "IAX subclass %d received\n", f
.subclass
);
6706 /* Update last ts unless the frame's timestamp originated with us. */
6707 if (iaxs
[fr
->callno
]->last
< fr
->ts
&&
6708 f
.subclass
!= IAX_COMMAND_ACK
&&
6709 f
.subclass
!= IAX_COMMAND_PONG
&&
6710 f
.subclass
!= IAX_COMMAND_LAGRP
) {
6711 iaxs
[fr
->callno
]->last
= fr
->ts
;
6712 if (option_debug
&& iaxdebug
)
6713 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
6716 if (ast_test_flag(iaxs
[fr
->callno
], IAX_DELAYPBXSTART
)) {
6717 if (ast_pbx_start(iaxs
[fr
->callno
]->owner
)) {
6718 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", iaxs
[fr
->callno
]->owner
->name
);
6719 ast_hangup(iaxs
[fr
->callno
]->owner
);
6720 iaxs
[fr
->callno
]->owner
= NULL
;
6721 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6726 switch(f
.subclass
) {
6727 case IAX_COMMAND_ACK
:
6730 case IAX_COMMAND_QUELCH
:
6731 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6732 /* Generate Manager Hold event, if necessary*/
6733 if (iaxs
[fr
->callno
]->owner
) {
6734 manager_event(EVENT_FLAG_CALL
, "Hold",
6737 iaxs
[fr
->callno
]->owner
->name
,
6738 iaxs
[fr
->callno
]->owner
->uniqueid
);
6741 ast_set_flag(iaxs
[fr
->callno
], IAX_QUELCH
);
6742 if (ies
.musiconhold
) {
6743 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
)) {
6744 const char *mohsuggest
= iaxs
[fr
->callno
]->mohsuggest
;
6745 ast_queue_control_data(iaxs
[fr
->callno
]->owner
, AST_CONTROL_HOLD
,
6746 S_OR(mohsuggest
, NULL
),
6747 !ast_strlen_zero(mohsuggest
) ? strlen(mohsuggest
) + 1 : 0);
6752 case IAX_COMMAND_UNQUELCH
:
6753 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6754 /* Generate Manager Unhold event, if necessary*/
6755 if (iaxs
[fr
->callno
]->owner
&& ast_test_flag(iaxs
[fr
->callno
], IAX_QUELCH
)) {
6756 manager_event(EVENT_FLAG_CALL
, "Unhold",
6759 iaxs
[fr
->callno
]->owner
->name
,
6760 iaxs
[fr
->callno
]->owner
->uniqueid
);
6763 ast_clear_flag(iaxs
[fr
->callno
], IAX_QUELCH
);
6764 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
))
6765 ast_queue_control(iaxs
[fr
->callno
]->owner
, AST_CONTROL_UNHOLD
);
6768 case IAX_COMMAND_TXACC
:
6769 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_BEGIN
) {
6770 /* Ack the packet with the given timestamp */
6771 AST_LIST_LOCK(&iaxq
.queue
);
6772 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
6773 /* Cancel any outstanding txcnt's */
6774 if ((fr
->callno
== cur
->callno
) && (cur
->transfer
))
6777 AST_LIST_UNLOCK(&iaxq
.queue
);
6778 memset(&ied1
, 0, sizeof(ied1
));
6779 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->callno
);
6780 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREADY
, 0, ied1
.buf
, ied1
.pos
, -1);
6781 iaxs
[fr
->callno
]->transferring
= TRANSFER_READY
;
6784 case IAX_COMMAND_NEW
:
6785 /* Ignore if it's already up */
6786 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
))
6788 if (ies
.provverpres
&& ies
.serviceident
&& sin
.sin_addr
.s_addr
)
6789 check_provisioning(&sin
, fd
, ies
.serviceident
, ies
.provver
);
6790 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
6791 if (ast_test_flag(iaxs
[fr
->callno
], IAX_TRUNK
)) {
6792 fr
->callno
= make_trunk(fr
->callno
, 1);
6794 /* For security, always ack immediately */
6796 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6797 if (check_access(fr
->callno
, &sin
, &ies
)) {
6798 /* They're not allowed on */
6799 auth_fail(fr
->callno
, IAX_COMMAND_REJECT
);
6801 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
);
6804 /* This might re-enter the IAX code and need the lock */
6805 if (strcasecmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
6806 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6807 exists
= ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
);
6808 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6811 if (ast_strlen_zero(iaxs
[fr
->callno
]->secret
) && ast_strlen_zero(iaxs
[fr
->callno
]->inkeys
)) {
6812 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD") && !exists
) {
6813 memset(&ied0
, 0, sizeof(ied0
));
6814 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
6815 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
6816 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6818 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
);
6820 /* Select an appropriate format */
6822 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
6823 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
6824 using_prefs
= "reqonly";
6826 using_prefs
= "disabled";
6828 format
= iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
;
6829 memset(&pref
, 0, sizeof(pref
));
6830 strcpy(caller_pref_buf
, "disabled");
6831 strcpy(host_pref_buf
, "disabled");
6833 using_prefs
= "mine";
6834 /* If the information elements are in here... use them */
6835 if (ies
.codec_prefs
)
6836 ast_codec_pref_convert(&iaxs
[fr
->callno
]->rprefs
, ies
.codec_prefs
, 32, 0);
6837 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
6838 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
6839 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
6840 pref
= iaxs
[fr
->callno
]->rprefs
;
6841 using_prefs
= "caller";
6843 pref
= iaxs
[fr
->callno
]->prefs
;
6846 pref
= iaxs
[fr
->callno
]->prefs
;
6848 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->capability
& iaxs
[fr
->callno
]->peercapability
, 0);
6849 ast_codec_pref_string(&iaxs
[fr
->callno
]->rprefs
, caller_pref_buf
, sizeof(caller_pref_buf
) - 1);
6850 ast_codec_pref_string(&iaxs
[fr
->callno
]->prefs
, host_pref_buf
, sizeof(host_pref_buf
) - 1);
6853 if(!ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
6854 format
= iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
;
6856 memset(&ied0
, 0, sizeof(ied0
));
6857 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
6858 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
6859 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6861 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
6862 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
);
6864 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
);
6868 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
6869 if(!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
))
6872 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
6873 using_prefs
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ? "reqonly" : "disabled";
6874 memset(&pref
, 0, sizeof(pref
));
6875 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6876 strcpy(caller_pref_buf
,"disabled");
6877 strcpy(host_pref_buf
,"disabled");
6879 using_prefs
= "mine";
6880 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
6881 /* Do the opposite of what we tried above. */
6882 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
6883 pref
= iaxs
[fr
->callno
]->prefs
;
6885 pref
= iaxs
[fr
->callno
]->rprefs
;
6886 using_prefs
= "caller";
6888 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
, 1);
6890 } else /* if no codec_prefs IE do it the old way */
6891 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6896 memset(&ied0
, 0, sizeof(ied0
));
6897 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
6898 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
6899 ast_log(LOG_ERROR
, "No best format in 0x%x???\n", iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6900 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6902 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
);
6903 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
6909 /* No authentication required, let them in */
6910 memset(&ied1
, 0, sizeof(ied1
));
6911 iax_ie_append_int(&ied1
, IAX_IE_FORMAT
, format
);
6912 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACCEPT
, 0, ied1
.buf
, ied1
.pos
, -1);
6913 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
6914 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
6915 if (option_verbose
> 2)
6916 ast_verbose(VERBOSE_PREFIX_3
"Accepting UNAUTHENTICATED call from %s:\n"
6917 "%srequested format = %s,\n"
6918 "%srequested prefs = %s,\n"
6919 "%sactual format = %s,\n"
6920 "%shost prefs = %s,\n"
6921 "%spriority = %s\n",
6922 ast_inet_ntoa(sin
.sin_addr
),
6924 ast_getformatname(iaxs
[fr
->callno
]->peerformat
),
6928 ast_getformatname(format
),
6934 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, format
, 1)))
6935 iax2_destroy(fr
->callno
);
6937 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
6938 /* If this is a TBD call, we're ready but now what... */
6939 if (option_verbose
> 2)
6940 ast_verbose(VERBOSE_PREFIX_3
"Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin
.sin_addr
));
6946 if (iaxs
[fr
->callno
]->authmethods
& IAX_AUTH_MD5
)
6947 merge_encryption(iaxs
[fr
->callno
],ies
.encmethods
);
6949 iaxs
[fr
->callno
]->encmethods
= 0;
6950 if (!authenticate_request(iaxs
[fr
->callno
]))
6951 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_AUTHENTICATED
);
6953 case IAX_COMMAND_DPREQ
:
6954 /* Request status in the dialplan */
6955 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
) &&
6956 !ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
) && ies
.called_number
) {
6958 /* Spawn a thread for the lookup */
6959 spawn_dp_lookup(fr
->callno
, iaxs
[fr
->callno
]->context
, ies
.called_number
, iaxs
[fr
->callno
]->cid_num
);
6961 /* Just look it up */
6962 dp_lookup(fr
->callno
, iaxs
[fr
->callno
]->context
, ies
.called_number
, iaxs
[fr
->callno
]->cid_num
, 1);
6966 case IAX_COMMAND_HANGUP
:
6967 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
6968 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received hangup\n", fr
->callno
);
6969 /* Set hangup cause according to remote */
6970 if (ies
.causecode
&& iaxs
[fr
->callno
]->owner
)
6971 iaxs
[fr
->callno
]->owner
->hangupcause
= ies
.causecode
;
6972 /* Send ack immediately, before we destroy */
6973 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6974 iax2_destroy(fr
->callno
);
6976 case IAX_COMMAND_REJECT
:
6977 /* Set hangup cause according to remote */
6978 if (ies
.causecode
&& iaxs
[fr
->callno
]->owner
)
6979 iaxs
[fr
->callno
]->owner
->hangupcause
= ies
.causecode
;
6981 if (!ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
)) {
6982 if (iaxs
[fr
->callno
]->owner
&& authdebug
)
6983 ast_log(LOG_WARNING
, "Call rejected by %s: %s\n",
6984 ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
),
6985 ies
.cause
? ies
.cause
: "<Unknown>");
6986 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received reject\n",
6989 /* Send ack immediately, before we destroy */
6990 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
,
6991 fr
->ts
, NULL
, 0, fr
->iseqno
);
6992 if (!ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
))
6993 iaxs
[fr
->callno
]->error
= EPERM
;
6994 iax2_destroy(fr
->callno
);
6996 case IAX_COMMAND_TRANSFER
:
6997 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
) && ies
.called_number
) {
6998 /* Set BLINDTRANSFER channel variables */
6999 pbx_builtin_setvar_helper(iaxs
[fr
->callno
]->owner
, "BLINDTRANSFER", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
7000 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), "BLINDTRANSFER", iaxs
[fr
->callno
]->owner
->name
);
7001 if (!strcmp(ies
.called_number
, ast_parking_ext())) {
7002 if (iax_park(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), iaxs
[fr
->callno
]->owner
)) {
7003 ast_log(LOG_WARNING
, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
7004 } else if (ast_bridged_channel(iaxs
[fr
->callno
]->owner
))
7005 ast_log(LOG_DEBUG
, "Parked call on '%s'\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
7007 if (ast_async_goto(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), iaxs
[fr
->callno
]->context
, ies
.called_number
, 1))
7008 ast_log(LOG_WARNING
, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
,
7009 ies
.called_number
, iaxs
[fr
->callno
]->context
);
7011 ast_log(LOG_DEBUG
, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
,
7012 ies
.called_number
, iaxs
[fr
->callno
]->context
);
7015 ast_log(LOG_DEBUG
, "Async goto not applicable on call %d\n", fr
->callno
);
7017 case IAX_COMMAND_ACCEPT
:
7018 /* Ignore if call is already up or needs authentication or is a TBD */
7019 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
| IAX_STATE_AUTHENTICATED
))
7021 if (ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
)) {
7022 /* Send ack immediately, before we destroy */
7023 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7024 iax2_destroy(fr
->callno
);
7028 iaxs
[fr
->callno
]->peerformat
= ies
.format
;
7030 if (iaxs
[fr
->callno
]->owner
)
7031 iaxs
[fr
->callno
]->peerformat
= iaxs
[fr
->callno
]->owner
->nativeformats
;
7033 iaxs
[fr
->callno
]->peerformat
= iaxs
[fr
->callno
]->capability
;
7035 if (option_verbose
> 2)
7036 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
));
7037 if (!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
)) {
7038 memset(&ied0
, 0, sizeof(ied0
));
7039 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7040 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7041 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7043 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
);
7045 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7046 if (iaxs
[fr
->callno
]->owner
) {
7047 /* Switch us to use a compatible format */
7048 iaxs
[fr
->callno
]->owner
->nativeformats
= iaxs
[fr
->callno
]->peerformat
;
7049 if (option_verbose
> 2)
7050 ast_verbose(VERBOSE_PREFIX_3
"Format for call is %s\n", ast_getformatname(iaxs
[fr
->callno
]->owner
->nativeformats
));
7052 if (ast_mutex_trylock(&iaxs
[fr
->callno
]->owner
->lock
)) {
7053 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7055 ast_mutex_lock(&iaxsl
[fr
->callno
]);
7056 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) goto retryowner2
;
7059 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) {
7060 /* Setup read/write formats properly. */
7061 if (iaxs
[fr
->callno
]->owner
->writeformat
)
7062 ast_set_write_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->writeformat
);
7063 if (iaxs
[fr
->callno
]->owner
->readformat
)
7064 ast_set_read_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->readformat
);
7065 ast_mutex_unlock(&iaxs
[fr
->callno
]->owner
->lock
);
7069 if (iaxs
[fr
->callno
]) {
7070 ast_mutex_lock(&dpcache_lock
);
7071 dp
= iaxs
[fr
->callno
]->dpentries
;
7073 if (!(dp
->flags
& CACHE_FLAG_TRANSMITTED
)) {
7074 iax2_dprequest(dp
, fr
->callno
);
7078 ast_mutex_unlock(&dpcache_lock
);
7081 case IAX_COMMAND_POKE
:
7082 /* Send back a pong packet with the original timestamp */
7083 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_PONG
, fr
->ts
, NULL
, 0, -1);
7085 case IAX_COMMAND_PING
:
7087 struct iax_ie_data pingied
;
7088 construct_rr(iaxs
[fr
->callno
], &pingied
);
7089 /* Send back a pong packet with the original timestamp */
7090 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_PONG
, fr
->ts
, pingied
.buf
, pingied
.pos
, -1);
7093 case IAX_COMMAND_PONG
:
7094 /* Calculate ping time */
7095 iaxs
[fr
->callno
]->pingtime
= calc_timestamp(iaxs
[fr
->callno
], 0, &f
) - fr
->ts
;
7099 if (iaxs
[fr
->callno
]->peerpoke
) {
7100 peer
= iaxs
[fr
->callno
]->peerpoke
;
7101 if ((peer
->lastms
< 0) || (peer
->historicms
> peer
->maxms
)) {
7102 if (iaxs
[fr
->callno
]->pingtime
<= peer
->maxms
) {
7103 ast_log(LOG_NOTICE
, "Peer '%s' is now REACHABLE! Time: %d\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7104 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7105 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7107 } else if ((peer
->historicms
> 0) && (peer
->historicms
<= peer
->maxms
)) {
7108 if (iaxs
[fr
->callno
]->pingtime
> peer
->maxms
) {
7109 ast_log(LOG_NOTICE
, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7110 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7111 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7114 peer
->lastms
= iaxs
[fr
->callno
]->pingtime
;
7115 if (peer
->smoothing
&& (peer
->lastms
> -1))
7116 peer
->historicms
= (iaxs
[fr
->callno
]->pingtime
+ peer
->historicms
) / 2;
7117 else if (peer
->smoothing
&& peer
->lastms
< 0)
7118 peer
->historicms
= (0 + peer
->historicms
) / 2;
7120 peer
->historicms
= iaxs
[fr
->callno
]->pingtime
;
7122 /* Remove scheduled iax2_poke_noanswer */
7123 if (peer
->pokeexpire
> -1)
7124 ast_sched_del(sched
, peer
->pokeexpire
);
7125 /* Schedule the next cycle */
7126 if ((peer
->lastms
< 0) || (peer
->historicms
> peer
->maxms
))
7127 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_peer_s
, peer
);
7129 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqok
, iax2_poke_peer_s
, peer
);
7130 /* and finally send the ack */
7131 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7132 /* And wrap up the qualify call */
7133 iax2_destroy(fr
->callno
);
7136 ast_log(LOG_DEBUG
, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer
->name
, peer
->lastms
, peer
->historicms
, peer
->maxms
);
7139 case IAX_COMMAND_LAGRQ
:
7140 case IAX_COMMAND_LAGRP
:
7145 iax_frame_wrap(fr
, &f
);
7146 if(f
.subclass
== IAX_COMMAND_LAGRQ
) {
7147 /* Received a LAGRQ - echo back a LAGRP */
7148 fr
->af
.subclass
= IAX_COMMAND_LAGRP
;
7149 iax2_send(iaxs
[fr
->callno
], &fr
->af
, fr
->ts
, -1, 0, 0, 0);
7151 /* Received LAGRP in response to our LAGRQ */
7153 /* This is a reply we've been given, actually measure the difference */
7154 ts
= calc_timestamp(iaxs
[fr
->callno
], 0, &fr
->af
);
7155 iaxs
[fr
->callno
]->lag
= ts
- fr
->ts
;
7156 if (option_debug
&& iaxdebug
)
7157 ast_log(LOG_DEBUG
, "Peer %s lag measured as %dms\n",
7158 ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
), iaxs
[fr
->callno
]->lag
);
7161 case IAX_COMMAND_AUTHREQ
:
7162 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
)) {
7163 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>");
7166 if (authenticate_reply(iaxs
[fr
->callno
], &iaxs
[fr
->callno
]->addr
, &ies
, iaxs
[fr
->callno
]->secret
, iaxs
[fr
->callno
]->outkey
)) {
7167 ast_log(LOG_WARNING
,
7168 "I don't know how to authenticate %s to %s\n",
7169 ies
.username
? ies
.username
: "<unknown>", ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
));
7172 case IAX_COMMAND_AUTHREP
:
7173 /* For security, always ack immediately */
7175 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7176 /* Ignore once we've started */
7177 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
)) {
7178 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>");
7181 if (authenticate_verify(iaxs
[fr
->callno
], &ies
)) {
7183 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
);
7184 memset(&ied0
, 0, sizeof(ied0
));
7185 auth_fail(fr
->callno
, IAX_COMMAND_REJECT
);
7188 if (strcasecmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
7189 /* This might re-enter the IAX code and need the lock */
7190 exists
= ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
);
7193 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD") && !exists
) {
7195 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
);
7196 memset(&ied0
, 0, sizeof(ied0
));
7197 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
7198 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
7199 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7201 /* Select an appropriate format */
7202 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
7203 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7204 using_prefs
= "reqonly";
7206 using_prefs
= "disabled";
7208 format
= iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
;
7209 memset(&pref
, 0, sizeof(pref
));
7210 strcpy(caller_pref_buf
, "disabled");
7211 strcpy(host_pref_buf
, "disabled");
7213 using_prefs
= "mine";
7214 if (ies
.codec_prefs
)
7215 ast_codec_pref_convert(&iaxs
[fr
->callno
]->rprefs
, ies
.codec_prefs
, 32, 0);
7216 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
7217 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
7218 pref
= iaxs
[fr
->callno
]->rprefs
;
7219 using_prefs
= "caller";
7221 pref
= iaxs
[fr
->callno
]->prefs
;
7223 } else /* if no codec_prefs IE do it the old way */
7224 pref
= iaxs
[fr
->callno
]->prefs
;
7226 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->capability
& iaxs
[fr
->callno
]->peercapability
, 0);
7227 ast_codec_pref_string(&iaxs
[fr
->callno
]->rprefs
, caller_pref_buf
, sizeof(caller_pref_buf
) - 1);
7228 ast_codec_pref_string(&iaxs
[fr
->callno
]->prefs
, host_pref_buf
, sizeof(host_pref_buf
) - 1);
7231 if(!ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7232 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
);
7233 format
= iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
;
7237 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
7238 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
);
7240 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
);
7242 memset(&ied0
, 0, sizeof(ied0
));
7243 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7244 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7245 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7248 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7249 if(!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
))
7252 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
7253 using_prefs
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ? "reqonly" : "disabled";
7254 memset(&pref
, 0, sizeof(pref
));
7255 format
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ?
7256 iaxs
[fr
->callno
]->peerformat
: ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7257 strcpy(caller_pref_buf
,"disabled");
7258 strcpy(host_pref_buf
,"disabled");
7260 using_prefs
= "mine";
7261 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
7262 /* Do the opposite of what we tried above. */
7263 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
7264 pref
= iaxs
[fr
->callno
]->prefs
;
7266 pref
= iaxs
[fr
->callno
]->rprefs
;
7267 using_prefs
= "caller";
7269 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
, 1);
7270 } else /* if no codec_prefs IE do it the old way */
7271 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7275 ast_log(LOG_ERROR
, "No best format in 0x%x???\n", iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7277 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
7278 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
);
7280 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
);
7282 memset(&ied0
, 0, sizeof(ied0
));
7283 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7284 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7285 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7290 /* Authentication received */
7291 memset(&ied1
, 0, sizeof(ied1
));
7292 iax_ie_append_int(&ied1
, IAX_IE_FORMAT
, format
);
7293 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACCEPT
, 0, ied1
.buf
, ied1
.pos
, -1);
7294 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
7295 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7296 if (option_verbose
> 2)
7297 ast_verbose(VERBOSE_PREFIX_3
"Accepting AUTHENTICATED call from %s:\n"
7298 "%srequested format = %s,\n"
7299 "%srequested prefs = %s,\n"
7300 "%sactual format = %s,\n"
7301 "%shost prefs = %s,\n"
7302 "%spriority = %s\n",
7303 ast_inet_ntoa(sin
.sin_addr
),
7305 ast_getformatname(iaxs
[fr
->callno
]->peerformat
),
7309 ast_getformatname(format
),
7315 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7316 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, format
, 0)))
7317 iax2_destroy(fr
->callno
);
7319 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
7320 /* If this is a TBD call, we're ready but now what... */
7321 if (option_verbose
> 2)
7322 ast_verbose(VERBOSE_PREFIX_3
"Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin
.sin_addr
));
7327 case IAX_COMMAND_DIAL
:
7328 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
)) {
7329 ast_clear_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
7330 ast_string_field_set(iaxs
[fr
->callno
], exten
, ies
.called_number
? ies
.called_number
: "s");
7331 if (!ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
)) {
7333 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
);
7334 memset(&ied0
, 0, sizeof(ied0
));
7335 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
7336 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
7337 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7339 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7340 if (option_verbose
> 2)
7341 ast_verbose(VERBOSE_PREFIX_3
"Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin
.sin_addr
), iaxs
[fr
->callno
]->peerformat
);
7342 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7343 send_command(iaxs
[fr
->callno
], AST_FRAME_CONTROL
, AST_CONTROL_PROGRESS
, 0, NULL
, 0, -1);
7344 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, iaxs
[fr
->callno
]->peerformat
, 0)))
7345 iax2_destroy(fr
->callno
);
7349 case IAX_COMMAND_INVAL
:
7350 iaxs
[fr
->callno
]->error
= ENOTCONN
;
7351 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received INVAL\n", fr
->callno
);
7352 iax2_destroy(fr
->callno
);
7354 ast_log(LOG_DEBUG
, "Destroying call %d\n", fr
->callno
);
7356 case IAX_COMMAND_VNAK
:
7357 ast_log(LOG_DEBUG
, "Received VNAK: resending outstanding frames\n");
7358 /* Force retransmission */
7359 vnak_retransmit(fr
->callno
, fr
->iseqno
);
7361 case IAX_COMMAND_REGREQ
:
7362 case IAX_COMMAND_REGREL
:
7363 /* For security, always ack immediately */
7365 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7366 if (register_verify(fr
->callno
, &sin
, &ies
)) {
7367 /* Send delayed failure */
7368 auth_fail(fr
->callno
, IAX_COMMAND_REGREJ
);
7371 if ((ast_strlen_zero(iaxs
[fr
->callno
]->secret
) && ast_strlen_zero(iaxs
[fr
->callno
]->inkeys
)) ||
7372 ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_AUTHENTICATED
| IAX_STATE_UNCHANGED
)) {
7373 if (f
.subclass
== IAX_COMMAND_REGREL
)
7374 memset(&sin
, 0, sizeof(sin
));
7375 if (update_registry(iaxs
[fr
->callno
]->peer
, &sin
, fr
->callno
, ies
.devicetype
, fd
, ies
.refresh
))
7376 ast_log(LOG_WARNING
, "Registry error\n");
7377 if (ies
.provverpres
&& ies
.serviceident
&& sin
.sin_addr
.s_addr
)
7378 check_provisioning(&sin
, fd
, ies
.serviceident
, ies
.provver
);
7381 registry_authrequest(iaxs
[fr
->callno
]->peer
, fr
->callno
);
7383 case IAX_COMMAND_REGACK
:
7384 if (iax2_ack_registry(&ies
, &sin
, fr
->callno
))
7385 ast_log(LOG_WARNING
, "Registration failure\n");
7386 /* Send ack immediately, before we destroy */
7387 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7388 iax2_destroy(fr
->callno
);
7390 case IAX_COMMAND_REGREJ
:
7391 if (iaxs
[fr
->callno
]->reg
) {
7393 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
));
7394 manager_event(EVENT_FLAG_SYSTEM
, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs
[fr
->callno
]->reg
->username
, ies
.cause
? ies
.cause
: "<unknown>");
7396 iaxs
[fr
->callno
]->reg
->regstate
= REG_STATE_REJECTED
;
7398 /* Send ack immediately, before we destroy */
7399 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7400 iax2_destroy(fr
->callno
);
7402 case IAX_COMMAND_REGAUTH
:
7403 /* Authentication request */
7404 if (registry_rerequest(&ies
, fr
->callno
, &sin
)) {
7405 memset(&ied0
, 0, sizeof(ied0
));
7406 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No authority found");
7407 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_NOT_SUBSCRIBED
);
7408 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7411 case IAX_COMMAND_TXREJ
:
7412 iaxs
[fr
->callno
]->transferring
= 0;
7413 if (option_verbose
> 2)
7414 ast_verbose(VERBOSE_PREFIX_3
"Channel '%s' unable to transfer\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>");
7415 memset(&iaxs
[fr
->callno
]->transfer
, 0, sizeof(iaxs
[fr
->callno
]->transfer
));
7416 if (iaxs
[fr
->callno
]->bridgecallno
) {
7417 if (iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
) {
7418 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= 0;
7419 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXREJ
, 0, NULL
, 0, -1);
7423 case IAX_COMMAND_TXREADY
:
7424 if ((iaxs
[fr
->callno
]->transferring
== TRANSFER_BEGIN
) ||
7425 (iaxs
[fr
->callno
]->transferring
== TRANSFER_MBEGIN
)) {
7426 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_MBEGIN
)
7427 iaxs
[fr
->callno
]->transferring
= TRANSFER_MREADY
;
7429 iaxs
[fr
->callno
]->transferring
= TRANSFER_READY
;
7430 if (option_verbose
> 2)
7431 ast_verbose(VERBOSE_PREFIX_3
"Channel '%s' ready to transfer\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>");
7432 if (iaxs
[fr
->callno
]->bridgecallno
) {
7433 if ((iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
== TRANSFER_READY
) ||
7434 (iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
== TRANSFER_MREADY
)) {
7435 /* They're both ready, now release them. */
7436 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_MREADY
) {
7437 if (option_verbose
> 2)
7438 ast_verbose(VERBOSE_PREFIX_3
"Attempting media bridge of %s and %s\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>",
7439 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
? iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
->name
: "<Unknown>");
7441 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= TRANSFER_MEDIA
;
7442 iaxs
[fr
->callno
]->transferring
= TRANSFER_MEDIA
;
7444 memset(&ied0
, 0, sizeof(ied0
));
7445 memset(&ied1
, 0, sizeof(ied1
));
7446 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->peercallno
);
7447 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->peercallno
);
7448 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXMEDIA
, 0, ied0
.buf
, ied0
.pos
, -1);
7449 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXMEDIA
, 0, ied1
.buf
, ied1
.pos
, -1);
7451 if (option_verbose
> 2)
7452 ast_verbose(VERBOSE_PREFIX_3
"Releasing %s and %s\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>",
7453 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
? iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
->name
: "<Unknown>");
7455 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= TRANSFER_RELEASED
;
7456 iaxs
[fr
->callno
]->transferring
= TRANSFER_RELEASED
;
7457 ast_set_flag(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], IAX_ALREADYGONE
);
7458 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
7460 /* Stop doing lag & ping requests */
7461 stop_stuff(fr
->callno
);
7462 stop_stuff(iaxs
[fr
->callno
]->bridgecallno
);
7464 memset(&ied0
, 0, sizeof(ied0
));
7465 memset(&ied1
, 0, sizeof(ied1
));
7466 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->peercallno
);
7467 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->peercallno
);
7468 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREL
, 0, ied0
.buf
, ied0
.pos
, -1);
7469 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXREL
, 0, ied1
.buf
, ied1
.pos
, -1);
7476 case IAX_COMMAND_TXREQ
:
7477 try_transfer(iaxs
[fr
->callno
], &ies
);
7479 case IAX_COMMAND_TXCNT
:
7480 if (iaxs
[fr
->callno
]->transferring
)
7481 send_command_transfer(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXACC
, 0, NULL
, 0);
7483 case IAX_COMMAND_TXREL
:
7484 /* Send ack immediately, rather than waiting until we've changed addresses */
7485 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7486 complete_transfer(fr
->callno
, &ies
);
7487 stop_stuff(fr
->callno
); /* for attended transfer to work with libiax */
7489 case IAX_COMMAND_TXMEDIA
:
7490 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_READY
) {
7491 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
7492 iaxs
[fr
->callno
]->transferring
= TRANSFER_MEDIAPASS
;
7495 case IAX_COMMAND_DPREP
:
7496 complete_dpreply(iaxs
[fr
->callno
], &ies
);
7498 case IAX_COMMAND_UNSUPPORT
:
7499 ast_log(LOG_NOTICE
, "Peer did not understand our iax command '%d'\n", ies
.iax_unknown
);
7501 case IAX_COMMAND_FWDOWNL
:
7502 /* Firmware download */
7503 memset(&ied0
, 0, sizeof(ied0
));
7504 res
= iax_firmware_append(&ied0
, (unsigned char *)ies
.devicetype
, ies
.fwdesc
);
7506 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7508 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_FWDATA
, 0, ied0
.buf
, ied0
.pos
, -1);
7510 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_FWDATA
, 0, ied0
.buf
, ied0
.pos
, -1);
7513 ast_log(LOG_DEBUG
, "Unknown IAX command %d on %d/%d\n", f
.subclass
, fr
->callno
, iaxs
[fr
->callno
]->peercallno
);
7514 memset(&ied0
, 0, sizeof(ied0
));
7515 iax_ie_append_byte(&ied0
, IAX_IE_IAX_UNKNOWN
, f
.subclass
);
7516 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_UNSUPPORT
, 0, ied0
.buf
, ied0
.pos
, -1);
7518 /* Don't actually pass these frames along */
7519 if ((f
.subclass
!= IAX_COMMAND_ACK
) &&
7520 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
7521 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
7522 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
7523 (f
.subclass
!= IAX_COMMAND_VNAK
)) {
7524 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->aseqno
!= iaxs
[fr
->callno
]->iseqno
)
7525 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7527 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7530 /* Unless this is an ACK or INVAL frame, ack it */
7531 if (iaxs
[fr
->callno
]->aseqno
!= iaxs
[fr
->callno
]->iseqno
)
7532 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7533 } else if (minivid
) {
7534 f
.frametype
= AST_FRAME_VIDEO
;
7535 if (iaxs
[fr
->callno
]->videoformat
> 0)
7536 f
.subclass
= iaxs
[fr
->callno
]->videoformat
| (ntohs(vh
->ts
) & 0x8000 ? 1 : 0);
7538 ast_log(LOG_WARNING
, "Received mini frame before first full video frame\n ");
7539 iax2_vnak(fr
->callno
);
7540 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7543 f
.datalen
= res
- sizeof(*vh
);
7545 f
.data
= thread
->buf
+ sizeof(*vh
);
7550 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF8000L
) | ((ntohs(vh
->ts
) + test_resync
) & 0x7fff);
7552 #endif /* IAXTESTS */
7553 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF8000L
) | (ntohs(vh
->ts
) & 0x7fff);
7556 f
.frametype
= AST_FRAME_VOICE
;
7557 if (iaxs
[fr
->callno
]->voiceformat
> 0)
7558 f
.subclass
= iaxs
[fr
->callno
]->voiceformat
;
7560 ast_log(LOG_WARNING
, "Received mini frame before first full voice frame\n ");
7561 iax2_vnak(fr
->callno
);
7562 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7565 f
.datalen
= res
- sizeof(struct ast_iax2_mini_hdr
);
7566 if (f
.datalen
< 0) {
7567 ast_log(LOG_WARNING
, "Datalen < 0?\n");
7568 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7572 f
.data
= thread
->buf
+ sizeof(*mh
);
7577 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | ((ntohs(mh
->ts
) + test_resync
) & 0xffff);
7579 #endif /* IAXTESTS */
7580 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | ntohs(mh
->ts
);
7581 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
7583 /* Don't pass any packets until we're started */
7584 if (!ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
7585 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7593 if (f
.datalen
&& (f
.frametype
== AST_FRAME_VOICE
)) {
7594 f
.samples
= ast_codec_get_samples(&f
);
7595 /* We need to byteswap incoming slinear samples from network byte order */
7596 if (f
.subclass
== AST_FORMAT_SLINEAR
)
7597 ast_frame_byteswap_be(&f
);
7600 iax_frame_wrap(fr
, &f
);
7602 /* If this is our most recent packet, use it as our basis for timestamping */
7603 if (iaxs
[fr
->callno
]->last
< fr
->ts
) {
7604 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
7607 if (option_debug
&& iaxdebug
)
7608 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
);
7609 fr
->outoforder
= -1;
7611 duped_fr
= iaxfrdup2(fr
);
7613 schedule_delivery(duped_fr
, updatehistory
, 0, &fr
->ts
);
7615 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->last
< fr
->ts
) {
7616 iaxs
[fr
->callno
]->last
= fr
->ts
;
7618 if (option_debug
&& iaxdebug
)
7619 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
7623 /* Always run again */
7624 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7628 /* Function to clean up process thread if it is cancelled */
7629 static void iax2_process_thread_cleanup(void *data
)
7631 struct iax2_thread
*thread
= data
;
7632 ast_mutex_destroy(&thread
->lock
);
7633 ast_cond_destroy(&thread
->cond
);
7635 ast_atomic_dec_and_test(&iaxactivethreadcount
);
7638 static void *iax2_process_thread(void *data
)
7640 struct iax2_thread
*thread
= data
;
7643 int put_into_idle
= 0;
7645 ast_atomic_fetchadd_int(&iaxactivethreadcount
,1);
7646 pthread_cleanup_push(iax2_process_thread_cleanup
, data
);
7648 /* Wait for something to signal us to be awake */
7649 ast_mutex_lock(&thread
->lock
);
7651 /* Put into idle list if applicable */
7653 insert_idle_thread(thread
);
7655 if (thread
->type
== IAX_TYPE_DYNAMIC
) {
7656 /* Wait to be signalled or time out */
7657 tv
= ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
7658 ts
.tv_sec
= tv
.tv_sec
;
7659 ts
.tv_nsec
= tv
.tv_usec
* 1000;
7660 if (ast_cond_timedwait(&thread
->cond
, &thread
->lock
, &ts
) == ETIMEDOUT
) {
7661 ast_mutex_unlock(&thread
->lock
);
7662 AST_LIST_LOCK(&dynamic_list
);
7663 AST_LIST_REMOVE(&dynamic_list
, thread
, list
);
7664 iaxdynamicthreadcount
--;
7665 AST_LIST_UNLOCK(&dynamic_list
);
7666 break; /* exiting the main loop */
7669 ast_cond_wait(&thread
->cond
, &thread
->lock
);
7671 ast_mutex_unlock(&thread
->lock
);
7673 /* Add ourselves to the active list now */
7674 AST_LIST_LOCK(&active_list
);
7675 AST_LIST_INSERT_HEAD(&active_list
, thread
, list
);
7676 AST_LIST_UNLOCK(&active_list
);
7678 /* See what we need to do */
7679 switch(thread
->iostate
) {
7680 case IAX_IOSTATE_READY
:
7682 thread
->iostate
= IAX_IOSTATE_PROCESSING
;
7683 socket_process(thread
);
7685 case IAX_IOSTATE_SCHEDREADY
:
7687 thread
->iostate
= IAX_IOSTATE_PROCESSING
;
7688 #ifdef SCHED_MULTITHREADED
7689 thread
->schedfunc(thread
->scheddata
);
7693 time(&thread
->checktime
);
7694 thread
->iostate
= IAX_IOSTATE_IDLE
;
7695 #ifdef DEBUG_SCHED_MULTITHREAD
7696 thread
->curfunc
[0]='\0';
7699 /* Now... remove ourselves from the active list, and return to the idle list */
7700 AST_LIST_LOCK(&active_list
);
7701 AST_LIST_REMOVE(&active_list
, thread
, list
);
7702 AST_LIST_UNLOCK(&active_list
);
7704 /* Go back into our respective list */
7708 /* I am exiting here on my own volition, I need to clean up my own data structures
7709 * Assume that I am no longer in any of the lists (idle, active, or dynamic)
7711 pthread_cleanup_pop(1);
7716 static int iax2_do_register(struct iax2_registry
*reg
)
7718 struct iax_ie_data ied
;
7719 if (option_debug
&& iaxdebug
)
7720 ast_log(LOG_DEBUG
, "Sending registration request for '%s'\n", reg
->username
);
7723 ((reg
->regstate
== REG_STATE_TIMEOUT
) || !reg
->addr
.sin_addr
.s_addr
)) {
7724 /* Maybe the IP has changed, force DNS refresh */
7725 ast_dnsmgr_refresh(reg
->dnsmgr
);
7729 * if IP has Changed, free allocated call to create a new one with new IP
7730 * call has the pointer to IP and must be updated to the new one
7732 if (reg
->dnsmgr
&& ast_dnsmgr_changed(reg
->dnsmgr
) && (reg
->callno
> 0)) {
7733 ast_mutex_lock(&iaxsl
[reg
->callno
]);
7734 iax2_destroy(reg
->callno
);
7735 ast_mutex_unlock(&iaxsl
[reg
->callno
]);
7738 if (!reg
->addr
.sin_addr
.s_addr
) {
7739 if (option_debug
&& iaxdebug
)
7740 ast_log(LOG_DEBUG
, "Unable to send registration request for '%s' without IP address\n", reg
->username
);
7741 /* Setup the next registration attempt */
7742 if (reg
->expire
> -1)
7743 ast_sched_del(sched
, reg
->expire
);
7744 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
7750 ast_log(LOG_DEBUG
, "Allocate call number\n");
7751 reg
->callno
= find_callno(0, 0, ®
->addr
, NEW_FORCE
, 1, defaultsockfd
);
7752 if (reg
->callno
< 1) {
7753 ast_log(LOG_WARNING
, "Unable to create call for registration\n");
7755 } else if (option_debug
)
7756 ast_log(LOG_DEBUG
, "Registration created on call %d\n", reg
->callno
);
7757 iaxs
[reg
->callno
]->reg
= reg
;
7759 /* Schedule the next registration attempt */
7760 if (reg
->expire
> -1)
7761 ast_sched_del(sched
, reg
->expire
);
7762 /* Setup the next registration a little early */
7763 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
7764 /* Send the request */
7765 memset(&ied
, 0, sizeof(ied
));
7766 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, reg
->username
);
7767 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, reg
->refresh
);
7768 send_command(iaxs
[reg
->callno
],AST_FRAME_IAX
, IAX_COMMAND_REGREQ
, 0, ied
.buf
, ied
.pos
, -1);
7769 reg
->regstate
= REG_STATE_REGSENT
;
7773 static char *iax2_prov_complete_template_3rd(const char *line
, const char *word
, int pos
, int state
)
7777 return iax_prov_complete_template(line
, word
, pos
, state
);
7780 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
)
7782 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
7783 is found for template */
7784 struct iax_ie_data provdata
;
7785 struct iax_ie_data ied
;
7787 struct sockaddr_in sin
;
7789 struct create_addr_info cai
;
7791 memset(&cai
, 0, sizeof(cai
));
7794 ast_log(LOG_DEBUG
, "Provisioning '%s' from template '%s'\n", dest
, template);
7796 if (iax_provision_build(&provdata
, &sig
, template, force
)) {
7797 ast_log(LOG_DEBUG
, "No provisioning found for template '%s'\n", template);
7802 memcpy(&sin
, end
, sizeof(sin
));
7803 cai
.sockfd
= sockfd
;
7804 } else if (create_addr(dest
, &sin
, &cai
))
7807 /* Build the rest of the message */
7808 memset(&ied
, 0, sizeof(ied
));
7809 iax_ie_append_raw(&ied
, IAX_IE_PROVISIONING
, provdata
.buf
, provdata
.pos
);
7811 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
7815 ast_mutex_lock(&iaxsl
[callno
]);
7817 /* Schedule autodestruct in case they don't ever give us anything back */
7818 if (iaxs
[callno
]->autoid
> -1)
7819 ast_sched_del(sched
, iaxs
[callno
]->autoid
);
7820 iaxs
[callno
]->autoid
= ast_sched_add(sched
, 15000, auto_hangup
, (void *)(long)callno
);
7821 ast_set_flag(iaxs
[callno
], IAX_PROVISION
);
7822 /* Got a call number now, so go ahead and send the provisioning information */
7823 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_PROVISION
, 0, ied
.buf
, ied
.pos
, -1);
7825 ast_mutex_unlock(&iaxsl
[callno
]);
7830 static char *papp
= "IAX2Provision";
7831 static char *psyn
= "Provision a calling IAXy with a given template";
7832 static char *pdescrip
=
7833 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
7834 "the calling entity is in fact an IAXy) with the given template or\n"
7835 "default if one is not specified. Returns -1 on error or 0 on success.\n";
7838 \ingroup applications
7840 static int iax2_prov_app(struct ast_channel
*chan
, void *data
)
7846 unsigned short callno
= PTR_TO_CALLNO(chan
->tech_pvt
);
7847 if (ast_strlen_zero(data
))
7849 sdata
= ast_strdupa(data
);
7850 opts
= strchr(sdata
, '|');
7854 if (chan
->tech
!= &iax2_tech
) {
7855 ast_log(LOG_NOTICE
, "Can't provision a non-IAX device!\n");
7858 if (!callno
|| !iaxs
[callno
] || !iaxs
[callno
]->addr
.sin_addr
.s_addr
) {
7859 ast_log(LOG_NOTICE
, "Can't provision something with no IP?\n");
7862 res
= iax2_provision(&iaxs
[callno
]->addr
, iaxs
[callno
]->sockfd
, NULL
, sdata
, force
);
7863 if (option_verbose
> 2)
7864 ast_verbose(VERBOSE_PREFIX_3
"Provisioned IAXY at '%s' with '%s'= %d\n",
7865 ast_inet_ntoa(iaxs
[callno
]->addr
.sin_addr
),
7871 static int iax2_prov_cmd(int fd
, int argc
, char *argv
[])
7876 return RESULT_SHOWUSAGE
;
7878 if (!strcasecmp(argv
[4], "forced"))
7881 return RESULT_SHOWUSAGE
;
7883 res
= iax2_provision(NULL
, -1, argv
[2], argv
[3], force
);
7885 ast_cli(fd
, "Unable to find peer/address '%s'\n", argv
[2]);
7887 ast_cli(fd
, "No template (including wildcard) matching '%s'\n", argv
[3]);
7889 ast_cli(fd
, "Provisioning '%s' with template '%s'%s\n", argv
[2], argv
[3], force
? ", forced" : "");
7890 return RESULT_SUCCESS
;
7893 static void __iax2_poke_noanswer(void *data
)
7895 struct iax2_peer
*peer
= data
;
7896 if (peer
->lastms
> -1) {
7897 ast_log(LOG_NOTICE
, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer
->name
, peer
->lastms
);
7898 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer
->name
, peer
->lastms
);
7899 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7901 if (peer
->callno
> 0) {
7902 ast_mutex_lock(&iaxsl
[peer
->callno
]);
7903 iax2_destroy(peer
->callno
);
7904 ast_mutex_unlock(&iaxsl
[peer
->callno
]);
7908 /* Try again quickly */
7909 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_peer_s
, peer
);
7912 static int iax2_poke_noanswer(void *data
)
7914 struct iax2_peer
*peer
= data
;
7915 peer
->pokeexpire
= -1;
7916 #ifdef SCHED_MULTITHREADED
7917 if (schedule_action(__iax2_poke_noanswer
, data
))
7919 __iax2_poke_noanswer(data
);
7923 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
)
7925 if (!peer
->maxms
|| !peer
->addr
.sin_addr
.s_addr
) {
7926 /* IF we have no IP, or this isn't to be monitored, return
7927 immediately after clearing things out */
7929 peer
->historicms
= 0;
7930 peer
->pokeexpire
= -1;
7934 if (peer
->callno
> 0) {
7935 ast_log(LOG_NOTICE
, "Still have a callno...\n");
7936 ast_mutex_lock(&iaxsl
[peer
->callno
]);
7937 iax2_destroy(peer
->callno
);
7938 ast_mutex_unlock(&iaxsl
[peer
->callno
]);
7941 ast_mutex_unlock(&iaxsl
[heldcall
]);
7942 peer
->callno
= find_callno(0, 0, &peer
->addr
, NEW_FORCE
, 0, peer
->sockfd
);
7944 ast_mutex_lock(&iaxsl
[heldcall
]);
7945 if (peer
->callno
< 1) {
7946 ast_log(LOG_WARNING
, "Unable to allocate call for poking peer '%s'\n", peer
->name
);
7950 /* Speed up retransmission times for this qualify call */
7951 iaxs
[peer
->callno
]->pingtime
= peer
->maxms
/ 4 + 1;
7952 iaxs
[peer
->callno
]->peerpoke
= peer
;
7954 /* Remove any pending pokeexpire task */
7955 if (peer
->pokeexpire
> -1)
7956 ast_sched_del(sched
, peer
->pokeexpire
);
7958 /* Queue up a new task to handle no reply */
7959 /* If the host is already unreachable then use the unreachable interval instead */
7960 if (peer
->lastms
< 0) {
7961 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_noanswer
, peer
);
7963 peer
->pokeexpire
= ast_sched_add(sched
, DEFAULT_MAXMS
* 2, iax2_poke_noanswer
, peer
);
7965 /* And send the poke */
7966 send_command(iaxs
[peer
->callno
], AST_FRAME_IAX
, IAX_COMMAND_POKE
, 0, NULL
, 0, -1);
7971 static void free_context(struct iax2_context
*con
)
7973 struct iax2_context
*conl
;
7981 static struct ast_channel
*iax2_request(const char *type
, int format
, void *data
, int *cause
)
7986 struct sockaddr_in sin
;
7987 struct ast_channel
*c
;
7988 struct parsed_dial_string pds
;
7989 struct create_addr_info cai
;
7992 memset(&pds
, 0, sizeof(pds
));
7993 tmpstr
= ast_strdupa(data
);
7994 parse_dial_string(tmpstr
, &pds
);
7996 memset(&cai
, 0, sizeof(cai
));
7997 cai
.capability
= iax2_capability
;
7999 ast_copy_flags(&cai
, &globalflags
, IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
8002 ast_log(LOG_WARNING
, "No peer given\n");
8007 /* Populate our address from the given */
8008 if (create_addr(pds
.peer
, &sin
, &cai
)) {
8009 *cause
= AST_CAUSE_UNREGISTERED
;
8014 sin
.sin_port
= htons(atoi(pds
.port
));
8016 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
8018 ast_log(LOG_WARNING
, "Unable to create call\n");
8019 *cause
= AST_CAUSE_CONGESTION
;
8023 ast_mutex_lock(&iaxsl
[callno
]);
8025 /* If this is a trunk, update it now */
8026 ast_copy_flags(iaxs
[callno
], &cai
, IAX_TRUNK
| IAX_SENDANI
| IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
8027 if (ast_test_flag(&cai
, IAX_TRUNK
))
8028 callno
= make_trunk(callno
, 1);
8029 iaxs
[callno
]->maxtime
= cai
.maxtime
;
8031 ast_string_field_set(iaxs
[callno
], host
, pds
.peer
);
8033 c
= ast_iax2_new(callno
, AST_STATE_DOWN
, cai
.capability
, 0);
8035 ast_mutex_unlock(&iaxsl
[callno
]);
8038 /* Choose a format we can live with */
8039 if (c
->nativeformats
& format
)
8040 c
->nativeformats
&= format
;
8042 native
= c
->nativeformats
;
8044 res
= ast_translator_best_choice(&fmt
, &native
);
8046 ast_log(LOG_WARNING
, "Unable to create translator path for %s to %s on %s\n",
8047 ast_getformatname(c
->nativeformats
), ast_getformatname(fmt
), c
->name
);
8051 c
->nativeformats
= native
;
8053 c
->readformat
= ast_best_codec(c
->nativeformats
);
8054 c
->writeformat
= c
->readformat
;
8060 static void *sched_thread(void *ignore
)
8068 res
= ast_sched_wait(sched
);
8069 if ((res
> 1000) || (res
< 0))
8071 tv
= ast_tvadd(ast_tvnow(), ast_samp2tv(res
, 1000));
8072 ts
.tv_sec
= tv
.tv_sec
;
8073 ts
.tv_nsec
= tv
.tv_usec
* 1000;
8075 pthread_testcancel();
8076 ast_mutex_lock(&sched_lock
);
8077 ast_cond_timedwait(&sched_cond
, &sched_lock
, &ts
);
8078 ast_mutex_unlock(&sched_lock
);
8079 pthread_testcancel();
8081 count
= ast_sched_runq(sched
);
8083 ast_log(LOG_DEBUG
, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count
);
8088 static void *network_thread(void *ignore
)
8090 /* Our job is simple: Send queued messages, retrying if necessary. Read frames
8091 from the network, and queue them for delivery to the channels */
8092 int res
, count
, wakeup
;
8093 struct iax_frame
*f
;
8096 ast_io_add(io
, timingfd
, timing_read
, AST_IO_IN
| AST_IO_PRI
, NULL
);
8099 pthread_testcancel();
8101 /* Go through the queue, sending messages which have not yet been
8102 sent, and scheduling retransmissions if appropriate */
8103 AST_LIST_LOCK(&iaxq
.queue
);
8106 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq
.queue
, f
, list
) {
8110 /* Try to lock the pvt, if we can't... don't fret - defer it till later */
8111 if (ast_mutex_trylock(&iaxsl
[f
->callno
])) {
8118 if (iaxs
[f
->callno
]) {
8123 ast_mutex_unlock(&iaxsl
[f
->callno
]);
8125 if (f
->retries
< 0) {
8126 /* This is not supposed to be retransmitted */
8127 AST_LIST_REMOVE(&iaxq
.queue
, f
, list
);
8129 /* Free the iax frame */
8132 /* We need reliable delivery. Schedule a retransmission */
8134 f
->retrans
= ast_sched_add(sched
, f
->retrytime
, attempt_transmit
, f
);
8135 signal_condition(&sched_lock
, &sched_cond
);
8138 AST_LIST_TRAVERSE_SAFE_END
8139 AST_LIST_UNLOCK(&iaxq
.queue
);
8141 pthread_testcancel();
8144 ast_log(LOG_DEBUG
, "chan_iax2: Sent %d queued outbound frames all at once\n", count
);
8146 /* Now do the IO, and run scheduled tasks */
8147 res
= ast_io_wait(io
, wakeup
);
8150 ast_log(LOG_DEBUG
, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res
);
8156 static int start_network_thread(void)
8158 pthread_attr_t attr
;
8159 int threadcount
= 0;
8161 for (x
= 0; x
< iaxthreadcount
; x
++) {
8162 struct iax2_thread
*thread
= ast_calloc(1, sizeof(struct iax2_thread
));
8164 thread
->type
= IAX_TYPE_POOL
;
8165 thread
->threadnum
= ++threadcount
;
8166 ast_mutex_init(&thread
->lock
);
8167 ast_cond_init(&thread
->cond
, NULL
);
8168 pthread_attr_init(&attr
);
8169 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
8170 if (ast_pthread_create(&thread
->threadid
, &attr
, iax2_process_thread
, thread
)) {
8171 ast_log(LOG_WARNING
, "Failed to create new thread!\n");
8175 AST_LIST_LOCK(&idle_list
);
8176 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
8177 AST_LIST_UNLOCK(&idle_list
);
8180 ast_pthread_create_background(&schedthreadid
, NULL
, sched_thread
, NULL
);
8181 ast_pthread_create_background(&netthreadid
, NULL
, network_thread
, NULL
);
8182 if (option_verbose
> 1)
8183 ast_verbose(VERBOSE_PREFIX_2
"%d helper threaads started\n", threadcount
);
8187 static struct iax2_context
*build_context(char *context
)
8189 struct iax2_context
*con
;
8191 if ((con
= ast_calloc(1, sizeof(*con
))))
8192 ast_copy_string(con
->context
, context
, sizeof(con
->context
));
8197 static int get_auth_methods(char *value
)
8200 if (strstr(value
, "rsa"))
8201 methods
|= IAX_AUTH_RSA
;
8202 if (strstr(value
, "md5"))
8203 methods
|= IAX_AUTH_MD5
;
8204 if (strstr(value
, "plaintext"))
8205 methods
|= IAX_AUTH_PLAINTEXT
;
8210 /*! \brief Check if address can be used as packet source.
8211 \return 0 address available, 1 address unavailable, -1 error
8213 static int check_srcaddr(struct sockaddr
*sa
, socklen_t salen
)
8218 sd
= socket(AF_INET
, SOCK_DGRAM
, 0);
8220 ast_log(LOG_ERROR
, "Socket: %s\n", strerror(errno
));
8224 res
= bind(sd
, sa
, salen
);
8226 ast_log(LOG_DEBUG
, "Can't bind: %s\n", strerror(errno
));
8235 /*! \brief Parse the "sourceaddress" value,
8236 lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
8238 static int peer_set_srcaddr(struct iax2_peer
*peer
, const char *srcaddr
)
8240 struct sockaddr_in sin
;
8242 int port
= IAX_DEFAULT_PORTNO
;
8243 int sockfd
= defaultsockfd
;
8248 if (!(tmp
= ast_strdupa(srcaddr
)))
8251 addr
= strsep(&tmp
, ":");
8255 port
= atoi(portstr
);
8257 port
= IAX_DEFAULT_PORTNO
;
8260 if (!ast_get_ip(&sin
, addr
)) {
8261 struct ast_netsock
*sock
;
8265 sin
.sin_family
= AF_INET
;
8266 res
= check_srcaddr((struct sockaddr
*) &sin
, sizeof(sin
));
8268 /* ip address valid. */
8269 sin
.sin_port
= htons(port
);
8270 if (!(sock
= ast_netsock_find(netsock
, &sin
)))
8271 sock
= ast_netsock_find(outsock
, &sin
);
8273 sockfd
= ast_netsock_sockfd(sock
);
8276 unsigned int orig_saddr
= sin
.sin_addr
.s_addr
;
8277 /* INADDR_ANY matches anyway! */
8278 sin
.sin_addr
.s_addr
= INADDR_ANY
;
8279 if (ast_netsock_find(netsock
, &sin
)) {
8280 sin
.sin_addr
.s_addr
= orig_saddr
;
8281 sock
= ast_netsock_bind(outsock
, io
, srcaddr
, port
, tos
, socket_read
, NULL
);
8283 sockfd
= ast_netsock_sockfd(sock
);
8284 ast_netsock_unref(sock
);
8294 peer
->sockfd
= sockfd
;
8296 if (nonlocal
== 1) {
8297 ast_log(LOG_WARNING
, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
8298 srcaddr
, peer
->name
);
8300 } else if (nonlocal
== 2) {
8301 ast_log(LOG_WARNING
, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
8302 srcaddr
, peer
->name
);
8305 ast_log(LOG_DEBUG
, "Using sourceaddress %s for '%s'\n", srcaddr
, peer
->name
);
8311 /*! \brief Create peer structure based on configuration */
8312 static struct iax2_peer
*build_peer(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
)
8314 struct iax2_peer
*peer
= NULL
;
8315 struct ast_ha
*oldha
= NULL
;
8320 AST_LIST_LOCK(&peers
);
8322 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
8323 if (!strcmp(peer
->name
, name
)) {
8324 if (!ast_test_flag(peer
, IAX_DELME
))
8337 AST_LIST_REMOVE(&peers
, peer
, entry
);
8338 AST_LIST_UNLOCK(&peers
);
8340 AST_LIST_UNLOCK(&peers
);
8341 if ((peer
= ast_calloc(1, sizeof(*peer
)))) {
8343 peer
->pokeexpire
= -1;
8344 peer
->sockfd
= defaultsockfd
;
8345 if (ast_string_field_init(peer
, 32)) {
8353 ast_copy_flags(peer
, &globalflags
, IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
8354 peer
->encmethods
= iax2_encryption
;
8356 ast_string_field_set(peer
,secret
,"");
8358 ast_string_field_set(peer
, name
, name
);
8359 peer
->addr
.sin_port
= htons(IAX_DEFAULT_PORTNO
);
8360 peer
->expiry
= min_reg_expire
;
8362 peer
->prefs
= prefs
;
8363 peer
->capability
= iax2_capability
;
8364 peer
->smoothing
= 0;
8365 peer
->pokefreqok
= DEFAULT_FREQ_OK
;
8366 peer
->pokefreqnotok
= DEFAULT_FREQ_NOTOK
;
8367 ast_string_field_set(peer
,context
,"");
8368 ast_string_field_set(peer
,peercontext
,"");
8369 ast_clear_flag(peer
, IAX_HASCALLERID
);
8370 ast_string_field_set(peer
, cid_name
, "");
8371 ast_string_field_set(peer
, cid_num
, "");
8379 if (!strcasecmp(v
->name
, "secret")) {
8380 ast_string_field_set(peer
, secret
, v
->value
);
8381 } else if (!strcasecmp(v
->name
, "mailbox")) {
8382 ast_string_field_set(peer
, mailbox
, v
->value
);
8383 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
8384 ast_string_field_set(peer
, mohinterpret
, v
->value
);
8385 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
8386 ast_string_field_set(peer
, mohsuggest
, v
->value
);
8387 } else if (!strcasecmp(v
->name
, "dbsecret")) {
8388 ast_string_field_set(peer
, dbsecret
, v
->value
);
8389 } else if (!strcasecmp(v
->name
, "trunk")) {
8390 ast_set2_flag(peer
, ast_true(v
->value
), IAX_TRUNK
);
8391 if (ast_test_flag(peer
, IAX_TRUNK
) && (timingfd
< 0)) {
8392 ast_log(LOG_WARNING
, "Unable to support trunking on peer '%s' without zaptel timing\n", peer
->name
);
8393 ast_clear_flag(peer
, IAX_TRUNK
);
8395 } else if (!strcasecmp(v
->name
, "auth")) {
8396 peer
->authmethods
= get_auth_methods(v
->value
);
8397 } else if (!strcasecmp(v
->name
, "encryption")) {
8398 peer
->encmethods
= get_encrypt_methods(v
->value
);
8399 } else if (!strcasecmp(v
->name
, "notransfer")) {
8400 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8401 ast_clear_flag(peer
, IAX_TRANSFERMEDIA
);
8402 ast_set2_flag(peer
, ast_true(v
->value
), IAX_NOTRANSFER
);
8403 } else if (!strcasecmp(v
->name
, "transfer")) {
8404 if (!strcasecmp(v
->value
, "mediaonly")) {
8405 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8406 } else if (ast_true(v
->value
)) {
8407 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8409 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8410 } else if (!strcasecmp(v
->name
, "jitterbuffer")) {
8411 ast_set2_flag(peer
, ast_true(v
->value
), IAX_USEJITTERBUF
);
8412 } else if (!strcasecmp(v
->name
, "forcejitterbuffer")) {
8413 ast_set2_flag(peer
, ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8414 } else if (!strcasecmp(v
->name
, "host")) {
8415 if (!strcasecmp(v
->value
, "dynamic")) {
8416 /* They'll register with us */
8417 ast_set_flag(peer
, IAX_DYNAMIC
);
8419 /* Initialize stuff iff we're not found, otherwise
8420 we keep going with what we had */
8421 memset(&peer
->addr
.sin_addr
, 0, 4);
8422 if (peer
->addr
.sin_port
) {
8423 /* If we've already got a port, make it the default rather than absolute */
8424 peer
->defaddr
.sin_port
= peer
->addr
.sin_port
;
8425 peer
->addr
.sin_port
= 0;
8429 /* Non-dynamic. Make sure we become that way if we're not */
8430 if (peer
->expire
> -1)
8431 ast_sched_del(sched
, peer
->expire
);
8433 ast_clear_flag(peer
, IAX_DYNAMIC
);
8434 if (ast_dnsmgr_lookup(v
->value
, &peer
->addr
.sin_addr
, &peer
->dnsmgr
)) {
8435 ast_string_field_free_pools(peer
);
8439 if (!peer
->addr
.sin_port
)
8440 peer
->addr
.sin_port
= htons(IAX_DEFAULT_PORTNO
);
8443 inet_aton("255.255.255.255", &peer
->mask
);
8444 } else if (!strcasecmp(v
->name
, "defaultip")) {
8445 if (ast_get_ip(&peer
->defaddr
, v
->value
)) {
8446 ast_string_field_free_pools(peer
);
8450 } else if (!strcasecmp(v
->name
, "sourceaddress")) {
8451 peer_set_srcaddr(peer
, v
->value
);
8452 } else if (!strcasecmp(v
->name
, "permit") ||
8453 !strcasecmp(v
->name
, "deny")) {
8454 peer
->ha
= ast_append_ha(v
->name
, v
->value
, peer
->ha
);
8455 } else if (!strcasecmp(v
->name
, "mask")) {
8457 inet_aton(v
->value
, &peer
->mask
);
8458 } else if (!strcasecmp(v
->name
, "context")) {
8459 ast_string_field_set(peer
, context
, v
->value
);
8460 } else if (!strcasecmp(v
->name
, "regexten")) {
8461 ast_string_field_set(peer
, regexten
, v
->value
);
8462 } else if (!strcasecmp(v
->name
, "peercontext")) {
8463 ast_string_field_set(peer
, peercontext
, v
->value
);
8464 } else if (!strcasecmp(v
->name
, "port")) {
8465 if (ast_test_flag(peer
, IAX_DYNAMIC
))
8466 peer
->defaddr
.sin_port
= htons(atoi(v
->value
));
8468 peer
->addr
.sin_port
= htons(atoi(v
->value
));
8469 } else if (!strcasecmp(v
->name
, "username")) {
8470 ast_string_field_set(peer
, username
, v
->value
);
8471 } else if (!strcasecmp(v
->name
, "allow")) {
8472 ast_parse_allow_disallow(&peer
->prefs
, &peer
->capability
, v
->value
, 1);
8473 } else if (!strcasecmp(v
->name
, "disallow")) {
8474 ast_parse_allow_disallow(&peer
->prefs
, &peer
->capability
, v
->value
, 0);
8475 } else if (!strcasecmp(v
->name
, "callerid")) {
8476 if (!ast_strlen_zero(v
->value
)) {
8479 ast_callerid_split(v
->value
, name2
, 80, num2
, 80);
8480 ast_string_field_set(peer
, cid_name
, name2
);
8481 ast_string_field_set(peer
, cid_num
, num2
);
8482 ast_set_flag(peer
, IAX_HASCALLERID
);
8484 ast_clear_flag(peer
, IAX_HASCALLERID
);
8485 ast_string_field_set(peer
, cid_name
, "");
8486 ast_string_field_set(peer
, cid_num
, "");
8488 } else if (!strcasecmp(v
->name
, "fullname")) {
8489 if (!ast_strlen_zero(v
->value
)) {
8490 ast_string_field_set(peer
, cid_name
, v
->value
);
8491 ast_set_flag(peer
, IAX_HASCALLERID
);
8493 ast_string_field_set(peer
, cid_name
, "");
8494 if (ast_strlen_zero(peer
->cid_num
))
8495 ast_clear_flag(peer
, IAX_HASCALLERID
);
8497 } else if (!strcasecmp(v
->name
, "cid_number")) {
8498 if (!ast_strlen_zero(v
->value
)) {
8499 ast_string_field_set(peer
, cid_num
, v
->value
);
8500 ast_set_flag(peer
, IAX_HASCALLERID
);
8502 ast_string_field_set(peer
, cid_num
, "");
8503 if (ast_strlen_zero(peer
->cid_name
))
8504 ast_clear_flag(peer
, IAX_HASCALLERID
);
8506 } else if (!strcasecmp(v
->name
, "sendani")) {
8507 ast_set2_flag(peer
, ast_true(v
->value
), IAX_SENDANI
);
8508 } else if (!strcasecmp(v
->name
, "inkeys")) {
8509 ast_string_field_set(peer
, inkeys
, v
->value
);
8510 } else if (!strcasecmp(v
->name
, "outkey")) {
8511 ast_string_field_set(peer
, outkey
, v
->value
);
8512 } else if (!strcasecmp(v
->name
, "qualify")) {
8513 if (!strcasecmp(v
->value
, "no")) {
8515 } else if (!strcasecmp(v
->value
, "yes")) {
8516 peer
->maxms
= DEFAULT_MAXMS
;
8517 } else if (sscanf(v
->value
, "%d", &peer
->maxms
) != 1) {
8518 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
);
8521 } else if (!strcasecmp(v
->name
, "qualifysmoothing")) {
8522 peer
->smoothing
= ast_true(v
->value
);
8523 } else if (!strcasecmp(v
->name
, "qualifyfreqok")) {
8524 if (sscanf(v
->value
, "%d", &peer
->pokefreqok
) != 1) {
8525 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
);
8527 } else if (!strcasecmp(v
->name
, "qualifyfreqnotok")) {
8528 if (sscanf(v
->value
, "%d", &peer
->pokefreqnotok
) != 1) {
8529 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
);
8530 } else ast_log(LOG_WARNING
, "Set peer->pokefreqnotok to %d\n", peer
->pokefreqnotok
);
8531 } else if (!strcasecmp(v
->name
, "timezone")) {
8532 ast_string_field_set(peer
, zonetag
, v
->value
);
8533 } else if (!strcasecmp(v
->name
, "adsi")) {
8534 peer
->adsi
= ast_true(v
->value
);
8535 }/* else if (strcasecmp(v->name,"type")) */
8536 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8543 if (!peer
->authmethods
)
8544 peer
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8545 ast_clear_flag(peer
, IAX_DELME
);
8546 /* Make sure these are IPv4 addresses */
8547 peer
->addr
.sin_family
= AF_INET
;
8554 /*! \brief Create in-memory user structure from configuration */
8555 static struct iax2_user
*build_user(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
)
8557 struct iax2_user
*user
= NULL
;
8558 struct iax2_context
*con
, *conl
= NULL
;
8559 struct ast_ha
*oldha
= NULL
;
8560 struct iax2_context
*oldcon
= NULL
;
8563 int oldcurauthreq
= 0;
8564 char *varname
= NULL
, *varval
= NULL
;
8565 struct ast_variable
*tmpvar
= NULL
;
8567 AST_LIST_LOCK(&users
);
8569 AST_LIST_TRAVERSE(&users
, user
, entry
) {
8570 if (!strcmp(user
->name
, name
)) {
8571 if (!ast_test_flag(user
, IAX_DELME
))
8581 oldcurauthreq
= user
->curauthreq
;
8583 oldcon
= user
->contexts
;
8585 user
->contexts
= NULL
;
8587 /* Already in the list, remove it and it will be added back (or FREE'd) */
8588 AST_LIST_REMOVE(&users
, user
, entry
);
8589 AST_LIST_UNLOCK(&users
);
8591 AST_LIST_UNLOCK(&users
);
8592 /* This is going to memset'd to 0 in the next block */
8593 user
= ast_calloc(sizeof(*user
),1);
8598 ast_string_field_free_pools(user
);
8599 memset(user
, 0, sizeof(struct iax2_user
));
8600 if (ast_string_field_init(user
, 32)) {
8604 user
->maxauthreq
= maxauthreq
;
8605 user
->curauthreq
= oldcurauthreq
;
8606 user
->prefs
= prefs
;
8607 user
->capability
= iax2_capability
;
8608 user
->encmethods
= iax2_encryption
;
8610 ast_string_field_set(user
, name
, name
);
8611 ast_string_field_set(user
, language
, language
);
8612 ast_copy_flags(user
, &globalflags
, IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
| IAX_CODEC_USER_FIRST
| IAX_CODEC_NOPREFS
| IAX_CODEC_NOCAP
);
8613 ast_clear_flag(user
, IAX_HASCALLERID
);
8614 ast_string_field_set(user
, cid_name
, "");
8615 ast_string_field_set(user
, cid_num
, "");
8622 if (!strcasecmp(v
->name
, "context")) {
8623 con
= build_context(v
->value
);
8628 user
->contexts
= con
;
8631 } else if (!strcasecmp(v
->name
, "permit") ||
8632 !strcasecmp(v
->name
, "deny")) {
8633 user
->ha
= ast_append_ha(v
->name
, v
->value
, user
->ha
);
8634 } else if (!strcasecmp(v
->name
, "setvar")) {
8635 varname
= ast_strdupa(v
->value
);
8636 if (varname
&& (varval
= strchr(varname
,'='))) {
8639 if((tmpvar
= ast_variable_new(varname
, varval
))) {
8640 tmpvar
->next
= user
->vars
;
8641 user
->vars
= tmpvar
;
8644 } else if (!strcasecmp(v
->name
, "allow")) {
8645 ast_parse_allow_disallow(&user
->prefs
, &user
->capability
, v
->value
, 1);
8646 } else if (!strcasecmp(v
->name
, "disallow")) {
8647 ast_parse_allow_disallow(&user
->prefs
, &user
->capability
,v
->value
, 0);
8648 } else if (!strcasecmp(v
->name
, "trunk")) {
8649 ast_set2_flag(user
, ast_true(v
->value
), IAX_TRUNK
);
8650 if (ast_test_flag(user
, IAX_TRUNK
) && (timingfd
< 0)) {
8651 ast_log(LOG_WARNING
, "Unable to support trunking on user '%s' without zaptel timing\n", user
->name
);
8652 ast_clear_flag(user
, IAX_TRUNK
);
8654 } else if (!strcasecmp(v
->name
, "auth")) {
8655 user
->authmethods
= get_auth_methods(v
->value
);
8656 } else if (!strcasecmp(v
->name
, "encryption")) {
8657 user
->encmethods
= get_encrypt_methods(v
->value
);
8658 } else if (!strcasecmp(v
->name
, "notransfer")) {
8659 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8660 ast_clear_flag(user
, IAX_TRANSFERMEDIA
);
8661 ast_set2_flag(user
, ast_true(v
->value
), IAX_NOTRANSFER
);
8662 } else if (!strcasecmp(v
->name
, "transfer")) {
8663 if (!strcasecmp(v
->value
, "mediaonly")) {
8664 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8665 } else if (ast_true(v
->value
)) {
8666 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8668 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8669 } else if (!strcasecmp(v
->name
, "codecpriority")) {
8670 if(!strcasecmp(v
->value
, "caller"))
8671 ast_set_flag(user
, IAX_CODEC_USER_FIRST
);
8672 else if(!strcasecmp(v
->value
, "disabled"))
8673 ast_set_flag(user
, IAX_CODEC_NOPREFS
);
8674 else if(!strcasecmp(v
->value
, "reqonly")) {
8675 ast_set_flag(user
, IAX_CODEC_NOCAP
);
8676 ast_set_flag(user
, IAX_CODEC_NOPREFS
);
8678 } else if (!strcasecmp(v
->name
, "jitterbuffer")) {
8679 ast_set2_flag(user
, ast_true(v
->value
), IAX_USEJITTERBUF
);
8680 } else if (!strcasecmp(v
->name
, "forcejitterbuffer")) {
8681 ast_set2_flag(user
, ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8682 } else if (!strcasecmp(v
->name
, "dbsecret")) {
8683 ast_string_field_set(user
, dbsecret
, v
->value
);
8684 } else if (!strcasecmp(v
->name
, "secret")) {
8685 if (!ast_strlen_zero(user
->secret
)) {
8686 char *old
= ast_strdupa(user
->secret
);
8688 ast_string_field_build(user
, secret
, "%s;%s", old
, v
->value
);
8690 ast_string_field_set(user
, secret
, v
->value
);
8691 } else if (!strcasecmp(v
->name
, "callerid")) {
8692 if (!ast_strlen_zero(v
->value
) && strcasecmp(v
->value
, "asreceived")) {
8695 ast_callerid_split(v
->value
, name2
, sizeof(name2
), num2
, sizeof(num2
));
8696 ast_string_field_set(user
, cid_name
, name2
);
8697 ast_string_field_set(user
, cid_num
, num2
);
8698 ast_set_flag(user
, IAX_HASCALLERID
);
8700 ast_clear_flag(user
, IAX_HASCALLERID
);
8701 ast_string_field_set(user
, cid_name
, "");
8702 ast_string_field_set(user
, cid_num
, "");
8704 } else if (!strcasecmp(v
->name
, "fullname")) {
8705 if (!ast_strlen_zero(v
->value
)) {
8706 ast_string_field_set(user
, cid_name
, v
->value
);
8707 ast_set_flag(user
, IAX_HASCALLERID
);
8709 ast_string_field_set(user
, cid_name
, "");
8710 if (ast_strlen_zero(user
->cid_num
))
8711 ast_clear_flag(user
, IAX_HASCALLERID
);
8713 } else if (!strcasecmp(v
->name
, "cid_number")) {
8714 if (!ast_strlen_zero(v
->value
)) {
8715 ast_string_field_set(user
, cid_num
, v
->value
);
8716 ast_set_flag(user
, IAX_HASCALLERID
);
8718 ast_string_field_set(user
, cid_num
, "");
8719 if (ast_strlen_zero(user
->cid_name
))
8720 ast_clear_flag(user
, IAX_HASCALLERID
);
8722 } else if (!strcasecmp(v
->name
, "accountcode")) {
8723 ast_string_field_set(user
, accountcode
, v
->value
);
8724 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
8725 ast_string_field_set(user
, mohinterpret
, v
->value
);
8726 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
8727 ast_string_field_set(user
, mohsuggest
, v
->value
);
8728 } else if (!strcasecmp(v
->name
, "language")) {
8729 ast_string_field_set(user
, language
, v
->value
);
8730 } else if (!strcasecmp(v
->name
, "amaflags")) {
8731 format
= ast_cdr_amaflags2int(v
->value
);
8733 ast_log(LOG_WARNING
, "Invalid AMA Flags: %s at line %d\n", v
->value
, v
->lineno
);
8735 user
->amaflags
= format
;
8737 } else if (!strcasecmp(v
->name
, "inkeys")) {
8738 ast_string_field_set(user
, inkeys
, v
->value
);
8739 } else if (!strcasecmp(v
->name
, "maxauthreq")) {
8740 user
->maxauthreq
= atoi(v
->value
);
8741 if (user
->maxauthreq
< 0)
8742 user
->maxauthreq
= 0;
8743 } else if (!strcasecmp(v
->name
, "adsi")) {
8744 user
->adsi
= ast_true(v
->value
);
8745 }/* else if (strcasecmp(v->name,"type")) */
8746 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8753 if (!user
->authmethods
) {
8754 if (!ast_strlen_zero(user
->secret
)) {
8755 user
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8756 if (!ast_strlen_zero(user
->inkeys
))
8757 user
->authmethods
|= IAX_AUTH_RSA
;
8758 } else if (!ast_strlen_zero(user
->inkeys
)) {
8759 user
->authmethods
= IAX_AUTH_RSA
;
8761 user
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8764 ast_clear_flag(user
, IAX_DELME
);
8769 free_context(oldcon
);
8773 static void delete_users(void)
8775 struct iax2_user
*user
;
8776 struct iax2_peer
*peer
;
8777 struct iax2_registry
*reg
;
8779 AST_LIST_LOCK(&users
);
8780 AST_LIST_TRAVERSE(&users
, user
, entry
)
8781 ast_set_flag(user
, IAX_DELME
);
8782 AST_LIST_UNLOCK(&users
);
8784 AST_LIST_LOCK(®istrations
);
8785 while ((reg
= AST_LIST_REMOVE_HEAD(®istrations
, entry
))) {
8786 if (reg
->expire
> -1)
8787 ast_sched_del(sched
, reg
->expire
);
8789 ast_mutex_lock(&iaxsl
[reg
->callno
]);
8790 if (iaxs
[reg
->callno
]) {
8791 iaxs
[reg
->callno
]->reg
= NULL
;
8792 iax2_destroy(reg
->callno
);
8794 ast_mutex_unlock(&iaxsl
[reg
->callno
]);
8797 ast_dnsmgr_release(reg
->dnsmgr
);
8800 AST_LIST_UNLOCK(®istrations
);
8802 AST_LIST_LOCK(&peers
);
8803 AST_LIST_TRAVERSE(&peers
, peer
, entry
)
8804 ast_set_flag(peer
, IAX_DELME
);
8805 AST_LIST_UNLOCK(&peers
);
8808 static void destroy_user(struct iax2_user
*user
)
8810 ast_free_ha(user
->ha
);
8811 free_context(user
->contexts
);
8813 ast_variables_destroy(user
->vars
);
8816 ast_string_field_free_pools(user
);
8820 static void prune_users(void)
8822 struct iax2_user
*user
= NULL
;
8824 AST_LIST_LOCK(&users
);
8825 AST_LIST_TRAVERSE_SAFE_BEGIN(&users
, user
, entry
) {
8826 if (ast_test_flag(user
, IAX_DELME
)) {
8828 AST_LIST_REMOVE_CURRENT(&users
, entry
);
8831 AST_LIST_TRAVERSE_SAFE_END
8832 AST_LIST_UNLOCK(&users
);
8836 static void destroy_peer(struct iax2_peer
*peer
)
8838 ast_free_ha(peer
->ha
);
8840 /* Delete it, it needs to disappear */
8841 if (peer
->expire
> -1)
8842 ast_sched_del(sched
, peer
->expire
);
8843 if (peer
->pokeexpire
> -1)
8844 ast_sched_del(sched
, peer
->pokeexpire
);
8845 if (peer
->callno
> 0) {
8846 ast_mutex_lock(&iaxsl
[peer
->callno
]);
8847 iax2_destroy(peer
->callno
);
8848 ast_mutex_unlock(&iaxsl
[peer
->callno
]);
8851 register_peer_exten(peer
, 0);
8854 ast_dnsmgr_release(peer
->dnsmgr
);
8856 ast_string_field_free_pools(peer
);
8861 static void prune_peers(void){
8862 /* Prune peers who still are supposed to be deleted */
8863 struct iax2_peer
*peer
= NULL
;
8865 AST_LIST_LOCK(&peers
);
8866 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers
, peer
, entry
) {
8867 if (ast_test_flag(peer
, IAX_DELME
)) {
8869 AST_LIST_REMOVE_CURRENT(&peers
, entry
);
8872 AST_LIST_TRAVERSE_SAFE_END
8873 AST_LIST_UNLOCK(&peers
);
8876 static void set_timing(void)
8879 int bs
= trunkfreq
* 8;
8880 if (timingfd
> -1) {
8883 ioctl(timingfd
, ZT_TIMERCONFIG
, &bs
) &&
8885 ioctl(timingfd
, ZT_SET_BLOCKSIZE
, &bs
))
8886 ast_log(LOG_WARNING
, "Unable to set blocksize on timing source\n");
8892 /*! \brief Load configuration */
8893 static int set_config(char *config_file
, int reload
)
8895 struct ast_config
*cfg
, *ucfg
;
8896 int capability
=iax2_capability
;
8897 struct ast_variable
*v
;
8902 int portno
= IAX_DEFAULT_PORTNO
;
8904 struct iax2_user
*user
;
8905 struct iax2_peer
*peer
;
8906 struct ast_netsock
*ns
;
8908 static unsigned short int last_port
=0;
8911 cfg
= ast_config_load(config_file
);
8914 ast_log(LOG_ERROR
, "Unable to load config %s\n", config_file
);
8918 /* Reset global codec prefs */
8919 memset(&prefs
, 0 , sizeof(struct ast_codec_pref
));
8921 /* Reset Global Flags */
8922 memset(&globalflags
, 0, sizeof(globalflags
));
8923 ast_set_flag(&globalflags
, IAX_RTUPDATE
);
8929 min_reg_expire
= IAX_DEFAULT_REG_EXPIRE
;
8930 max_reg_expire
= IAX_DEFAULT_REG_EXPIRE
;
8934 v
= ast_variable_browse(cfg
, "general");
8936 /* Seed initial tos value */
8937 tosval
= ast_variable_retrieve(cfg
, "general", "tos");
8939 if (ast_str2tos(tosval
, &tos
))
8940 ast_log(LOG_WARNING
, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
8943 if (!strcasecmp(v
->name
, "bindport")){
8945 ast_log(LOG_NOTICE
, "Ignoring bindport on reload\n");
8947 portno
= atoi(v
->value
);
8948 } else if (!strcasecmp(v
->name
, "pingtime"))
8949 ping_time
= atoi(v
->value
);
8950 else if (!strcasecmp(v
->name
, "iaxthreadcount")) {
8952 if (atoi(v
->value
) != iaxthreadcount
)
8953 ast_log(LOG_NOTICE
, "Ignoring any changes to iaxthreadcount during reload\n");
8955 iaxthreadcount
= atoi(v
->value
);
8956 if (iaxthreadcount
< 1) {
8957 ast_log(LOG_NOTICE
, "iaxthreadcount must be at least 1.\n");
8959 } else if (iaxthreadcount
> 256) {
8960 ast_log(LOG_NOTICE
, "limiting iaxthreadcount to 256\n");
8961 iaxthreadcount
= 256;
8964 } else if (!strcasecmp(v
->name
, "iaxmaxthreadcount")) {
8966 AST_LIST_LOCK(&dynamic_list
);
8967 iaxmaxthreadcount
= atoi(v
->value
);
8968 AST_LIST_UNLOCK(&dynamic_list
);
8970 iaxmaxthreadcount
= atoi(v
->value
);
8971 if (iaxmaxthreadcount
< 0) {
8972 ast_log(LOG_NOTICE
, "iaxmaxthreadcount must be at least 0.\n");
8973 iaxmaxthreadcount
= 0;
8974 } else if (iaxmaxthreadcount
> 256) {
8975 ast_log(LOG_NOTICE
, "Limiting iaxmaxthreadcount to 256\n");
8976 iaxmaxthreadcount
= 256;
8979 } else if (!strcasecmp(v
->name
, "nochecksums")) {
8981 if (ast_true(v
->value
))
8986 if (ast_true(v
->value
))
8987 ast_log(LOG_WARNING
, "Disabling RTP checksums is not supported on this operating system!\n");
8990 else if (!strcasecmp(v
->name
, "maxjitterbuffer"))
8991 maxjitterbuffer
= atoi(v
->value
);
8992 else if (!strcasecmp(v
->name
, "resyncthreshold"))
8993 resyncthreshold
= atoi(v
->value
);
8994 else if (!strcasecmp(v
->name
, "maxjitterinterps"))
8995 maxjitterinterps
= atoi(v
->value
);
8996 else if (!strcasecmp(v
->name
, "lagrqtime"))
8997 lagrq_time
= atoi(v
->value
);
8998 else if (!strcasecmp(v
->name
, "maxregexpire"))
8999 max_reg_expire
= atoi(v
->value
);
9000 else if (!strcasecmp(v
->name
, "minregexpire"))
9001 min_reg_expire
= atoi(v
->value
);
9002 else if (!strcasecmp(v
->name
, "bindaddr")) {
9004 ast_log(LOG_NOTICE
, "Ignoring bindaddr on reload\n");
9006 if (!(ns
= ast_netsock_bind(netsock
, io
, v
->value
, portno
, tos
, socket_read
, NULL
))) {
9007 ast_log(LOG_WARNING
, "Unable apply binding to '%s' at line %d\n", v
->value
, v
->lineno
);
9009 if (option_verbose
> 1) {
9010 if (strchr(v
->value
, ':'))
9011 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to '%s'\n", v
->value
);
9013 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to '%s:%d'\n", v
->value
, portno
);
9015 if (defaultsockfd
< 0)
9016 defaultsockfd
= ast_netsock_sockfd(ns
);
9017 ast_netsock_unref(ns
);
9020 } else if (!strcasecmp(v
->name
, "authdebug"))
9021 authdebug
= ast_true(v
->value
);
9022 else if (!strcasecmp(v
->name
, "encryption"))
9023 iax2_encryption
= get_encrypt_methods(v
->value
);
9024 else if (!strcasecmp(v
->name
, "notransfer")) {
9025 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
9026 ast_clear_flag((&globalflags
), IAX_TRANSFERMEDIA
);
9027 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_NOTRANSFER
);
9028 } else if (!strcasecmp(v
->name
, "transfer")) {
9029 if (!strcasecmp(v
->value
, "mediaonly")) {
9030 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
9031 } else if (ast_true(v
->value
)) {
9032 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
9034 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
9035 } else if (!strcasecmp(v
->name
, "codecpriority")) {
9036 if(!strcasecmp(v
->value
, "caller"))
9037 ast_set_flag((&globalflags
), IAX_CODEC_USER_FIRST
);
9038 else if(!strcasecmp(v
->value
, "disabled"))
9039 ast_set_flag((&globalflags
), IAX_CODEC_NOPREFS
);
9040 else if(!strcasecmp(v
->value
, "reqonly")) {
9041 ast_set_flag((&globalflags
), IAX_CODEC_NOCAP
);
9042 ast_set_flag((&globalflags
), IAX_CODEC_NOPREFS
);
9044 } else if (!strcasecmp(v
->name
, "jitterbuffer"))
9045 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_USEJITTERBUF
);
9046 else if (!strcasecmp(v
->name
, "forcejitterbuffer"))
9047 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_FORCEJITTERBUF
);
9048 else if (!strcasecmp(v
->name
, "delayreject"))
9049 delayreject
= ast_true(v
->value
);
9050 else if (!strcasecmp(v
->name
, "rtcachefriends"))
9051 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTCACHEFRIENDS
);
9052 else if (!strcasecmp(v
->name
, "rtignoreregexpire"))
9053 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTIGNOREREGEXPIRE
);
9054 else if (!strcasecmp(v
->name
, "rtupdate"))
9055 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTUPDATE
);
9056 else if (!strcasecmp(v
->name
, "trunktimestamps"))
9057 ast_set2_flag(&globalflags
, ast_true(v
->value
), IAX_TRUNKTIMESTAMPS
);
9058 else if (!strcasecmp(v
->name
, "rtautoclear")) {
9059 int i
= atoi(v
->value
);
9061 global_rtautoclear
= i
;
9064 ast_set2_flag((&globalflags
), i
|| ast_true(v
->value
), IAX_RTAUTOCLEAR
);
9065 } else if (!strcasecmp(v
->name
, "trunkfreq")) {
9066 trunkfreq
= atoi(v
->value
);
9069 } else if (!strcasecmp(v
->name
, "autokill")) {
9070 if (sscanf(v
->value
, "%d", &x
) == 1) {
9074 ast_log(LOG_NOTICE
, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v
->lineno
);
9075 } else if (ast_true(v
->value
)) {
9076 autokill
= DEFAULT_MAXMS
;
9080 } else if (!strcasecmp(v
->name
, "bandwidth")) {
9081 if (!strcasecmp(v
->value
, "low")) {
9082 capability
= IAX_CAPABILITY_LOWBANDWIDTH
;
9083 } else if (!strcasecmp(v
->value
, "medium")) {
9084 capability
= IAX_CAPABILITY_MEDBANDWIDTH
;
9085 } else if (!strcasecmp(v
->value
, "high")) {
9086 capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
9088 ast_log(LOG_WARNING
, "bandwidth must be either low, medium, or high\n");
9089 } else if (!strcasecmp(v
->name
, "allow")) {
9090 ast_parse_allow_disallow(&prefs
, &capability
, v
->value
, 1);
9091 } else if (!strcasecmp(v
->name
, "disallow")) {
9092 ast_parse_allow_disallow(&prefs
, &capability
, v
->value
, 0);
9093 } else if (!strcasecmp(v
->name
, "register")) {
9094 iax2_register(v
->value
, v
->lineno
);
9095 } else if (!strcasecmp(v
->name
, "iaxcompat")) {
9096 iaxcompat
= ast_true(v
->value
);
9097 } else if (!strcasecmp(v
->name
, "regcontext")) {
9098 ast_copy_string(regcontext
, v
->value
, sizeof(regcontext
));
9099 /* Create context if it doesn't exist already */
9100 if (!ast_context_find(regcontext
))
9101 ast_context_create(NULL
, regcontext
, "IAX2");
9102 } else if (!strcasecmp(v
->name
, "tos")) {
9103 if (ast_str2tos(v
->value
, &tos
))
9104 ast_log(LOG_WARNING
, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v
->lineno
);
9105 } else if (!strcasecmp(v
->name
, "accountcode")) {
9106 ast_copy_string(accountcode
, v
->value
, sizeof(accountcode
));
9107 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
9108 ast_copy_string(mohinterpret
, v
->value
, sizeof(user
->mohinterpret
));
9109 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
9110 ast_copy_string(mohsuggest
, v
->value
, sizeof(user
->mohsuggest
));
9111 } else if (!strcasecmp(v
->name
, "amaflags")) {
9112 format
= ast_cdr_amaflags2int(v
->value
);
9114 ast_log(LOG_WARNING
, "Invalid AMA Flags: %s at line %d\n", v
->value
, v
->lineno
);
9118 } else if (!strcasecmp(v
->name
, "language")) {
9119 ast_copy_string(language
, v
->value
, sizeof(language
));
9120 } else if (!strcasecmp(v
->name
, "maxauthreq")) {
9121 maxauthreq
= atoi(v
->value
);
9124 } else if (!strcasecmp(v
->name
, "adsi")) {
9125 adsi
= ast_true(v
->value
);
9126 } /*else if (strcasecmp(v->name,"type")) */
9127 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
9131 if (defaultsockfd
< 0) {
9132 if (!(ns
= ast_netsock_bind(netsock
, io
, "0.0.0.0", portno
, tos
, socket_read
, NULL
))) {
9133 ast_log(LOG_ERROR
, "Unable to create network socket: %s\n", strerror(errno
));
9135 if (option_verbose
> 1)
9136 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to default address 0.0.0.0:%d\n", portno
);
9137 defaultsockfd
= ast_netsock_sockfd(ns
);
9138 ast_netsock_unref(ns
);
9142 ast_netsock_release(outsock
);
9143 outsock
= ast_netsock_list_alloc();
9145 ast_log(LOG_ERROR
, "Could not allocate outsock list.\n");
9148 ast_netsock_init(outsock
);
9151 if (min_reg_expire
> max_reg_expire
) {
9152 ast_log(LOG_WARNING
, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
9153 min_reg_expire
, max_reg_expire
, max_reg_expire
);
9154 min_reg_expire
= max_reg_expire
;
9156 iax2_capability
= capability
;
9158 ucfg
= ast_config_load("users.conf");
9160 struct ast_variable
*gen
;
9163 const char *hasiax
, *registeriax
;
9165 genhasiax
= ast_true(ast_variable_retrieve(ucfg
, "general", "hasiax"));
9166 genregisteriax
= ast_true(ast_variable_retrieve(ucfg
, "general", "registeriax"));
9167 gen
= ast_variable_browse(ucfg
, "general");
9168 cat
= ast_category_browse(ucfg
, NULL
);
9170 if (strcasecmp(cat
, "general")) {
9171 hasiax
= ast_variable_retrieve(ucfg
, cat
, "hasiax");
9172 registeriax
= ast_variable_retrieve(ucfg
, cat
, "registeriax");
9173 if (ast_true(hasiax
) || (!hasiax
&& genhasiax
)) {
9174 /* Start with general parameters, then specific parameters, user and peer */
9175 user
= build_user(cat
, gen
, ast_variable_browse(ucfg
, cat
), 0);
9177 AST_LIST_LOCK(&users
);
9178 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
9179 AST_LIST_UNLOCK(&users
);
9181 peer
= build_peer(cat
, gen
, ast_variable_browse(ucfg
, cat
), 0);
9183 AST_LIST_LOCK(&peers
);
9184 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
9185 AST_LIST_UNLOCK(&peers
);
9186 if (ast_test_flag(peer
, IAX_DYNAMIC
))
9187 reg_source_db(peer
);
9190 if (ast_true(registeriax
) || (!registeriax
&& genregisteriax
)) {
9192 const char *host
= ast_variable_retrieve(ucfg
, cat
, "host");
9193 const char *username
= ast_variable_retrieve(ucfg
, cat
, "username");
9194 const char *secret
= ast_variable_retrieve(ucfg
, cat
, "secret");
9196 host
= ast_variable_retrieve(ucfg
, "general", "host");
9198 username
= ast_variable_retrieve(ucfg
, "general", "username");
9200 secret
= ast_variable_retrieve(ucfg
, "general", "secret");
9201 if (!ast_strlen_zero(username
) && !ast_strlen_zero(host
)) {
9202 if (!ast_strlen_zero(secret
))
9203 snprintf(tmp
, sizeof(tmp
), "%s:%s@%s", username
, secret
, host
);
9205 snprintf(tmp
, sizeof(tmp
), "%s@%s", username
, host
);
9206 iax2_register(tmp
, 0);
9210 cat
= ast_category_browse(ucfg
, cat
);
9212 ast_config_destroy(ucfg
);
9215 cat
= ast_category_browse(cfg
, NULL
);
9217 if (strcasecmp(cat
, "general")) {
9218 utype
= ast_variable_retrieve(cfg
, cat
, "type");
9220 if (!strcasecmp(utype
, "user") || !strcasecmp(utype
, "friend")) {
9221 user
= build_user(cat
, ast_variable_browse(cfg
, cat
), NULL
, 0);
9223 AST_LIST_LOCK(&users
);
9224 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
9225 AST_LIST_UNLOCK(&users
);
9228 if (!strcasecmp(utype
, "peer") || !strcasecmp(utype
, "friend")) {
9229 peer
= build_peer(cat
, ast_variable_browse(cfg
, cat
), NULL
, 0);
9231 AST_LIST_LOCK(&peers
);
9232 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
9233 AST_LIST_UNLOCK(&peers
);
9234 if (ast_test_flag(peer
, IAX_DYNAMIC
))
9235 reg_source_db(peer
);
9237 } else if (strcasecmp(utype
, "user")) {
9238 ast_log(LOG_WARNING
, "Unknown type '%s' for '%s' in %s\n", utype
, cat
, config_file
);
9241 ast_log(LOG_WARNING
, "Section '%s' lacks type\n", cat
);
9243 cat
= ast_category_browse(cfg
, cat
);
9245 ast_config_destroy(cfg
);
9250 static int reload_config(void)
9252 char *config
= "iax.conf";
9253 struct iax2_registry
*reg
;
9254 struct iax2_peer
*peer
;
9256 strcpy(accountcode
, "");
9257 strcpy(language
, "");
9258 strcpy(mohinterpret
, "default");
9259 strcpy(mohsuggest
, "");
9262 ast_clear_flag((&globalflags
), IAX_NOTRANSFER
);
9263 ast_clear_flag((&globalflags
), IAX_TRANSFERMEDIA
);
9264 ast_clear_flag((&globalflags
), IAX_USEJITTERBUF
);
9265 ast_clear_flag((&globalflags
), IAX_FORCEJITTERBUF
);
9267 set_config(config
, 1);
9270 AST_LIST_LOCK(®istrations
);
9271 AST_LIST_TRAVERSE(®istrations
, reg
, entry
)
9272 iax2_do_register(reg
);
9273 AST_LIST_UNLOCK(®istrations
);
9274 /* Qualify hosts, too */
9275 AST_LIST_LOCK(&peers
);
9276 AST_LIST_TRAVERSE(&peers
, peer
, entry
)
9277 iax2_poke_peer(peer
, 0);
9278 AST_LIST_UNLOCK(&peers
);
9280 iax_provision_reload();
9285 static int iax2_reload(int fd
, int argc
, char *argv
[])
9287 return reload_config();
9290 static int reload(void)
9292 return reload_config();
9295 static int cache_get_callno_locked(const char *data
)
9297 struct sockaddr_in sin
;
9300 struct iax_ie_data ied
;
9301 struct create_addr_info cai
;
9302 struct parsed_dial_string pds
;
9305 for (x
=0; x
<IAX_MAX_CALLS
; x
++) {
9306 /* Look for an *exact match* call. Once a call is negotiated, it can only
9307 look up entries for a single context */
9308 if (!ast_mutex_trylock(&iaxsl
[x
])) {
9309 if (iaxs
[x
] && !strcasecmp(data
, iaxs
[x
]->dproot
))
9311 ast_mutex_unlock(&iaxsl
[x
]);
9315 /* No match found, we need to create a new one */
9317 memset(&cai
, 0, sizeof(cai
));
9318 memset(&ied
, 0, sizeof(ied
));
9319 memset(&pds
, 0, sizeof(pds
));
9321 tmpstr
= ast_strdupa(data
);
9322 parse_dial_string(tmpstr
, &pds
);
9324 /* Populate our address from the given */
9325 if (create_addr(pds
.peer
, &sin
, &cai
))
9328 ast_log(LOG_DEBUG
, "peer: %s, username: %s, password: %s, context: %s\n",
9329 pds
.peer
, pds
.username
, pds
.password
, pds
.context
);
9331 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
9333 ast_log(LOG_WARNING
, "Unable to create call\n");
9337 ast_mutex_lock(&iaxsl
[callno
]);
9338 ast_string_field_set(iaxs
[callno
], dproot
, data
);
9339 iaxs
[callno
]->capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
9341 iax_ie_append_short(&ied
, IAX_IE_VERSION
, IAX_PROTO_VERSION
);
9342 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, "TBD");
9343 /* the string format is slightly different from a standard dial string,
9344 because the context appears in the 'exten' position
9347 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, pds
.exten
);
9349 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, pds
.username
);
9350 iax_ie_append_int(&ied
, IAX_IE_FORMAT
, IAX_CAPABILITY_FULLBANDWIDTH
);
9351 iax_ie_append_int(&ied
, IAX_IE_CAPABILITY
, IAX_CAPABILITY_FULLBANDWIDTH
);
9352 /* Keep password handy */
9354 ast_string_field_set(iaxs
[callno
], secret
, pds
.password
);
9356 ast_string_field_set(iaxs
[callno
], outkey
, pds
.key
);
9357 /* Start the call going */
9358 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_NEW
, 0, ied
.buf
, ied
.pos
, -1);
9363 static struct iax2_dpcache
*find_cache(struct ast_channel
*chan
, const char *data
, const char *context
, const char *exten
, int priority
)
9365 struct iax2_dpcache
*dp
, *prev
= NULL
, *next
;
9374 struct ast_channel
*c
;
9375 struct ast_frame
*f
;
9376 gettimeofday(&tv
, NULL
);
9380 /* Expire old caches */
9381 if (ast_tvcmp(tv
, dp
->expiry
) > 0) {
9382 /* It's expired, let it disappear */
9384 prev
->next
= dp
->next
;
9387 if (!dp
->peer
&& !(dp
->flags
& CACHE_FLAG_PENDING
) && !dp
->callno
) {
9388 /* Free memory and go again */
9391 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
);
9396 /* We found an entry that matches us! */
9397 if (!strcmp(dp
->peercontext
, data
) && !strcmp(dp
->exten
, exten
))
9403 /* No matching entry. Create a new one. */
9404 /* First, can we make a callno? */
9405 callno
= cache_get_callno_locked(data
);
9407 ast_log(LOG_WARNING
, "Unable to generate call for '%s'\n", data
);
9410 if (!(dp
= ast_calloc(1, sizeof(*dp
)))) {
9411 ast_mutex_unlock(&iaxsl
[callno
]);
9414 ast_copy_string(dp
->peercontext
, data
, sizeof(dp
->peercontext
));
9415 ast_copy_string(dp
->exten
, exten
, sizeof(dp
->exten
));
9416 gettimeofday(&dp
->expiry
, NULL
);
9417 dp
->orig
= dp
->expiry
;
9418 /* Expires in 30 mins by default */
9419 dp
->expiry
.tv_sec
+= iaxdefaultdpcache
;
9421 dp
->flags
= CACHE_FLAG_PENDING
;
9422 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
9423 dp
->waiters
[x
] = -1;
9425 dp
->peer
= iaxs
[callno
]->dpentries
;
9426 iaxs
[callno
]->dpentries
= dp
;
9427 /* Send the request if we're already up */
9428 if (ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_STARTED
))
9429 iax2_dprequest(dp
, callno
);
9430 ast_mutex_unlock(&iaxsl
[callno
]);
9432 /* By here we must have a dp */
9433 if (dp
->flags
& CACHE_FLAG_PENDING
) {
9434 /* Okay, here it starts to get nasty. We need a pipe now to wait
9435 for a reply to come back so long as it's pending */
9436 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++) {
9437 /* Find an empty slot */
9438 if (dp
->waiters
[x
] < 0)
9441 if (x
>= sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0])) {
9442 ast_log(LOG_WARNING
, "No more waiter positions available\n");
9446 ast_log(LOG_WARNING
, "Unable to create pipe for comm\n");
9449 dp
->waiters
[x
] = com
[1];
9450 /* Okay, now we wait */
9451 timeout
= iaxdefaulttimeout
* 1000;
9452 /* Temporarily unlock */
9453 ast_mutex_unlock(&dpcache_lock
);
9454 /* Defer any dtmf */
9456 old
= ast_channel_defer_dtmf(chan
);
9459 c
= ast_waitfor_nandfds(&chan
, chan
? 1 : 0, &com
[0], 1, NULL
, &outfd
, &timeout
);
9468 /* Got hung up on, abort! */
9475 ast_log(LOG_WARNING
, "Timeout waiting for %s exten %s\n", data
, exten
);
9477 ast_mutex_lock(&dpcache_lock
);
9478 dp
->waiters
[x
] = -1;
9482 /* Don't interpret anything, just abort. Not sure what th epoint
9483 of undeferring dtmf on a hung up channel is but hey whatever */
9485 ast_channel_undefer_dtmf(chan
);
9488 if (!(dp
->flags
& CACHE_FLAG_TIMEOUT
)) {
9489 /* Now to do non-independent analysis the results of our wait */
9490 if (dp
->flags
& CACHE_FLAG_PENDING
) {
9491 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
9492 pending. Don't let it take as long to timeout. */
9493 dp
->flags
&= ~CACHE_FLAG_PENDING
;
9494 dp
->flags
|= CACHE_FLAG_TIMEOUT
;
9495 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
9496 systems without leaving it unavailable once the server comes back online */
9497 dp
->expiry
.tv_sec
= dp
->orig
.tv_sec
+ 60;
9498 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
9499 if (dp
->waiters
[x
] > -1)
9500 write(dp
->waiters
[x
], "asdf", 4);
9503 /* Our caller will obtain the rest */
9505 ast_channel_undefer_dtmf(chan
);
9510 /*! \brief Part of the IAX2 switch interface */
9511 static int iax2_exists(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9513 struct iax2_dpcache
*dp
;
9516 ast_log(LOG_NOTICE
, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9518 if ((priority
!= 1) && (priority
!= 2))
9520 ast_mutex_lock(&dpcache_lock
);
9521 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9523 if (dp
->flags
& CACHE_FLAG_EXISTS
)
9526 ast_mutex_unlock(&dpcache_lock
);
9528 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9533 /*! \brief part of the IAX2 dial plan switch interface */
9534 static int iax2_canmatch(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9537 struct iax2_dpcache
*dp
;
9539 ast_log(LOG_NOTICE
, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9541 if ((priority
!= 1) && (priority
!= 2))
9543 ast_mutex_lock(&dpcache_lock
);
9544 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9546 if (dp
->flags
& CACHE_FLAG_CANEXIST
)
9549 ast_mutex_unlock(&dpcache_lock
);
9551 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9556 /*! \brief Part of the IAX2 Switch interface */
9557 static int iax2_matchmore(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9560 struct iax2_dpcache
*dp
;
9562 ast_log(LOG_NOTICE
, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9564 if ((priority
!= 1) && (priority
!= 2))
9566 ast_mutex_lock(&dpcache_lock
);
9567 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9569 if (dp
->flags
& CACHE_FLAG_MATCHMORE
)
9572 ast_mutex_unlock(&dpcache_lock
);
9574 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9579 /*! \brief Execute IAX2 dialplan switch */
9580 static int iax2_exec(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9585 struct iax2_dpcache
*dp
;
9586 struct ast_app
*dial
;
9588 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
);
9590 if (priority
== 2) {
9591 /* Indicate status, can be overridden in dialplan */
9592 const char *dialstatus
= pbx_builtin_getvar_helper(chan
, "DIALSTATUS");
9594 dial
= pbx_findapp(dialstatus
);
9596 pbx_exec(chan
, dial
, "");
9599 } else if (priority
!= 1)
9601 ast_mutex_lock(&dpcache_lock
);
9602 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9604 if (dp
->flags
& CACHE_FLAG_EXISTS
) {
9605 ast_copy_string(odata
, data
, sizeof(odata
));
9606 ncontext
= strchr(odata
, '/');
9610 snprintf(req
, sizeof(req
), "IAX2/%s/%s@%s", odata
, exten
, ncontext
);
9612 snprintf(req
, sizeof(req
), "IAX2/%s/%s", odata
, exten
);
9614 if (option_verbose
> 2)
9615 ast_verbose(VERBOSE_PREFIX_3
"Executing Dial('%s')\n", req
);
9617 ast_mutex_unlock(&dpcache_lock
);
9618 ast_log(LOG_WARNING
, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten
, context
, data
);
9622 ast_mutex_unlock(&dpcache_lock
);
9623 dial
= pbx_findapp("Dial");
9625 return pbx_exec(chan
, dial
, req
);
9627 ast_log(LOG_WARNING
, "No dial application registered\n");
9632 static int function_iaxpeer(struct ast_channel
*chan
, char *cmd
, char *data
, char *buf
, size_t len
)
9634 struct iax2_peer
*peer
;
9635 char *peername
, *colname
;
9637 peername
= ast_strdupa(data
);
9639 /* if our channel, return the IP address of the endpoint of current channel */
9640 if (!strcmp(peername
,"CURRENTCHANNEL")) {
9641 unsigned short callno
;
9642 if (chan
->tech
!= &iax2_tech
)
9644 callno
= PTR_TO_CALLNO(chan
->tech_pvt
);
9645 ast_copy_string(buf
, iaxs
[callno
]->addr
.sin_addr
.s_addr
? ast_inet_ntoa(iaxs
[callno
]->addr
.sin_addr
) : "", len
);
9649 if ((colname
= strchr(peername
, ':'))) /*! \todo : will be removed after the 1.4 relese */
9651 else if ((colname
= strchr(peername
, '|')))
9656 if (!(peer
= find_peer(peername
, 1)))
9659 if (!strcasecmp(colname
, "ip")) {
9660 ast_copy_string(buf
, peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "", len
);
9661 } else if (!strcasecmp(colname
, "status")) {
9662 peer_status(peer
, buf
, len
);
9663 } else if (!strcasecmp(colname
, "mailbox")) {
9664 ast_copy_string(buf
, peer
->mailbox
, len
);
9665 } else if (!strcasecmp(colname
, "context")) {
9666 ast_copy_string(buf
, peer
->context
, len
);
9667 } else if (!strcasecmp(colname
, "expire")) {
9668 snprintf(buf
, len
, "%d", peer
->expire
);
9669 } else if (!strcasecmp(colname
, "dynamic")) {
9670 ast_copy_string(buf
, (ast_test_flag(peer
, IAX_DYNAMIC
) ? "yes" : "no"), len
);
9671 } else if (!strcasecmp(colname
, "callerid_name")) {
9672 ast_copy_string(buf
, peer
->cid_name
, len
);
9673 } else if (!strcasecmp(colname
, "callerid_num")) {
9674 ast_copy_string(buf
, peer
->cid_num
, len
);
9675 } else if (!strcasecmp(colname
, "codecs")) {
9676 ast_getformatname_multiple(buf
, len
-1, peer
->capability
);
9677 } else if (!strncasecmp(colname
, "codec[", 6)) {
9678 char *codecnum
, *ptr
;
9679 int index
= 0, codec
= 0;
9681 codecnum
= strchr(colname
, '[');
9684 if ((ptr
= strchr(codecnum
, ']'))) {
9687 index
= atoi(codecnum
);
9688 if((codec
= ast_codec_pref_index(&peer
->prefs
, index
))) {
9689 ast_copy_string(buf
, ast_getformatname(codec
), len
);
9696 struct ast_custom_function iaxpeer_function
= {
9698 .synopsis
= "Gets IAX peer information",
9699 .syntax
= "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
9700 .read
= function_iaxpeer
,
9701 .desc
= "If peername specified, valid items are:\n"
9702 "- ip (default) The IP address.\n"
9703 "- status The peer's status (if qualify=yes)\n"
9704 "- mailbox The configured mailbox.\n"
9705 "- context The configured context.\n"
9706 "- expire The epoch time of the next expire.\n"
9707 "- dynamic Is it dynamic? (yes/no).\n"
9708 "- callerid_name The configured Caller ID name.\n"
9709 "- callerid_num The configured Caller ID number.\n"
9710 "- codecs The configured codecs.\n"
9711 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
9713 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
9718 /*! \brief Part of the device state notification system ---*/
9719 static int iax2_devicestate(void *data
)
9721 struct parsed_dial_string pds
;
9722 char *tmp
= ast_strdupa(data
);
9723 struct iax2_peer
*p
;
9724 int res
= AST_DEVICE_INVALID
;
9726 memset(&pds
, 0, sizeof(pds
));
9727 parse_dial_string(tmp
, &pds
);
9728 if (ast_strlen_zero(pds
.peer
))
9731 if (option_debug
> 2)
9732 ast_log(LOG_DEBUG
, "Checking device state for device %s\n", pds
.peer
);
9734 /* SLD: FIXME: second call to find_peer during registration */
9735 if (!(p
= find_peer(pds
.peer
, 1)))
9738 res
= AST_DEVICE_UNAVAILABLE
;
9739 if (option_debug
> 2)
9740 ast_log(LOG_DEBUG
, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
9741 pds
.peer
, p
->addr
.sin_addr
.s_addr
, p
->defaddr
.sin_addr
.s_addr
, p
->maxms
, p
->lastms
);
9743 if ((p
->addr
.sin_addr
.s_addr
|| p
->defaddr
.sin_addr
.s_addr
) &&
9744 (!p
->maxms
|| ((p
->lastms
> -1) && (p
->historicms
<= p
->maxms
)))) {
9745 /* Peer is registered, or have default IP address
9746 and a valid registration */
9747 if (p
->historicms
== 0 || p
->historicms
<= p
->maxms
)
9748 /* let the core figure out whether it is in use or not */
9749 res
= AST_DEVICE_UNKNOWN
;
9752 if (ast_test_flag(p
, IAX_TEMPONLY
))
9758 static struct ast_switch iax2_switch
=
9761 description
: "IAX Remote Dialplan Switch",
9762 exists
: iax2_exists
,
9763 canmatch
: iax2_canmatch
,
9765 matchmore
: iax2_matchmore
,
9768 static char show_stats_usage
[] =
9769 "Usage: iax2 show stats\n"
9770 " Display statistics on IAX channel driver.\n";
9772 static char show_cache_usage
[] =
9773 "Usage: iax2 show cache\n"
9774 " Display currently cached IAX Dialplan results.\n";
9776 static char show_peer_usage
[] =
9777 "Usage: iax2 show peer <name>\n"
9778 " Display details on specific IAX peer\n";
9780 static char prune_realtime_usage
[] =
9781 "Usage: iax2 prune realtime [<peername>|all]\n"
9782 " Prunes object(s) from the cache\n";
9784 static char iax2_reload_usage
[] =
9785 "Usage: iax2 reload\n"
9786 " Reloads IAX configuration from iax.conf\n";
9788 static char show_prov_usage
[] =
9789 "Usage: iax2 provision <host> <template> [forced]\n"
9790 " Provisions the given peer or IP address using a template\n"
9791 " matching either 'template' or '*' if the template is not\n"
9792 " found. If 'forced' is specified, even empty provisioning\n"
9793 " fields will be provisioned as empty fields.\n";
9795 static char show_users_usage
[] =
9796 "Usage: iax2 show users [like <pattern>]\n"
9797 " Lists all known IAX2 users.\n"
9798 " Optional regular expression pattern is used to filter the user list.\n";
9800 static char show_channels_usage
[] =
9801 "Usage: iax2 show channels\n"
9802 " Lists all currently active IAX channels.\n";
9804 static char show_netstats_usage
[] =
9805 "Usage: iax2 show netstats\n"
9806 " Lists network status for all currently active IAX channels.\n";
9808 static char show_threads_usage
[] =
9809 "Usage: iax2 show threads\n"
9810 " Lists status of IAX helper threads\n";
9812 static char show_peers_usage
[] =
9813 "Usage: iax2 show peers [registered] [like <pattern>]\n"
9814 " Lists all known IAX2 peers.\n"
9815 " Optional 'registered' argument lists only peers with known addresses.\n"
9816 " Optional regular expression pattern is used to filter the peer list.\n";
9818 static char show_firmware_usage
[] =
9819 "Usage: iax2 show firmware\n"
9820 " Lists all known IAX firmware images.\n";
9822 static char show_reg_usage
[] =
9823 "Usage: iax2 show registry\n"
9824 " Lists all registration requests and status.\n";
9826 static char debug_usage
[] =
9827 "Usage: iax2 set debug\n"
9828 " Enables dumping of IAX packets for debugging purposes\n";
9830 static char no_debug_usage
[] =
9831 "Usage: iax2 set debug off\n"
9832 " Disables dumping of IAX packets for debugging purposes\n";
9834 static char debug_trunk_usage
[] =
9835 "Usage: iax2 set debug trunk\n"
9836 " Requests current status of IAX trunking\n";
9838 static char no_debug_trunk_usage
[] =
9839 "Usage: iax2 set debug trunk off\n"
9840 " Requests current status of IAX trunking\n";
9842 static char debug_jb_usage
[] =
9843 "Usage: iax2 set debug jb\n"
9844 " Enables jitterbuffer debugging information\n";
9846 static char no_debug_jb_usage
[] =
9847 "Usage: iax2 set debug jb off\n"
9848 " Disables jitterbuffer debugging information\n";
9850 static char iax2_test_losspct_usage
[] =
9851 "Usage: iax2 test losspct <percentage>\n"
9852 " For testing, throws away <percentage> percent of incoming packets\n";
9855 static char iax2_test_late_usage
[] =
9856 "Usage: iax2 test late <ms>\n"
9857 " For testing, count the next frame as <ms> ms late\n";
9859 static char iax2_test_resync_usage
[] =
9860 "Usage: iax2 test resync <ms>\n"
9861 " For testing, adjust all future frames by <ms> ms\n";
9863 static char iax2_test_jitter_usage
[] =
9864 "Usage: iax2 test jitter <ms> <pct>\n"
9865 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
9866 #endif /* IAXTESTS */
9868 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated
= {
9869 { "iax2", "trunk", "debug", NULL
},
9870 iax2_do_trunk_debug
, NULL
,
9873 static struct ast_cli_entry cli_iax2_jb_debug_deprecated
= {
9874 { "iax2", "jb", "debug", NULL
},
9875 iax2_do_jb_debug
, NULL
,
9878 static struct ast_cli_entry cli_iax2_no_debug_deprecated
= {
9879 { "iax2", "no", "debug", NULL
},
9880 iax2_no_debug
, NULL
,
9883 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated
= {
9884 { "iax2", "no", "trunk", "debug", NULL
},
9885 iax2_no_trunk_debug
, NULL
,
9888 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated
= {
9889 { "iax2", "no", "jb", "debug", NULL
},
9890 iax2_no_jb_debug
, NULL
,
9893 static struct ast_cli_entry cli_iax2
[] = {
9894 { { "iax2", "show", "cache", NULL
},
9895 iax2_show_cache
, "Display IAX cached dialplan",
9896 show_cache_usage
, NULL
, },
9898 { { "iax2", "show", "channels", NULL
},
9899 iax2_show_channels
, "List active IAX channels",
9900 show_channels_usage
, NULL
, },
9902 { { "iax2", "show", "firmware", NULL
},
9903 iax2_show_firmware
, "List available IAX firmwares",
9904 show_firmware_usage
, NULL
, },
9906 { { "iax2", "show", "netstats", NULL
},
9907 iax2_show_netstats
, "List active IAX channel netstats",
9908 show_netstats_usage
, NULL
, },
9910 { { "iax2", "show", "peers", NULL
},
9911 iax2_show_peers
, "List defined IAX peers",
9912 show_peers_usage
, NULL
, },
9914 { { "iax2", "show", "registry", NULL
},
9915 iax2_show_registry
, "Display IAX registration status",
9916 show_reg_usage
, NULL
, },
9918 { { "iax2", "show", "stats", NULL
},
9919 iax2_show_stats
, "Display IAX statistics",
9920 show_stats_usage
, NULL
, },
9922 { { "iax2", "show", "threads", NULL
},
9923 iax2_show_threads
, "Display IAX helper thread info",
9924 show_threads_usage
, NULL
, },
9926 { { "iax2", "show", "users", NULL
},
9927 iax2_show_users
, "List defined IAX users",
9928 show_users_usage
, NULL
, },
9930 { { "iax2", "prune", "realtime", NULL
},
9931 iax2_prune_realtime
, "Prune a cached realtime lookup",
9932 prune_realtime_usage
, complete_iax2_show_peer
},
9934 { { "iax2", "reload", NULL
},
9935 iax2_reload
, "Reload IAX configuration",
9936 iax2_reload_usage
},
9938 { { "iax2", "show", "peer", NULL
},
9939 iax2_show_peer
, "Show details on specific IAX peer",
9940 show_peer_usage
, complete_iax2_show_peer
},
9942 { { "iax2", "set", "debug", NULL
},
9943 iax2_do_debug
, "Enable IAX debugging",
9946 { { "iax2", "set", "debug", "trunk", NULL
},
9947 iax2_do_trunk_debug
, "Enable IAX trunk debugging",
9948 debug_trunk_usage
, NULL
, &cli_iax2_trunk_debug_deprecated
},
9950 { { "iax2", "set", "debug", "jb", NULL
},
9951 iax2_do_jb_debug
, "Enable IAX jitterbuffer debugging",
9952 debug_jb_usage
, NULL
, &cli_iax2_jb_debug_deprecated
},
9954 { { "iax2", "set", "debug", "off", NULL
},
9955 iax2_no_debug
, "Disable IAX debugging",
9956 no_debug_usage
, NULL
, &cli_iax2_no_debug_deprecated
},
9958 { { "iax2", "set", "debug", "trunk", "off", NULL
},
9959 iax2_no_trunk_debug
, "Disable IAX trunk debugging",
9960 no_debug_trunk_usage
, NULL
, &cli_iax2_no_trunk_debug_deprecated
},
9962 { { "iax2", "set", "debug", "jb", "off", NULL
},
9963 iax2_no_jb_debug
, "Disable IAX jitterbuffer debugging",
9964 no_debug_jb_usage
, NULL
, &cli_iax2_no_jb_debug_deprecated
},
9966 { { "iax2", "test", "losspct", NULL
},
9967 iax2_test_losspct
, "Set IAX2 incoming frame loss percentage",
9968 iax2_test_losspct_usage
},
9970 { { "iax2", "provision", NULL
},
9971 iax2_prov_cmd
, "Provision an IAX device",
9972 show_prov_usage
, iax2_prov_complete_template_3rd
},
9975 { { "iax2", "test", "late", NULL
},
9976 iax2_test_late
, "Test the receipt of a late frame",
9977 iax2_test_late_usage
},
9979 { { "iax2", "test", "resync", NULL
},
9980 iax2_test_resync
, "Test a resync in received timestamps",
9981 iax2_test_resync_usage
},
9983 { { "iax2", "test", "jitter", NULL
},
9984 iax2_test_jitter
, "Simulates jitter for testing",
9985 iax2_test_jitter_usage
},
9986 #endif /* IAXTESTS */
9989 static int __unload_module(void)
9991 struct iax2_thread
*thread
= NULL
;
9994 /* Make sure threads do not hold shared resources when they are canceled */
9996 /* Grab the sched lock resource to keep it away from threads about to die */
9997 /* Cancel the network thread, close the net socket */
9998 if (netthreadid
!= AST_PTHREADT_NULL
) {
9999 AST_LIST_LOCK(&iaxq
.queue
);
10000 ast_mutex_lock(&sched_lock
);
10001 pthread_cancel(netthreadid
);
10002 ast_cond_signal(&sched_cond
);
10003 ast_mutex_unlock(&sched_lock
); /* Release the schedule lock resource */
10004 AST_LIST_UNLOCK(&iaxq
.queue
);
10005 pthread_join(netthreadid
, NULL
);
10007 if (schedthreadid
!= AST_PTHREADT_NULL
) {
10008 ast_mutex_lock(&sched_lock
);
10009 pthread_cancel(schedthreadid
);
10010 ast_cond_signal(&sched_cond
);
10011 ast_mutex_unlock(&sched_lock
);
10012 pthread_join(schedthreadid
, NULL
);
10015 /* Call for all threads to halt */
10016 AST_LIST_LOCK(&idle_list
);
10017 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list
, thread
, list
) {
10018 AST_LIST_REMOVE_CURRENT(&idle_list
, list
);
10019 pthread_cancel(thread
->threadid
);
10021 AST_LIST_TRAVERSE_SAFE_END
10022 AST_LIST_UNLOCK(&idle_list
);
10024 AST_LIST_LOCK(&active_list
);
10025 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list
, thread
, list
) {
10026 AST_LIST_REMOVE_CURRENT(&active_list
, list
);
10027 pthread_cancel(thread
->threadid
);
10029 AST_LIST_TRAVERSE_SAFE_END
10030 AST_LIST_UNLOCK(&active_list
);
10032 AST_LIST_LOCK(&dynamic_list
);
10033 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list
, thread
, list
) {
10034 AST_LIST_REMOVE_CURRENT(&dynamic_list
, list
);
10035 pthread_cancel(thread
->threadid
);
10037 AST_LIST_TRAVERSE_SAFE_END
10038 AST_LIST_UNLOCK(&dynamic_list
);
10040 AST_LIST_HEAD_DESTROY(&iaxq
.queue
);
10042 /* Wait for threads to exit */
10043 while(0 < iaxactivethreadcount
)
10046 ast_netsock_release(netsock
);
10047 ast_netsock_release(outsock
);
10048 for (x
=0;x
<IAX_MAX_CALLS
;x
++)
10051 ast_manager_unregister( "IAXpeers" );
10052 ast_manager_unregister( "IAXnetstats" );
10053 ast_unregister_application(papp
);
10054 ast_cli_unregister_multiple(cli_iax2
, sizeof(cli_iax2
) / sizeof(struct ast_cli_entry
));
10055 ast_unregister_switch(&iax2_switch
);
10056 ast_channel_unregister(&iax2_tech
);
10058 iax_provision_unload();
10059 sched_context_destroy(sched
);
10061 ast_mutex_destroy(&waresl
.lock
);
10063 for (x
= 0; x
< IAX_MAX_CALLS
; x
++)
10064 ast_mutex_destroy(&iaxsl
[x
]);
10069 static int unload_module(void)
10071 ast_custom_function_unregister(&iaxpeer_function
);
10072 return __unload_module();
10076 /*! \brief Load IAX2 module, load configuraiton ---*/
10077 static int load_module(void)
10079 char *config
= "iax.conf";
10082 struct iax2_registry
*reg
= NULL
;
10083 struct iax2_peer
*peer
= NULL
;
10085 ast_custom_function_register(&iaxpeer_function
);
10087 iax_set_output(iax_debug_output
);
10088 iax_set_error(iax_error_output
);
10089 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
10093 timingfd
= open("/dev/zap/timer", O_RDWR
);
10096 timingfd
= open("/dev/zap/pseudo", O_RDWR
);
10098 ast_log(LOG_WARNING
, "Unable to open IAX timing interface: %s\n", strerror(errno
));
10101 memset(iaxs
, 0, sizeof(iaxs
));
10103 for (x
=0;x
<IAX_MAX_CALLS
;x
++)
10104 ast_mutex_init(&iaxsl
[x
]);
10106 ast_cond_init(&sched_cond
, NULL
);
10108 io
= io_context_create();
10109 sched
= sched_context_create();
10111 if (!io
|| !sched
) {
10112 ast_log(LOG_ERROR
, "Out of memory\n");
10116 netsock
= ast_netsock_list_alloc();
10118 ast_log(LOG_ERROR
, "Could not allocate netsock list.\n");
10121 ast_netsock_init(netsock
);
10123 outsock
= ast_netsock_list_alloc();
10125 ast_log(LOG_ERROR
, "Could not allocate outsock list.\n");
10128 ast_netsock_init(outsock
);
10130 ast_mutex_init(&waresl
.lock
);
10132 AST_LIST_HEAD_INIT(&iaxq
.queue
);
10134 ast_cli_register_multiple(cli_iax2
, sizeof(cli_iax2
) / sizeof(struct ast_cli_entry
));
10136 ast_register_application(papp
, iax2_prov_app
, psyn
, pdescrip
);
10138 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers
, "List IAX Peers" );
10139 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats
, "Show IAX Netstats" );
10141 if(set_config(config
, 0) == -1)
10142 return AST_MODULE_LOAD_DECLINE
;
10144 if (ast_channel_register(&iax2_tech
)) {
10145 ast_log(LOG_ERROR
, "Unable to register channel class %s\n", "IAX2");
10150 if (ast_register_switch(&iax2_switch
))
10151 ast_log(LOG_ERROR
, "Unable to register IAX switch\n");
10153 res
= start_network_thread();
10155 if (option_verbose
> 1)
10156 ast_verbose(VERBOSE_PREFIX_2
"IAX Ready and Listening\n");
10158 ast_log(LOG_ERROR
, "Unable to start network thread\n");
10159 ast_netsock_release(netsock
);
10160 ast_netsock_release(outsock
);
10163 AST_LIST_LOCK(®istrations
);
10164 AST_LIST_TRAVERSE(®istrations
, reg
, entry
)
10165 iax2_do_register(reg
);
10166 AST_LIST_UNLOCK(®istrations
);
10168 AST_LIST_LOCK(&peers
);
10169 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
10170 if (peer
->sockfd
< 0)
10171 peer
->sockfd
= defaultsockfd
;
10172 iax2_poke_peer(peer
, 0);
10174 AST_LIST_UNLOCK(&peers
);
10176 iax_provision_reload();
10180 AST_MODULE_INFO(ASTERISK_GPL_KEY
, AST_MODFLAG_DEFAULT
, "Inter Asterisk eXchange (Ver 2)",
10181 .load
= load_module
,
10182 .unload
= unload_module
,