2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Implementation of Inter-Asterisk eXchange Version 2
23 * \author Mark Spencer <markster@digium.com>
26 * \arg \ref Config_iax
28 * \ingroup channel_drivers
37 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
41 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <netinet/in.h>
46 #include <arpa/inet.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/ip.h>
50 #include <sys/signal.h>
62 #include <sys/ioctl.h>
63 #include <zaptel/zaptel.h>
66 #include "asterisk/lock.h"
67 #include "asterisk/frame.h"
68 #include "asterisk/channel.h"
69 #include "asterisk/logger.h"
70 #include "asterisk/module.h"
71 #include "asterisk/pbx.h"
72 #include "asterisk/sched.h"
73 #include "asterisk/io.h"
74 #include "asterisk/config.h"
75 #include "asterisk/options.h"
76 #include "asterisk/cli.h"
77 #include "asterisk/translate.h"
78 #include "asterisk/md5.h"
79 #include "asterisk/cdr.h"
80 #include "asterisk/crypto.h"
81 #include "asterisk/acl.h"
82 #include "asterisk/manager.h"
83 #include "asterisk/callerid.h"
84 #include "asterisk/app.h"
85 #include "asterisk/astdb.h"
86 #include "asterisk/musiconhold.h"
87 #include "asterisk/features.h"
88 #include "asterisk/utils.h"
89 #include "asterisk/causes.h"
90 #include "asterisk/localtime.h"
91 #include "asterisk/aes.h"
92 #include "asterisk/dnsmgr.h"
93 #include "asterisk/devicestate.h"
94 #include "asterisk/netsock.h"
95 #include "asterisk/stringfields.h"
96 #include "asterisk/linkedlists.h"
99 #include "iax2-parser.h"
100 #include "iax2-provision.h"
101 #include "jitterbuf.h"
103 /* Define SCHED_MULTITHREADED to run the scheduler in a special
104 multithreaded mode. */
105 #define SCHED_MULTITHREADED
107 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
108 thread is actually doing. */
109 #define DEBUG_SCHED_MULTITHREAD
111 #ifndef IPTOS_MINCOST
112 #define IPTOS_MINCOST 0x02
116 static int nochecksums
= 0;
120 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
121 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
123 #define DEFAULT_THREAD_COUNT 10
124 #define DEFAULT_MAX_THREAD_COUNT 100
125 #define DEFAULT_RETRY_TIME 1000
126 #define MEMORY_SIZE 100
127 #define DEFAULT_DROP 3
128 /* Flag to use with trunk calls, keeping these calls high up. It halves our effective use
129 but keeps the division between trunked and non-trunked better. */
130 #define TRUNK_CALL_START 0x4000
132 #define DEBUG_SUPPORT
134 #define MIN_REUSE_TIME 60 /* Don't reuse a call number within 60 seconds */
136 /* Sample over last 100 units to determine historic jitter */
139 static struct ast_codec_pref prefs
;
141 static const char tdesc
[] = "Inter Asterisk eXchange Driver (Ver 2)";
143 static char context
[80] = "default";
145 static char language
[MAX_LANGUAGE
] = "";
146 static char regcontext
[AST_MAX_CONTEXT
] = "";
148 static int maxauthreq
= 3;
149 static int max_retries
= 4;
150 static int ping_time
= 20;
151 static int lagrq_time
= 10;
152 static int maxtrunkcall
= TRUNK_CALL_START
;
153 static int maxnontrunkcall
= 1;
154 static int maxjitterbuffer
=1000;
155 static int resyncthreshold
=1000;
156 static int maxjitterinterps
=10;
157 static int trunkfreq
= 20;
158 static int authdebug
= 1;
159 static int autokill
= 0;
160 static int iaxcompat
= 0;
162 static int iaxdefaultdpcache
=10 * 60; /* Cache dialplan entries for 10 minutes by default */
164 static int iaxdefaulttimeout
= 5; /* Default to wait no more than 5 seconds for a reply to come back */
166 static unsigned int tos
= 0;
168 static int min_reg_expire
;
169 static int max_reg_expire
;
171 static int timingfd
= -1; /* Timing file descriptor */
173 static struct ast_netsock_list
*netsock
;
174 static int defaultsockfd
= -1;
176 int (*iax2_regfunk
)(const char *username
, int onoff
) = NULL
;
179 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
181 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
182 ~AST_FORMAT_SLINEAR & \
187 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
189 ~AST_FORMAT_G726_AAL2 & \
192 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
196 #define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
197 #define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */
198 #define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */
200 static struct io_context
*io
;
201 static struct sched_context
*sched
;
203 static int iax2_capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
205 static int iaxdebug
= 0;
207 static int iaxtrunkdebug
= 0;
209 static int test_losspct
= 0;
211 static int test_late
= 0;
212 static int test_resync
= 0;
213 static int test_jit
= 0;
214 static int test_jitpct
= 0;
215 #endif /* IAXTESTS */
217 static char accountcode
[AST_MAX_ACCOUNT_CODE
];
218 static char mohinterpret
[MAX_MUSICCLASS
];
219 static char mohsuggest
[MAX_MUSICCLASS
];
220 static int amaflags
= 0;
222 static int delayreject
= 0;
223 static int iax2_encryption
= 0;
225 static struct ast_flags globalflags
= { 0 };
227 static pthread_t netthreadid
= AST_PTHREADT_NULL
;
228 static pthread_t schedthreadid
= AST_PTHREADT_NULL
;
229 AST_MUTEX_DEFINE_STATIC(sched_lock
);
230 static ast_cond_t sched_cond
;
233 IAX_STATE_STARTED
= (1 << 0),
234 IAX_STATE_AUTHENTICATED
= (1 << 1),
235 IAX_STATE_TBD
= (1 << 2),
236 IAX_STATE_UNCHANGED
= (1 << 3),
239 struct iax2_context
{
240 char context
[AST_MAX_CONTEXT
];
241 struct iax2_context
*next
;
245 IAX_HASCALLERID
= (1 << 0), /*!< CallerID has been specified */
246 IAX_DELME
= (1 << 1), /*!< Needs to be deleted */
247 IAX_TEMPONLY
= (1 << 2), /*!< Temporary (realtime) */
248 IAX_TRUNK
= (1 << 3), /*!< Treat as a trunk */
249 IAX_NOTRANSFER
= (1 << 4), /*!< Don't native bridge */
250 IAX_USEJITTERBUF
= (1 << 5), /*!< Use jitter buffer */
251 IAX_DYNAMIC
= (1 << 6), /*!< dynamic peer */
252 IAX_SENDANI
= (1 << 7), /*!< Send ANI along with CallerID */
253 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
254 IAX_ALREADYGONE
= (1 << 9), /*!< Already disconnected */
255 IAX_PROVISION
= (1 << 10), /*!< This is a provisioning request */
256 IAX_QUELCH
= (1 << 11), /*!< Whether or not we quelch audio */
257 IAX_ENCRYPTED
= (1 << 12), /*!< Whether we should assume encrypted tx/rx */
258 IAX_KEYPOPULATED
= (1 << 13), /*!< Whether we have a key populated */
259 IAX_CODEC_USER_FIRST
= (1 << 14), /*!< are we willing to let the other guy choose the codec? */
260 IAX_CODEC_NOPREFS
= (1 << 15), /*!< Force old behaviour by turning off prefs */
261 IAX_CODEC_NOCAP
= (1 << 16), /*!< only consider requested format and ignore capabilities*/
262 IAX_RTCACHEFRIENDS
= (1 << 17), /*!< let realtime stay till your reload */
263 IAX_RTUPDATE
= (1 << 18), /*!< Send a realtime update */
264 IAX_RTAUTOCLEAR
= (1 << 19), /*!< erase me on expire */
265 IAX_FORCEJITTERBUF
= (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
266 IAX_RTIGNOREREGEXPIRE
= (1 << 21), /*!< When using realtime, ignore registration expiration */
267 IAX_TRUNKTIMESTAMPS
= (1 << 22), /*!< Send trunk timestamps */
268 IAX_TRANSFERMEDIA
= (1 << 23), /*!< When doing IAX2 transfers, transfer media only */
269 IAX_MAXAUTHREQ
= (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */
272 static int global_rtautoclear
= 120;
274 static int reload_config(void);
275 static int iax2_reload(int fd
, int argc
, char *argv
[]);
279 AST_DECLARE_STRING_FIELDS(
280 AST_STRING_FIELD(name
);
281 AST_STRING_FIELD(secret
);
282 AST_STRING_FIELD(dbsecret
);
283 AST_STRING_FIELD(accountcode
);
284 AST_STRING_FIELD(mohinterpret
);
285 AST_STRING_FIELD(mohsuggest
);
286 AST_STRING_FIELD(inkeys
); /*!< Key(s) this user can use to authenticate to us */
287 AST_STRING_FIELD(language
);
288 AST_STRING_FIELD(cid_num
);
289 AST_STRING_FIELD(cid_name
);
298 int maxauthreq
; /*!< Maximum allowed outstanding AUTHREQs */
299 int curauthreq
; /*!< Current number of outstanding AUTHREQs */
300 struct ast_codec_pref prefs
;
302 struct iax2_context
*contexts
;
303 struct ast_variable
*vars
;
304 AST_LIST_ENTRY(iax2_user
) entry
;
308 AST_DECLARE_STRING_FIELDS(
309 AST_STRING_FIELD(name
);
310 AST_STRING_FIELD(username
);
311 AST_STRING_FIELD(secret
);
312 AST_STRING_FIELD(dbsecret
);
313 AST_STRING_FIELD(outkey
); /*!< What key we use to talk to this peer */
315 AST_STRING_FIELD(regexten
); /*!< Extension to register (if regcontext is used) */
316 AST_STRING_FIELD(context
); /*!< For transfers only */
317 AST_STRING_FIELD(peercontext
); /*!< Context to pass to peer */
318 AST_STRING_FIELD(mailbox
); /*!< Mailbox */
319 AST_STRING_FIELD(mohinterpret
);
320 AST_STRING_FIELD(mohsuggest
);
321 AST_STRING_FIELD(inkeys
); /*!< Key(s) this peer can use to authenticate to us */
322 /* Suggested caller id if registering */
323 AST_STRING_FIELD(cid_num
); /*!< Default context (for transfer really) */
324 AST_STRING_FIELD(cid_name
); /*!< Default context (for transfer really) */
325 AST_STRING_FIELD(zonetag
); /*!< Time Zone */
327 struct ast_codec_pref prefs
;
328 struct ast_dnsmgr_entry
*dnsmgr
; /*!< DNS refresh manager */
329 struct sockaddr_in addr
;
331 int sockfd
; /*!< Socket to use for transmission */
336 /* Dynamic Registration fields */
337 struct sockaddr_in defaddr
; /*!< Default address if there is one */
338 int authmethods
; /*!< Authentication methods (IAX_AUTH_*) */
339 int encmethods
; /*!< Encryption methods (IAX_ENCRYPT_*) */
341 int expire
; /*!< Schedule entry for expiry */
342 int expiry
; /*!< How soon to expire */
343 int capability
; /*!< Capability */
346 int callno
; /*!< Call number of POKE request */
347 int pokeexpire
; /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
348 int lastms
; /*!< How long last response took (in ms), or -1 for no response */
349 int maxms
; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
351 int pokefreqok
; /*!< How often to check if the host is up */
352 int pokefreqnotok
; /*!< How often to check when the host has been determined to be down */
353 int historicms
; /*!< How long recent average responses took */
354 int smoothing
; /*!< Sample over how many units to determine historic ms */
357 AST_LIST_ENTRY(iax2_peer
) entry
;
360 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
362 static struct iax2_trunk_peer
{
365 struct sockaddr_in addr
;
366 struct timeval txtrunktime
; /*!< Transmit trunktime */
367 struct timeval rxtrunktime
; /*!< Receive trunktime */
368 struct timeval lasttxtime
; /*!< Last transmitted trunktime */
369 struct timeval trunkact
; /*!< Last trunk activity */
370 unsigned int lastsent
; /*!< Last sent time */
371 /* Trunk data and length */
372 unsigned char *trunkdata
;
373 unsigned int trunkdatalen
;
374 unsigned int trunkdataalloc
;
375 struct iax2_trunk_peer
*next
;
380 AST_MUTEX_DEFINE_STATIC(tpeerlock
);
382 struct iax_firmware
{
383 struct iax_firmware
*next
;
387 struct ast_iax2_firmware_header
*fwh
;
392 REG_STATE_UNREGISTERED
= 0,
395 REG_STATE_REGISTERED
,
401 enum iax_transfer_state
{
406 TRANSFER_PASSTHROUGH
,
410 TRANSFER_MPASSTHROUGH
,
415 struct iax2_registry
{
416 struct sockaddr_in addr
; /*!< Who we connect to for registration purposes */
418 char secret
[80]; /*!< Password or key name in []'s */
420 int expire
; /*!< Sched ID of expiration */
421 int refresh
; /*!< How often to refresh */
422 enum iax_reg_state regstate
;
423 int messages
; /*!< Message count, low 8 bits = new, high 8 bits = old */
424 int callno
; /*!< Associated call number if applicable */
425 struct sockaddr_in us
; /*!< Who the server thinks we are */
426 struct ast_dnsmgr_entry
*dnsmgr
; /*!< DNS refresh manager */
427 AST_LIST_ENTRY(iax2_registry
) entry
;
430 static AST_LIST_HEAD_STATIC(registrations
, iax2_registry
);
432 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
433 #define MIN_RETRY_TIME 100
434 #define MAX_RETRY_TIME 10000
436 #define MAX_JITTER_BUFFER 50
437 #define MIN_JITTER_BUFFER 10
439 #define DEFAULT_TRUNKDATA 640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
440 #define MAX_TRUNKDATA 640 * 200 /*!< 40ms, uncompressed linear * 200 channels */
442 #define MAX_TIMESTAMP_SKEW 160 /*!< maximum difference between actual and predicted ts for sending */
444 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
445 #define TS_GAP_FOR_JB_RESYNC 5000
447 static int iaxthreadcount
= DEFAULT_THREAD_COUNT
;
448 static int iaxmaxthreadcount
= DEFAULT_MAX_THREAD_COUNT
;
449 static int iaxdynamicthreadcount
= 0;
450 static int iaxactivethreadcount
= 0;
462 struct chan_iax2_pvt
{
463 /*! Socket to send/receive on for this call */
465 /*! Last received voice format */
467 /*! Last received video format */
469 /*! Last sent voice format */
471 /*! Last sent video format */
473 /*! What we are capable of sending */
475 /*! Last received timestamp */
477 /*! Last sent timestamp - never send the same timestamp twice in a single call */
478 unsigned int lastsent
;
479 /*! Next outgoing timestamp if everything is good */
480 unsigned int nextpred
;
481 /*! True if the last voice we transmitted was not silence/CNG */
484 unsigned int pingtime
;
485 /*! Max time for initial response */
488 struct sockaddr_in addr
;
489 /*! Actual used codec preferences */
490 struct ast_codec_pref prefs
;
491 /*! Requested codec preferences */
492 struct ast_codec_pref rprefs
;
493 /*! Our call number */
494 unsigned short callno
;
496 unsigned short peercallno
;
497 /*! Peer selected format */
499 /*! Peer capability */
501 /*! timeval that we base our transmission on */
502 struct timeval offset
;
503 /*! timeval that we base our delivery on */
504 struct timeval rxcore
;
505 /*! The jitterbuffer */
507 /*! active jb read scheduler id */
511 /*! Error, as discovered by the manager */
513 /*! Owner if we have one */
514 struct ast_channel
*owner
;
515 /*! What's our state? */
516 struct ast_flags state
;
517 /*! Expiry (optional) */
519 /*! Next outgoing sequence number */
520 unsigned char oseqno
;
521 /*! Next sequence number they have not yet acknowledged */
522 unsigned char rseqno
;
523 /*! Next incoming sequence number */
524 unsigned char iseqno
;
525 /*! Last incoming sequence number we have acknowledged */
526 unsigned char aseqno
;
528 AST_DECLARE_STRING_FIELDS(
530 AST_STRING_FIELD(peer
);
531 /*! Default Context */
532 AST_STRING_FIELD(context
);
533 /*! Caller ID if available */
534 AST_STRING_FIELD(cid_num
);
535 AST_STRING_FIELD(cid_name
);
536 /*! Hidden Caller ID (i.e. ANI) if appropriate */
537 AST_STRING_FIELD(ani
);
539 AST_STRING_FIELD(dnid
);
541 AST_STRING_FIELD(rdnis
);
542 /*! Requested Extension */
543 AST_STRING_FIELD(exten
);
544 /*! Expected Username */
545 AST_STRING_FIELD(username
);
546 /*! Expected Secret */
547 AST_STRING_FIELD(secret
);
549 AST_STRING_FIELD(challenge
);
550 /*! Public keys permitted keys for incoming authentication */
551 AST_STRING_FIELD(inkeys
);
552 /*! Private key for outgoing authentication */
553 AST_STRING_FIELD(outkey
);
554 /*! Preferred language */
555 AST_STRING_FIELD(language
);
556 /*! Hostname/peername for naming purposes */
557 AST_STRING_FIELD(host
);
559 AST_STRING_FIELD(dproot
);
560 AST_STRING_FIELD(accountcode
);
561 AST_STRING_FIELD(mohinterpret
);
562 AST_STRING_FIELD(mohsuggest
);
565 /*! permitted authentication methods */
567 /*! permitted encryption methods */
569 /*! Encryption AES-128 Key */
571 /*! Decryption AES-128 Key */
573 /*! 32 bytes of semi-random data */
574 unsigned char semirand
[32];
575 /*! Associated registry */
576 struct iax2_registry
*reg
;
577 /*! Associated peer for poking */
578 struct iax2_peer
*peerpoke
;
583 /*! Transferring status */
584 enum iax_transfer_state transferring
;
585 /*! Transfer identifier */
587 /*! Who we are IAX transfering to */
588 struct sockaddr_in transfer
;
589 /*! What's the new call number for the transfer */
590 unsigned short transfercallno
;
591 /*! Transfer decrypt AES-128 Key */
592 aes_encrypt_ctx tdcx
;
594 /*! Status of knowledge of peer ADSI capability */
597 /*! Who we are bridged to */
598 unsigned short bridgecallno
;
600 int pingid
; /*!< Transmit PING request */
601 int lagid
; /*!< Retransmit lag request */
602 int autoid
; /*!< Auto hangup for Dialplan requestor */
603 int authid
; /*!< Authentication rejection ID */
604 int authfail
; /*!< Reason to report failure */
605 int initid
; /*!< Initial peer auto-congest ID (based on qualified peers) */
610 struct iax2_dpcache
*dpentries
;
611 struct ast_variable
*vars
;
612 /*! last received remote rr */
613 struct iax_rr remote_rr
;
614 /*! Current base time: (just for stats) */
616 /*! Dropped frame count: (just for stats) */
618 /*! received frame count: (just for stats) */
622 static struct ast_iax2_queue
{
623 AST_LIST_HEAD(, iax_frame
) queue
;
627 static AST_LIST_HEAD_STATIC(users
, iax2_user
);
629 static AST_LIST_HEAD_STATIC(peers
, iax2_peer
);
631 static struct ast_firmware_list
{
632 struct iax_firmware
*wares
;
636 /*! Extension exists */
637 #define CACHE_FLAG_EXISTS (1 << 0)
638 /*! Extension is nonexistent */
639 #define CACHE_FLAG_NONEXISTENT (1 << 1)
640 /*! Extension can exist */
641 #define CACHE_FLAG_CANEXIST (1 << 2)
642 /*! Waiting to hear back response */
643 #define CACHE_FLAG_PENDING (1 << 3)
645 #define CACHE_FLAG_TIMEOUT (1 << 4)
646 /*! Request transmitted */
647 #define CACHE_FLAG_TRANSMITTED (1 << 5)
649 #define CACHE_FLAG_UNKNOWN (1 << 6)
651 #define CACHE_FLAG_MATCHMORE (1 << 7)
653 static struct iax2_dpcache
{
654 char peercontext
[AST_MAX_CONTEXT
];
655 char exten
[AST_MAX_EXTENSION
];
657 struct timeval expiry
;
659 unsigned short callno
;
661 struct iax2_dpcache
*next
;
662 struct iax2_dpcache
*peer
; /*!< For linking in peers */
665 AST_MUTEX_DEFINE_STATIC(dpcache_lock
);
667 static void reg_source_db(struct iax2_peer
*p
);
668 static struct iax2_peer
*realtime_peer(const char *peername
, struct sockaddr_in
*sin
);
670 static void destroy_peer(struct iax2_peer
*peer
);
671 static int ast_cli_netstats(struct mansession
*s
, int fd
, int limit_fmt
);
673 #define IAX_IOSTATE_IDLE 0
674 #define IAX_IOSTATE_READY 1
675 #define IAX_IOSTATE_PROCESSING 2
676 #define IAX_IOSTATE_SCHEDREADY 3
678 #define IAX_TYPE_POOL 1
679 #define IAX_TYPE_DYNAMIC 2
682 AST_LIST_ENTRY(iax2_thread
) list
;
685 #ifdef SCHED_MULTITHREADED
686 void (*schedfunc
)(void *);
689 #ifdef DEBUG_SCHED_MULTITHREAD
695 struct sockaddr_in iosin
;
696 unsigned char buf
[4096];
705 static AST_LIST_HEAD_STATIC(idle_list
, iax2_thread
);
706 static AST_LIST_HEAD_STATIC(active_list
, iax2_thread
);
707 static AST_LIST_HEAD_STATIC(dynamic_list
, iax2_thread
);
709 static void *iax2_process_thread(void *data
);
711 static void signal_condition(ast_mutex_t
*lock
, ast_cond_t
*cond
)
713 ast_mutex_lock(lock
);
714 ast_cond_signal(cond
);
715 ast_mutex_unlock(lock
);
718 static void iax_debug_output(const char *data
)
721 ast_verbose("%s", data
);
724 static void iax_error_output(const char *data
)
726 ast_log(LOG_WARNING
, "%s", data
);
729 static void jb_error_output(const char *fmt
, ...)
735 vsnprintf(buf
, 1024, fmt
, args
);
738 ast_log(LOG_ERROR
, buf
);
741 static void jb_warning_output(const char *fmt
, ...)
747 vsnprintf(buf
, 1024, fmt
, args
);
750 ast_log(LOG_WARNING
, buf
);
753 static void jb_debug_output(const char *fmt
, ...)
759 vsnprintf(buf
, 1024, fmt
, args
);
765 /* XXX We probably should use a mutex when working with this XXX */
766 static struct chan_iax2_pvt
*iaxs
[IAX_MAX_CALLS
];
767 static ast_mutex_t iaxsl
[IAX_MAX_CALLS
];
768 static struct timeval lastused
[IAX_MAX_CALLS
];
770 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
);
771 static int expire_registry(void *data
);
772 static int iax2_answer(struct ast_channel
*c
);
773 static int iax2_call(struct ast_channel
*c
, char *dest
, int timeout
);
774 static int iax2_devicestate(void *data
);
775 static int iax2_digit_begin(struct ast_channel
*c
, char digit
);
776 static int iax2_digit_end(struct ast_channel
*c
, char digit
, unsigned int duration
);
777 static int iax2_do_register(struct iax2_registry
*reg
);
778 static int iax2_fixup(struct ast_channel
*oldchannel
, struct ast_channel
*newchan
);
779 static int iax2_hangup(struct ast_channel
*c
);
780 static int iax2_indicate(struct ast_channel
*c
, int condition
, const void *data
, size_t datalen
);
781 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
);
782 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
);
783 static int iax2_send(struct chan_iax2_pvt
*pvt
, struct ast_frame
*f
, unsigned int ts
, int seqno
, int now
, int transfer
, int final
);
784 static int iax2_sendhtml(struct ast_channel
*c
, int subclass
, const char *data
, int datalen
);
785 static int iax2_sendimage(struct ast_channel
*c
, struct ast_frame
*img
);
786 static int iax2_sendtext(struct ast_channel
*c
, const char *text
);
787 static int iax2_setoption(struct ast_channel
*c
, int option
, void *data
, int datalen
);
788 static int iax2_transfer(struct ast_channel
*c
, const char *dest
);
789 static int iax2_write(struct ast_channel
*c
, struct ast_frame
*f
);
790 static int send_command(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int, int);
791 static int send_command_final(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int, int);
792 static int send_command_immediate(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int, int);
793 static int send_command_locked(unsigned short callno
, char, int, unsigned int, const unsigned char *, int, int);
794 static int send_command_transfer(struct chan_iax2_pvt
*, char, int, unsigned int, const unsigned char *, int);
795 static struct ast_channel
*iax2_request(const char *type
, int format
, void *data
, int *cause
);
796 static struct ast_frame
*iax2_read(struct ast_channel
*c
);
797 static struct iax2_peer
*build_peer(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
);
798 static struct iax2_user
*build_user(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
);
799 static void realtime_update_peer(const char *peername
, struct sockaddr_in
*sin
, time_t regtime
);
800 static void destroy_user(struct iax2_user
*user
);
801 static void prune_peers(void);
803 static const struct ast_channel_tech iax2_tech
= {
805 .description
= tdesc
,
806 .capabilities
= IAX_CAPABILITY_FULLBANDWIDTH
,
807 .properties
= AST_CHAN_TP_WANTSJITTER
,
808 .requester
= iax2_request
,
809 .devicestate
= iax2_devicestate
,
810 .send_digit_begin
= iax2_digit_begin
,
811 .send_digit_end
= iax2_digit_end
,
812 .send_text
= iax2_sendtext
,
813 .send_image
= iax2_sendimage
,
814 .send_html
= iax2_sendhtml
,
816 .hangup
= iax2_hangup
,
817 .answer
= iax2_answer
,
820 .write_video
= iax2_write
,
821 .indicate
= iax2_indicate
,
822 .setoption
= iax2_setoption
,
823 .bridge
= iax2_bridge
,
824 .transfer
= iax2_transfer
,
828 static void insert_idle_thread(struct iax2_thread
*thread
)
830 if (thread
->type
== IAX_TYPE_DYNAMIC
) {
831 AST_LIST_LOCK(&dynamic_list
);
832 AST_LIST_INSERT_TAIL(&dynamic_list
, thread
, list
);
833 AST_LIST_UNLOCK(&dynamic_list
);
835 AST_LIST_LOCK(&idle_list
);
836 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
837 AST_LIST_UNLOCK(&idle_list
);
843 static struct iax2_thread
*find_idle_thread(void)
846 struct iax2_thread
*thread
= NULL
;
848 /* Pop the head of the list off */
849 AST_LIST_LOCK(&idle_list
);
850 thread
= AST_LIST_REMOVE_HEAD(&idle_list
, list
);
851 AST_LIST_UNLOCK(&idle_list
);
853 /* If no idle thread is available from the regular list, try dynamic */
854 if (thread
== NULL
) {
855 AST_LIST_LOCK(&dynamic_list
);
856 thread
= AST_LIST_REMOVE_HEAD(&dynamic_list
, list
);
857 /* Make sure we absolutely have a thread... if not, try to make one if allowed */
858 if (thread
== NULL
&& iaxmaxthreadcount
> iaxdynamicthreadcount
) {
859 /* We need to MAKE a thread! */
860 if ((thread
= ast_calloc(1, sizeof(*thread
)))) {
861 thread
->threadnum
= iaxdynamicthreadcount
;
862 thread
->type
= IAX_TYPE_DYNAMIC
;
863 ast_mutex_init(&thread
->lock
);
864 ast_cond_init(&thread
->cond
, NULL
);
865 pthread_attr_init(&attr
);
866 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
867 if (ast_pthread_create(&thread
->threadid
, &attr
, iax2_process_thread
, thread
)) {
871 /* All went well and the thread is up, so increment our count */
872 iaxdynamicthreadcount
++;
876 AST_LIST_UNLOCK(&dynamic_list
);
882 #ifdef SCHED_MULTITHREADED
883 static int __schedule_action(void (*func
)(void *data
), void *data
, const char *funcname
)
885 struct iax2_thread
*thread
= NULL
;
886 static time_t lasterror
;
889 thread
= find_idle_thread();
891 if (thread
!= NULL
) {
892 thread
->schedfunc
= func
;
893 thread
->scheddata
= data
;
894 thread
->iostate
= IAX_IOSTATE_SCHEDREADY
;
895 #ifdef DEBUG_SCHED_MULTITHREAD
896 ast_copy_string(thread
->curfunc
, funcname
, sizeof(thread
->curfunc
));
898 signal_condition(&thread
->lock
, &thread
->cond
);
903 ast_log(LOG_NOTICE
, "Out of idle IAX2 threads for scheduling!\n");
908 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
911 static int send_ping(void *data
);
913 static void __send_ping(void *data
)
915 int callno
= (long)data
;
916 ast_mutex_lock(&iaxsl
[callno
]);
917 if (iaxs
[callno
] && iaxs
[callno
]->pingid
!= -1) {
918 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_PING
, 0, NULL
, 0, -1);
919 iaxs
[callno
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, data
);
921 ast_mutex_unlock(&iaxsl
[callno
]);
924 static int send_ping(void *data
)
926 #ifdef SCHED_MULTITHREADED
927 if (schedule_action(__send_ping
, data
))
933 static int get_encrypt_methods(const char *s
)
936 if (!strcasecmp(s
, "aes128"))
937 e
= IAX_ENCRYPT_AES128
;
938 else if (ast_true(s
))
939 e
= IAX_ENCRYPT_AES128
;
945 static int send_lagrq(void *data
);
947 static void __send_lagrq(void *data
)
949 int callno
= (long)data
;
950 /* Ping only if it's real not if it's bridged */
951 ast_mutex_lock(&iaxsl
[callno
]);
952 if (iaxs
[callno
] && iaxs
[callno
]->lagid
!= -1) {
953 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_LAGRQ
, 0, NULL
, 0, -1);
954 iaxs
[callno
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, data
);
956 ast_mutex_unlock(&iaxsl
[callno
]);
959 static int send_lagrq(void *data
)
961 #ifdef SCHED_MULTITHREADED
962 if (schedule_action(__send_lagrq
, data
))
968 static unsigned char compress_subclass(int subclass
)
972 /* If it's 128 or smaller, just return it */
973 if (subclass
< IAX_FLAG_SC_LOG
)
975 /* Otherwise find its power */
976 for (x
= 0; x
< IAX_MAX_SHIFT
; x
++) {
977 if (subclass
& (1 << x
)) {
979 ast_log(LOG_WARNING
, "Can't compress subclass %d\n", subclass
);
985 return power
| IAX_FLAG_SC_LOG
;
988 static int uncompress_subclass(unsigned char csub
)
990 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
991 if (csub
& IAX_FLAG_SC_LOG
) {
992 /* special case for 'compressed' -1 */
996 return 1 << (csub
& ~IAX_FLAG_SC_LOG
& IAX_MAX_SHIFT
);
1002 static struct iax2_peer
*find_peer(const char *name
, int realtime
)
1004 struct iax2_peer
*peer
= NULL
;
1006 /* Grab peer from linked list */
1007 AST_LIST_LOCK(&peers
);
1008 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
1009 if (!strcasecmp(peer
->name
, name
)) {
1013 AST_LIST_UNLOCK(&peers
);
1015 /* Now go for realtime if applicable */
1016 if(!peer
&& realtime
)
1017 peer
= realtime_peer(name
, NULL
);
1021 static int iax2_getpeername(struct sockaddr_in sin
, char *host
, int len
, int lockpeer
)
1023 struct iax2_peer
*peer
= NULL
;
1027 AST_LIST_LOCK(&peers
);
1028 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
1029 if ((peer
->addr
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
) &&
1030 (peer
->addr
.sin_port
== sin
.sin_port
)) {
1031 ast_copy_string(host
, peer
->name
, len
);
1037 AST_LIST_UNLOCK(&peers
);
1039 peer
= realtime_peer(NULL
, &sin
);
1041 ast_copy_string(host
, peer
->name
, len
);
1042 if (ast_test_flag(peer
, IAX_TEMPONLY
))
1051 static struct chan_iax2_pvt
*new_iax(struct sockaddr_in
*sin
, int lockpeer
, const char *host
)
1053 struct chan_iax2_pvt
*tmp
;
1056 if (!(tmp
= ast_calloc(1, sizeof(*tmp
))))
1059 if (ast_string_field_init(tmp
, 32)) {
1067 tmp
->peercallno
= 0;
1068 tmp
->transfercallno
= 0;
1069 tmp
->bridgecallno
= 0;
1076 ast_string_field_set(tmp
,exten
, "s");
1077 ast_string_field_set(tmp
,host
, host
);
1081 jbconf
.max_jitterbuf
= maxjitterbuffer
;
1082 jbconf
.resync_threshold
= resyncthreshold
;
1083 jbconf
.max_contig_interp
= maxjitterinterps
;
1084 jb_setconf(tmp
->jb
,&jbconf
);
1089 static struct iax_frame
*iaxfrdup2(struct iax_frame
*fr
)
1091 struct iax_frame
*new = iax_frame_new(DIRECTION_INGRESS
, fr
->af
.datalen
, fr
->cacheable
);
1093 size_t mallocd_datalen
= new->mallocd_datalen
;
1094 memcpy(new, fr
, sizeof(*new));
1095 iax_frame_wrap(new, &fr
->af
);
1096 new->mallocd_datalen
= mallocd_datalen
;
1099 new->direction
= DIRECTION_INGRESS
;
1105 #define NEW_PREVENT 0
1109 static int match(struct sockaddr_in
*sin
, unsigned short callno
, unsigned short dcallno
, struct chan_iax2_pvt
*cur
)
1111 if ((cur
->addr
.sin_addr
.s_addr
== sin
->sin_addr
.s_addr
) &&
1112 (cur
->addr
.sin_port
== sin
->sin_port
)) {
1113 /* This is the main host */
1114 if ((cur
->peercallno
== callno
) ||
1115 ((dcallno
== cur
->callno
) && !cur
->peercallno
)) {
1116 /* That's us. Be sure we keep track of the peer call number */
1120 if ((cur
->transfer
.sin_addr
.s_addr
== sin
->sin_addr
.s_addr
) &&
1121 (cur
->transfer
.sin_port
== sin
->sin_port
) && (cur
->transferring
)) {
1122 /* We're transferring */
1123 if (dcallno
== cur
->callno
)
1129 static void update_max_trunk(void)
1131 int max
= TRUNK_CALL_START
;
1133 /* XXX Prolly don't need locks here XXX */
1134 for (x
=TRUNK_CALL_START
;x
<IAX_MAX_CALLS
- 1; x
++) {
1139 if (option_debug
&& iaxdebug
)
1140 ast_log(LOG_DEBUG
, "New max trunk callno is %d\n", max
);
1143 static void update_max_nontrunk(void)
1147 /* XXX Prolly don't need locks here XXX */
1148 for (x
=1;x
<TRUNK_CALL_START
- 1; x
++) {
1152 maxnontrunkcall
= max
;
1153 if (option_debug
&& iaxdebug
)
1154 ast_log(LOG_DEBUG
, "New max nontrunk callno is %d\n", max
);
1157 static int make_trunk(unsigned short callno
, int locked
)
1162 if (iaxs
[callno
]->oseqno
) {
1163 ast_log(LOG_WARNING
, "Can't make trunk once a call has started!\n");
1166 if (callno
& TRUNK_CALL_START
) {
1167 ast_log(LOG_WARNING
, "Call %d is already a trunk\n", callno
);
1170 gettimeofday(&now
, NULL
);
1171 for (x
=TRUNK_CALL_START
;x
<IAX_MAX_CALLS
- 1; x
++) {
1172 ast_mutex_lock(&iaxsl
[x
]);
1173 if (!iaxs
[x
] && ((now
.tv_sec
- lastused
[x
].tv_sec
) > MIN_REUSE_TIME
)) {
1174 iaxs
[x
] = iaxs
[callno
];
1175 iaxs
[x
]->callno
= x
;
1176 iaxs
[callno
] = NULL
;
1177 /* Update the two timers that should have been started */
1178 if (iaxs
[x
]->pingid
> -1)
1179 ast_sched_del(sched
, iaxs
[x
]->pingid
);
1180 if (iaxs
[x
]->lagid
> -1)
1181 ast_sched_del(sched
, iaxs
[x
]->lagid
);
1182 iaxs
[x
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, (void *)(long)x
);
1183 iaxs
[x
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, (void *)(long)x
);
1185 ast_mutex_unlock(&iaxsl
[callno
]);
1188 ast_mutex_unlock(&iaxsl
[x
]);
1191 ast_mutex_unlock(&iaxsl
[x
]);
1193 if (x
>= IAX_MAX_CALLS
- 1) {
1194 ast_log(LOG_WARNING
, "Unable to trunk call: Insufficient space\n");
1197 ast_log(LOG_DEBUG
, "Made call %d into trunk call %d\n", callno
, x
);
1198 /* We move this call from a non-trunked to a trunked call */
1200 update_max_nontrunk();
1204 static int find_callno(unsigned short callno
, unsigned short dcallno
, struct sockaddr_in
*sin
, int new, int lockpeer
, int sockfd
)
1210 if (new <= NEW_ALLOW
) {
1211 /* Look for an existing connection first */
1212 for (x
=1;(res
< 1) && (x
<maxnontrunkcall
);x
++) {
1213 ast_mutex_lock(&iaxsl
[x
]);
1215 /* Look for an exact match */
1216 if (match(sin
, callno
, dcallno
, iaxs
[x
])) {
1220 ast_mutex_unlock(&iaxsl
[x
]);
1222 for (x
=TRUNK_CALL_START
;(res
< 1) && (x
<maxtrunkcall
);x
++) {
1223 ast_mutex_lock(&iaxsl
[x
]);
1225 /* Look for an exact match */
1226 if (match(sin
, callno
, dcallno
, iaxs
[x
])) {
1230 ast_mutex_unlock(&iaxsl
[x
]);
1233 if ((res
< 1) && (new >= NEW_ALLOW
)) {
1234 /* It may seem odd that we look through the peer list for a name for
1235 * this *incoming* call. Well, it is weird. However, users don't
1236 * have an IP address/port number that we can match against. So,
1237 * this is just checking for a peer that has that IP/port and
1238 * assuming that we have a user of the same name. This isn't always
1239 * correct, but it will be changed if needed after authentication. */
1240 if (!iax2_getpeername(*sin
, host
, sizeof(host
), lockpeer
))
1241 snprintf(host
, sizeof(host
), "%s:%d", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
1242 gettimeofday(&now
, NULL
);
1243 for (x
=1;x
<TRUNK_CALL_START
;x
++) {
1244 /* Find first unused call number that hasn't been used in a while */
1245 ast_mutex_lock(&iaxsl
[x
]);
1246 if (!iaxs
[x
] && ((now
.tv_sec
- lastused
[x
].tv_sec
) > MIN_REUSE_TIME
)) break;
1247 ast_mutex_unlock(&iaxsl
[x
]);
1249 /* We've still got lock held if we found a spot */
1250 if (x
>= TRUNK_CALL_START
) {
1251 ast_log(LOG_WARNING
, "No more space\n");
1254 iaxs
[x
] = new_iax(sin
, lockpeer
, host
);
1255 update_max_nontrunk();
1257 if (option_debug
&& iaxdebug
)
1258 ast_log(LOG_DEBUG
, "Creating new call structure %d\n", x
);
1259 iaxs
[x
]->sockfd
= sockfd
;
1260 iaxs
[x
]->addr
.sin_port
= sin
->sin_port
;
1261 iaxs
[x
]->addr
.sin_family
= sin
->sin_family
;
1262 iaxs
[x
]->addr
.sin_addr
.s_addr
= sin
->sin_addr
.s_addr
;
1263 iaxs
[x
]->peercallno
= callno
;
1264 iaxs
[x
]->callno
= x
;
1265 iaxs
[x
]->pingtime
= DEFAULT_RETRY_TIME
;
1266 iaxs
[x
]->expiry
= min_reg_expire
;
1267 iaxs
[x
]->pingid
= ast_sched_add(sched
, ping_time
* 1000, send_ping
, (void *)(long)x
);
1268 iaxs
[x
]->lagid
= ast_sched_add(sched
, lagrq_time
* 1000, send_lagrq
, (void *)(long)x
);
1269 iaxs
[x
]->amaflags
= amaflags
;
1270 ast_copy_flags(iaxs
[x
], (&globalflags
), IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
1272 ast_string_field_set(iaxs
[x
], accountcode
, accountcode
);
1273 ast_string_field_set(iaxs
[x
], mohinterpret
, mohinterpret
);
1274 ast_string_field_set(iaxs
[x
], mohsuggest
, mohsuggest
);
1276 ast_log(LOG_WARNING
, "Out of resources\n");
1277 ast_mutex_unlock(&iaxsl
[x
]);
1280 ast_mutex_unlock(&iaxsl
[x
]);
1286 static void iax2_frame_free(struct iax_frame
*fr
)
1288 if (fr
->retrans
> -1)
1289 ast_sched_del(sched
, fr
->retrans
);
1293 static int iax2_queue_frame(int callno
, struct ast_frame
*f
)
1295 /* Assumes lock for callno is already held... */
1297 if (iaxs
[callno
] && iaxs
[callno
]->owner
) {
1298 if (ast_mutex_trylock(&iaxs
[callno
]->owner
->lock
)) {
1299 /* Avoid deadlock by pausing and trying again */
1300 ast_mutex_unlock(&iaxsl
[callno
]);
1302 ast_mutex_lock(&iaxsl
[callno
]);
1304 ast_queue_frame(iaxs
[callno
]->owner
, f
);
1305 ast_mutex_unlock(&iaxs
[callno
]->owner
->lock
);
1314 static void destroy_firmware(struct iax_firmware
*cur
)
1316 /* Close firmware */
1318 munmap(cur
->fwh
, ntohl(cur
->fwh
->datalen
) + sizeof(*(cur
->fwh
)));
1324 static int try_firmware(char *s
)
1327 struct iax_firmware
*cur
;
1332 struct ast_iax2_firmware_header
*fwh
, fwh2
;
1333 struct MD5Context md5
;
1334 unsigned char sum
[16];
1335 unsigned char buf
[1024];
1339 s2
= alloca(strlen(s
) + 100);
1341 ast_log(LOG_WARNING
, "Alloca failed!\n");
1344 last
= strrchr(s
, '/');
1349 snprintf(s2
, strlen(s
) + 100, "/var/tmp/%s-%ld", last
, (unsigned long)ast_random());
1350 res
= stat(s
, &stbuf
);
1352 ast_log(LOG_WARNING
, "Failed to stat '%s': %s\n", s
, strerror(errno
));
1355 /* Make sure it's not a directory */
1356 if (S_ISDIR(stbuf
.st_mode
))
1358 ifd
= open(s
, O_RDONLY
);
1360 ast_log(LOG_WARNING
, "Cannot open '%s': %s\n", s
, strerror(errno
));
1363 fd
= open(s2
, O_RDWR
| O_CREAT
| O_EXCL
);
1365 ast_log(LOG_WARNING
, "Cannot open '%s' for writing: %s\n", s2
, strerror(errno
));
1369 /* Unlink our newly created file */
1372 /* Now copy the firmware into it */
1373 len
= stbuf
.st_size
;
1376 if (chunk
> sizeof(buf
))
1377 chunk
= sizeof(buf
);
1378 res
= read(ifd
, buf
, chunk
);
1380 ast_log(LOG_WARNING
, "Only read %d of %d bytes of data :(: %s\n", res
, chunk
, strerror(errno
));
1385 res
= write(fd
, buf
, chunk
);
1387 ast_log(LOG_WARNING
, "Only write %d of %d bytes of data :(: %s\n", res
, chunk
, strerror(errno
));
1395 /* Return to the beginning */
1396 lseek(fd
, 0, SEEK_SET
);
1397 if ((res
= read(fd
, &fwh2
, sizeof(fwh2
))) != sizeof(fwh2
)) {
1398 ast_log(LOG_WARNING
, "Unable to read firmware header in '%s'\n", s
);
1402 if (ntohl(fwh2
.magic
) != IAX_FIRMWARE_MAGIC
) {
1403 ast_log(LOG_WARNING
, "'%s' is not a valid firmware file\n", s
);
1407 if (ntohl(fwh2
.datalen
) != (stbuf
.st_size
- sizeof(fwh2
))) {
1408 ast_log(LOG_WARNING
, "Invalid data length in firmware '%s'\n", s
);
1412 if (fwh2
.devname
[sizeof(fwh2
.devname
) - 1] || ast_strlen_zero((char *)fwh2
.devname
)) {
1413 ast_log(LOG_WARNING
, "No or invalid device type specified for '%s'\n", s
);
1417 fwh
= mmap(NULL
, stbuf
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
1418 if (fwh
== (void *) -1) {
1419 ast_log(LOG_WARNING
, "mmap failed: %s\n", strerror(errno
));
1424 MD5Update(&md5
, fwh
->data
, ntohl(fwh
->datalen
));
1425 MD5Final(sum
, &md5
);
1426 if (memcmp(sum
, fwh
->chksum
, sizeof(sum
))) {
1427 ast_log(LOG_WARNING
, "Firmware file '%s' fails checksum\n", s
);
1428 munmap(fwh
, stbuf
.st_size
);
1434 if (!strcmp((char *)cur
->fwh
->devname
, (char *)fwh
->devname
)) {
1435 /* Found a candidate */
1436 if (cur
->dead
|| (ntohs(cur
->fwh
->version
) < ntohs(fwh
->version
)))
1437 /* The version we have on loaded is older, load this one instead */
1439 /* This version is no newer than what we have. Don't worry about it.
1440 We'll consider it a proper load anyhow though */
1441 munmap(fwh
, stbuf
.st_size
);
1448 /* Allocate a new one and link it */
1449 if ((cur
= ast_calloc(1, sizeof(*cur
)))) {
1451 cur
->next
= waresl
.wares
;
1457 munmap(cur
->fwh
, cur
->mmaplen
);
1463 cur
->mmaplen
= stbuf
.st_size
;
1469 static int iax_check_version(char *dev
)
1472 struct iax_firmware
*cur
;
1473 if (!ast_strlen_zero(dev
)) {
1474 ast_mutex_lock(&waresl
.lock
);
1477 if (!strcmp(dev
, (char *)cur
->fwh
->devname
)) {
1478 res
= ntohs(cur
->fwh
->version
);
1483 ast_mutex_unlock(&waresl
.lock
);
1488 static int iax_firmware_append(struct iax_ie_data
*ied
, const unsigned char *dev
, unsigned int desc
)
1491 unsigned int bs
= desc
& 0xff;
1492 unsigned int start
= (desc
>> 8) & 0xffffff;
1494 struct iax_firmware
*cur
;
1495 if (!ast_strlen_zero((char *)dev
) && bs
) {
1497 ast_mutex_lock(&waresl
.lock
);
1500 if (!strcmp((char *)dev
, (char *)cur
->fwh
->devname
)) {
1501 iax_ie_append_int(ied
, IAX_IE_FWBLOCKDESC
, desc
);
1502 if (start
< ntohl(cur
->fwh
->datalen
)) {
1503 bytes
= ntohl(cur
->fwh
->datalen
) - start
;
1506 iax_ie_append_raw(ied
, IAX_IE_FWBLOCKDATA
, cur
->fwh
->data
+ start
, bytes
);
1509 iax_ie_append(ied
, IAX_IE_FWBLOCKDATA
);
1519 ast_mutex_unlock(&waresl
.lock
);
1525 static void reload_firmware(void)
1527 struct iax_firmware
*cur
, *curl
, *curp
;
1532 /* Mark all as dead */
1533 ast_mutex_lock(&waresl
.lock
);
1539 /* Now that we've freed them, load the new ones */
1540 snprintf(dir
, sizeof(dir
), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR
);
1543 while((de
= readdir(fwd
))) {
1544 if (de
->d_name
[0] != '.') {
1545 snprintf(fn
, sizeof(fn
), "%s/%s", dir
, de
->d_name
);
1546 if (!try_firmware(fn
)) {
1547 if (option_verbose
> 1)
1548 ast_verbose(VERBOSE_PREFIX_2
"Loaded firmware '%s'\n", de
->d_name
);
1554 ast_log(LOG_WARNING
, "Error opening firmware directory '%s': %s\n", dir
, strerror(errno
));
1556 /* Clean up leftovers */
1568 destroy_firmware(curl
);
1573 ast_mutex_unlock(&waresl
.lock
);
1576 static int __do_deliver(void *data
)
1578 /* Just deliver the packet by using queueing. This is called by
1579 the IAX thread with the iaxsl lock held. */
1580 struct iax_frame
*fr
= data
;
1582 fr
->af
.has_timing_info
= 0;
1583 if (iaxs
[fr
->callno
] && !ast_test_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
))
1584 iax2_queue_frame(fr
->callno
, &fr
->af
);
1585 /* Free our iax frame */
1586 iax2_frame_free(fr
);
1587 /* And don't run again */
1591 static int handle_error(void)
1593 /* XXX Ideally we should figure out why an error occured and then abort those
1594 rather than continuing to try. Unfortunately, the published interface does
1595 not seem to work XXX */
1597 struct sockaddr_in
*sin
;
1600 struct sock_extended_err e
;
1605 m
.msg_controllen
= sizeof(e
);
1607 res
= recvmsg(netsocket
, &m
, MSG_ERRQUEUE
);
1609 ast_log(LOG_WARNING
, "Error detected, but unable to read error: %s\n", strerror(errno
));
1611 if (m
.msg_controllen
) {
1612 sin
= (struct sockaddr_in
*)SO_EE_OFFENDER(&e
);
1614 ast_log(LOG_WARNING
, "Receive error from %s\n", ast_inet_ntoa(sin
->sin_addr
));
1616 ast_log(LOG_WARNING
, "No address detected??\n");
1618 ast_log(LOG_WARNING
, "Local error: %s\n", strerror(e
.ee_errno
));
1625 static int transmit_trunk(struct iax_frame
*f
, struct sockaddr_in
*sin
, int sockfd
)
1628 res
= sendto(sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)sin
,
1632 ast_log(LOG_DEBUG
, "Received error: %s\n", strerror(errno
));
1639 static int send_packet(struct iax_frame
*f
)
1642 int callno
= f
->callno
;
1644 /* Don't send if there was an error, but return error instead */
1645 if (!callno
|| !iaxs
[callno
] || iaxs
[callno
]->error
)
1648 /* Called with iaxsl held */
1649 if (option_debug
> 2 && iaxdebug
)
1650 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
));
1653 iax_showframe(f
, NULL
, 0, &iaxs
[callno
]->transfer
, f
->datalen
- sizeof(struct ast_iax2_full_hdr
));
1654 res
= sendto(iaxs
[callno
]->sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)&iaxs
[callno
]->transfer
,
1655 sizeof(iaxs
[callno
]->transfer
));
1658 iax_showframe(f
, NULL
, 0, &iaxs
[callno
]->addr
, f
->datalen
- sizeof(struct ast_iax2_full_hdr
));
1659 res
= sendto(iaxs
[callno
]->sockfd
, f
->data
, f
->datalen
, 0,(struct sockaddr
*)&iaxs
[callno
]->addr
,
1660 sizeof(iaxs
[callno
]->addr
));
1663 if (option_debug
&& iaxdebug
)
1664 ast_log(LOG_DEBUG
, "Received error: %s\n", strerror(errno
));
1671 static void iax2_destroy_helper(struct chan_iax2_pvt
*pvt
)
1673 struct iax2_user
*user
= NULL
;
1675 /* Decrement AUTHREQ count if needed */
1676 if (ast_test_flag(pvt
, IAX_MAXAUTHREQ
)) {
1677 AST_LIST_LOCK(&users
);
1678 AST_LIST_TRAVERSE(&users
, user
, entry
) {
1679 if (!strcmp(user
->name
, pvt
->username
)) {
1684 AST_LIST_UNLOCK(&users
);
1685 ast_clear_flag(pvt
, IAX_MAXAUTHREQ
);
1687 /* No more pings or lagrq's */
1688 if (pvt
->pingid
> -1)
1689 ast_sched_del(sched
, pvt
->pingid
);
1691 if (pvt
->lagid
> -1)
1692 ast_sched_del(sched
, pvt
->lagid
);
1694 if (pvt
->autoid
> -1)
1695 ast_sched_del(sched
, pvt
->autoid
);
1697 if (pvt
->authid
> -1)
1698 ast_sched_del(sched
, pvt
->authid
);
1700 if (pvt
->initid
> -1)
1701 ast_sched_del(sched
, pvt
->initid
);
1704 ast_sched_del(sched
, pvt
->jbid
);
1708 static int iax2_predestroy(int callno
)
1710 struct ast_channel
*c
;
1711 struct chan_iax2_pvt
*pvt
= iaxs
[callno
];
1715 if (!ast_test_flag(pvt
, IAX_ALREADYGONE
)) {
1716 iax2_destroy_helper(pvt
);
1717 ast_set_flag(pvt
, IAX_ALREADYGONE
);
1721 c
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1723 ast_queue_hangup(c
);
1725 ast_module_unref(ast_module_info
->self
);
1730 static void iax2_destroy(int callno
)
1732 struct chan_iax2_pvt
*pvt
;
1733 struct iax_frame
*cur
;
1734 struct ast_channel
*owner
;
1738 gettimeofday(&lastused
[callno
], NULL
);
1740 owner
= pvt
? pvt
->owner
: NULL
;
1743 if (ast_mutex_trylock(&owner
->lock
)) {
1744 ast_log(LOG_NOTICE
, "Avoiding IAX destroy deadlock\n");
1745 ast_mutex_unlock(&iaxsl
[callno
]);
1747 ast_mutex_lock(&iaxsl
[callno
]);
1752 iaxs
[callno
] = NULL
;
1756 iax2_destroy_helper(pvt
);
1759 ast_set_flag(pvt
, IAX_ALREADYGONE
);
1762 /* If there's an owner, prod it to give up */
1763 owner
->_softhangup
|= AST_SOFTHANGUP_DEV
;
1764 ast_queue_hangup(owner
);
1767 AST_LIST_LOCK(&iaxq
.queue
);
1768 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
1769 /* Cancel any pending transmissions */
1770 if (cur
->callno
== pvt
->callno
)
1773 AST_LIST_UNLOCK(&iaxq
.queue
);
1776 pvt
->reg
->callno
= 0;
1780 ast_variables_destroy(pvt
->vars
);
1784 while (jb_getall(pvt
->jb
, &frame
) == JB_OK
)
1785 iax2_frame_free(frame
.data
);
1786 jb_destroy(pvt
->jb
);
1787 /* gotta free up the stringfields */
1788 ast_string_field_free_pools(pvt
);
1793 ast_mutex_unlock(&owner
->lock
);
1795 if (callno
& 0x4000)
1799 static int update_packet(struct iax_frame
*f
)
1801 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
1802 struct ast_iax2_full_hdr
*fh
= f
->data
;
1803 /* Mark this as a retransmission */
1804 fh
->dcallno
= ntohs(IAX_FLAG_RETRANS
| f
->dcallno
);
1806 f
->iseqno
= iaxs
[f
->callno
]->iseqno
;
1807 fh
->iseqno
= f
->iseqno
;
1811 static int attempt_transmit(void *data
);
1812 static void __attempt_transmit(void *data
)
1814 /* Attempt to transmit the frame to the remote peer...
1815 Called without iaxsl held. */
1816 struct iax_frame
*f
= data
;
1818 int callno
= f
->callno
;
1819 /* Make sure this call is still active */
1821 ast_mutex_lock(&iaxsl
[callno
]);
1822 if (callno
&& iaxs
[callno
]) {
1823 if ((f
->retries
< 0) /* Already ACK'd */ ||
1824 (f
->retries
>= max_retries
) /* Too many attempts */) {
1825 /* Record an error if we've transmitted too many times */
1826 if (f
->retries
>= max_retries
) {
1828 /* Transfer timeout */
1829 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREJ
, 0, NULL
, 0, -1);
1830 } else if (f
->final
) {
1832 iax2_destroy(callno
);
1834 if (iaxs
[callno
]->owner
)
1835 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
);
1836 iaxs
[callno
]->error
= ETIMEDOUT
;
1837 if (iaxs
[callno
]->owner
) {
1838 struct ast_frame fr
= { 0, };
1840 fr
.frametype
= AST_FRAME_CONTROL
;
1841 fr
.subclass
= AST_CONTROL_HANGUP
;
1842 iax2_queue_frame(callno
, &fr
);
1843 /* Remember, owner could disappear */
1844 if (iaxs
[callno
]->owner
)
1845 iaxs
[callno
]->owner
->hangupcause
= AST_CAUSE_DESTINATION_OUT_OF_ORDER
;
1847 if (iaxs
[callno
]->reg
) {
1848 memset(&iaxs
[callno
]->reg
->us
, 0, sizeof(iaxs
[callno
]->reg
->us
));
1849 iaxs
[callno
]->reg
->regstate
= REG_STATE_TIMEOUT
;
1850 iaxs
[callno
]->reg
->refresh
= IAX_DEFAULT_REG_EXPIRE
;
1852 iax2_destroy(callno
);
1859 /* Update it if it needs it */
1861 /* Attempt transmission */
1864 /* Try again later after 10 times as long */
1866 if (f
->retrytime
> MAX_RETRY_TIME
)
1867 f
->retrytime
= MAX_RETRY_TIME
;
1868 /* Transfer messages max out at one second */
1869 if (f
->transfer
&& (f
->retrytime
> 1000))
1870 f
->retrytime
= 1000;
1871 f
->retrans
= ast_sched_add(sched
, f
->retrytime
, attempt_transmit
, f
);
1874 /* Make sure it gets freed */
1879 ast_mutex_unlock(&iaxsl
[callno
]);
1880 /* Do not try again */
1882 /* Don't attempt delivery, just remove it from the queue */
1883 AST_LIST_LOCK(&iaxq
.queue
);
1884 AST_LIST_REMOVE(&iaxq
.queue
, f
, list
);
1886 AST_LIST_UNLOCK(&iaxq
.queue
);
1888 /* Free the IAX frame */
1893 static int attempt_transmit(void *data
)
1895 #ifdef SCHED_MULTITHREADED
1896 if (schedule_action(__attempt_transmit
, data
))
1898 __attempt_transmit(data
);
1902 static int iax2_prune_realtime(int fd
, int argc
, char *argv
[])
1904 struct iax2_peer
*peer
;
1907 return RESULT_SHOWUSAGE
;
1908 if (!strcmp(argv
[3],"all")) {
1910 ast_cli(fd
, "OK cache is flushed.\n");
1911 } else if ((peer
= find_peer(argv
[3], 0))) {
1912 if(ast_test_flag(peer
, IAX_RTCACHEFRIENDS
)) {
1913 ast_set_flag(peer
, IAX_RTAUTOCLEAR
);
1914 expire_registry((void*)peer
->name
);
1915 ast_cli(fd
, "OK peer %s was removed from the cache.\n", argv
[3]);
1917 ast_cli(fd
, "SORRY peer %s is not eligible for this operation.\n", argv
[3]);
1920 ast_cli(fd
, "SORRY peer %s was not found in the cache.\n", argv
[3]);
1923 return RESULT_SUCCESS
;
1926 static int iax2_test_losspct(int fd
, int argc
, char *argv
[])
1929 return RESULT_SHOWUSAGE
;
1931 test_losspct
= atoi(argv
[3]);
1933 return RESULT_SUCCESS
;
1937 static int iax2_test_late(int fd
, int argc
, char *argv
[])
1940 return RESULT_SHOWUSAGE
;
1942 test_late
= atoi(argv
[3]);
1944 return RESULT_SUCCESS
;
1947 static int iax2_test_resync(int fd
, int argc
, char *argv
[])
1950 return RESULT_SHOWUSAGE
;
1952 test_resync
= atoi(argv
[3]);
1954 return RESULT_SUCCESS
;
1957 static int iax2_test_jitter(int fd
, int argc
, char *argv
[])
1959 if (argc
< 4 || argc
> 5)
1960 return RESULT_SHOWUSAGE
;
1962 test_jit
= atoi(argv
[3]);
1964 test_jitpct
= atoi(argv
[4]);
1966 return RESULT_SUCCESS
;
1968 #endif /* IAXTESTS */
1970 /*! \brief peer_status: Report Peer status in character string */
1971 /* returns 1 if peer is online, -1 if unmonitored */
1972 static int peer_status(struct iax2_peer
*peer
, char *status
, int statuslen
)
1976 if (peer
->lastms
< 0) {
1977 ast_copy_string(status
, "UNREACHABLE", statuslen
);
1978 } else if (peer
->lastms
> peer
->maxms
) {
1979 snprintf(status
, statuslen
, "LAGGED (%d ms)", peer
->lastms
);
1981 } else if (peer
->lastms
) {
1982 snprintf(status
, statuslen
, "OK (%d ms)", peer
->lastms
);
1985 ast_copy_string(status
, "UNKNOWN", statuslen
);
1988 ast_copy_string(status
, "Unmonitored", statuslen
);
1994 /*! \brief Show one peer in detail */
1995 static int iax2_show_peer(int fd
, int argc
, char *argv
[])
1999 struct iax2_peer
*peer
;
2000 char codec_buf
[512];
2001 int x
= 0, codec
= 0, load_realtime
= 0;
2004 return RESULT_SHOWUSAGE
;
2006 load_realtime
= (argc
== 5 && !strcmp(argv
[4], "load")) ? 1 : 0;
2008 peer
= find_peer(argv
[3], load_realtime
);
2011 ast_cli(fd
, " * Name : %s\n", peer
->name
);
2012 ast_cli(fd
, " Secret : %s\n", ast_strlen_zero(peer
->secret
)?"<Not set>":"<Set>");
2013 ast_cli(fd
, " Context : %s\n", peer
->context
);
2014 ast_cli(fd
, " Mailbox : %s\n", peer
->mailbox
);
2015 ast_cli(fd
, " Dynamic : %s\n", ast_test_flag(peer
, IAX_DYNAMIC
) ? "Yes":"No");
2016 ast_cli(fd
, " Callerid : %s\n", ast_callerid_merge(cbuf
, sizeof(cbuf
), peer
->cid_name
, peer
->cid_num
, "<unspecified>"));
2017 ast_cli(fd
, " Expire : %d\n", peer
->expire
);
2018 ast_cli(fd
, " ACL : %s\n", (peer
->ha
?"Yes":"No"));
2019 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
));
2020 ast_cli(fd
, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer
->defaddr
.sin_addr
), ntohs(peer
->defaddr
.sin_port
));
2021 ast_cli(fd
, " Username : %s\n", peer
->username
);
2022 ast_cli(fd
, " Codecs : ");
2023 ast_getformatname_multiple(codec_buf
, sizeof(codec_buf
) -1, peer
->capability
);
2024 ast_cli(fd
, "%s\n", codec_buf
);
2026 ast_cli(fd
, " Codec Order : (");
2027 for(x
= 0; x
< 32 ; x
++) {
2028 codec
= ast_codec_pref_index(&peer
->prefs
,x
);
2031 ast_cli(fd
, "%s", ast_getformatname(codec
));
2032 if(x
< 31 && ast_codec_pref_index(&peer
->prefs
,x
+1))
2037 ast_cli(fd
, "none");
2040 ast_cli(fd
, " Status : ");
2041 peer_status(peer
, status
, sizeof(status
));
2042 ast_cli(fd
, "%s\n",status
);
2043 ast_cli(fd
, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer
->pokefreqok
, peer
->pokefreqnotok
, peer
->smoothing
? "On" : "Off");
2045 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2048 ast_cli(fd
,"Peer %s not found.\n", argv
[3]);
2052 return RESULT_SUCCESS
;
2055 static char *complete_iax2_show_peer(const char *line
, const char *word
, int pos
, int state
)
2058 struct iax2_peer
*p
= NULL
;
2060 int wordlen
= strlen(word
);
2062 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
2064 AST_LIST_LOCK(&peers
);
2065 AST_LIST_TRAVERSE(&peers
, p
, entry
) {
2066 if (!strncasecmp(p
->name
, word
, wordlen
) && ++which
> state
) {
2067 res
= ast_strdup(p
->name
);
2071 AST_LIST_UNLOCK(&peers
);
2077 static int iax2_show_stats(int fd
, int argc
, char *argv
[])
2079 struct iax_frame
*cur
;
2080 int cnt
= 0, dead
=0, final
=0;
2083 return RESULT_SHOWUSAGE
;
2085 AST_LIST_LOCK(&iaxq
.queue
);
2086 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
2087 if (cur
->retries
< 0)
2093 AST_LIST_UNLOCK(&iaxq
.queue
);
2095 ast_cli(fd
, " IAX Statistics\n");
2096 ast_cli(fd
, "---------------------\n");
2097 ast_cli(fd
, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
2098 ast_cli(fd
, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead
, final
, cnt
);
2100 return RESULT_SUCCESS
;
2103 static int iax2_show_cache(int fd
, int argc
, char *argv
[])
2105 struct iax2_dpcache
*dp
;
2106 char tmp
[1024], *pc
;
2110 gettimeofday(&tv
, NULL
);
2111 ast_mutex_lock(&dpcache_lock
);
2113 ast_cli(fd
, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
2115 s
= dp
->expiry
.tv_sec
- tv
.tv_sec
;
2117 if (dp
->flags
& CACHE_FLAG_EXISTS
)
2118 strncat(tmp
, "EXISTS|", sizeof(tmp
) - strlen(tmp
) - 1);
2119 if (dp
->flags
& CACHE_FLAG_NONEXISTENT
)
2120 strncat(tmp
, "NONEXISTENT|", sizeof(tmp
) - strlen(tmp
) - 1);
2121 if (dp
->flags
& CACHE_FLAG_CANEXIST
)
2122 strncat(tmp
, "CANEXIST|", sizeof(tmp
) - strlen(tmp
) - 1);
2123 if (dp
->flags
& CACHE_FLAG_PENDING
)
2124 strncat(tmp
, "PENDING|", sizeof(tmp
) - strlen(tmp
) - 1);
2125 if (dp
->flags
& CACHE_FLAG_TIMEOUT
)
2126 strncat(tmp
, "TIMEOUT|", sizeof(tmp
) - strlen(tmp
) - 1);
2127 if (dp
->flags
& CACHE_FLAG_TRANSMITTED
)
2128 strncat(tmp
, "TRANSMITTED|", sizeof(tmp
) - strlen(tmp
) - 1);
2129 if (dp
->flags
& CACHE_FLAG_MATCHMORE
)
2130 strncat(tmp
, "MATCHMORE|", sizeof(tmp
) - strlen(tmp
) - 1);
2131 if (dp
->flags
& CACHE_FLAG_UNKNOWN
)
2132 strncat(tmp
, "UNKNOWN|", sizeof(tmp
) - strlen(tmp
) - 1);
2133 /* Trim trailing pipe */
2134 if (!ast_strlen_zero(tmp
))
2135 tmp
[strlen(tmp
) - 1] = '\0';
2137 ast_copy_string(tmp
, "(none)", sizeof(tmp
));
2139 pc
= strchr(dp
->peercontext
, '@');
2141 pc
= dp
->peercontext
;
2144 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
2145 if (dp
->waiters
[x
] > -1)
2148 ast_cli(fd
, "%-20.20s %-12.12s %-9d %-8d %s\n", pc
, dp
->exten
, s
, y
, tmp
);
2150 ast_cli(fd
, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc
, dp
->exten
, "(expired)", y
, tmp
);
2153 ast_mutex_unlock(&dpcache_lock
);
2154 return RESULT_SUCCESS
;
2157 static unsigned int calc_rxstamp(struct chan_iax2_pvt
*p
, unsigned int offset
);
2159 static void unwrap_timestamp(struct iax_frame
*fr
)
2163 if ( (fr
->ts
& 0xFFFF0000) == (iaxs
[fr
->callno
]->last
& 0xFFFF0000) ) {
2164 x
= fr
->ts
- iaxs
[fr
->callno
]->last
;
2166 /* Sudden big jump backwards in timestamp:
2167 What likely happened here is that miniframe timestamp has circled but we haven't
2168 gotten the update from the main packet. We'll just pretend that we did, and
2169 update the timestamp appropriately. */
2170 fr
->ts
= ( (iaxs
[fr
->callno
]->last
& 0xFFFF0000) + 0x10000) | (fr
->ts
& 0xFFFF);
2171 if (option_debug
&& iaxdebug
)
2172 ast_log(LOG_DEBUG
, "schedule_delivery: pushed forward timestamp\n");
2175 /* Sudden apparent big jump forwards in timestamp:
2176 What's likely happened is this is an old miniframe belonging to the previous
2177 top-16-bit timestamp that has turned up out of order.
2178 Adjust the timestamp appropriately. */
2179 fr
->ts
= ( (iaxs
[fr
->callno
]->last
& 0xFFFF0000) - 0x10000) | (fr
->ts
& 0xFFFF);
2180 if (option_debug
&& iaxdebug
)
2181 ast_log(LOG_DEBUG
, "schedule_delivery: pushed back timestamp\n");
2186 static int get_from_jb(void *p
);
2188 static void update_jbsched(struct chan_iax2_pvt
*pvt
)
2192 when
= ast_tvdiff_ms(ast_tvnow(), pvt
->rxcore
);
2194 when
= jb_next(pvt
->jb
) - when
;
2196 if(pvt
->jbid
> -1) ast_sched_del(sched
, pvt
->jbid
);
2199 /* XXX should really just empty until when > 0.. */
2203 pvt
->jbid
= ast_sched_add(sched
, when
, get_from_jb
, CALLNO_TO_PTR(pvt
->callno
));
2205 /* Signal scheduler thread */
2206 signal_condition(&sched_lock
, &sched_cond
);
2209 static void __get_from_jb(void *p
)
2211 int callno
= PTR_TO_CALLNO(p
);
2212 struct chan_iax2_pvt
*pvt
= NULL
;
2213 struct iax_frame
*fr
;
2220 /* Make sure we have a valid private structure before going on */
2221 ast_mutex_lock(&iaxsl
[callno
]);
2225 ast_mutex_unlock(&iaxsl
[callno
]);
2231 gettimeofday(&tv
,NULL
);
2232 /* round up a millisecond since ast_sched_runq does; */
2233 /* prevents us from spinning while waiting for our now */
2234 /* to catch up with runq's now */
2237 now
= ast_tvdiff_ms(tv
, pvt
->rxcore
);
2239 if(now
>= (next
= jb_next(pvt
->jb
))) {
2240 ret
= jb_get(pvt
->jb
,&frame
,now
,ast_codec_interp_len(pvt
->voiceformat
));
2248 struct ast_frame af
= { 0, };
2250 /* create an interpolation frame */
2251 af
.frametype
= AST_FRAME_VOICE
;
2252 af
.subclass
= pvt
->voiceformat
;
2253 af
.samples
= frame
.ms
* 8;
2254 af
.src
= "IAX2 JB interpolation";
2255 af
.delivery
= ast_tvadd(pvt
->rxcore
, ast_samp2tv(next
, 1000));
2256 af
.offset
= AST_FRIENDLY_OFFSET
;
2258 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
2259 * which we'd need to malloc, and then it would free it. That seems like a drag */
2260 if (!ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
))
2261 iax2_queue_frame(callno
, &af
);
2265 iax2_frame_free(frame
.data
);
2272 /* shouldn't happen */
2276 update_jbsched(pvt
);
2277 ast_mutex_unlock(&iaxsl
[callno
]);
2280 static int get_from_jb(void *data
)
2282 #ifdef SCHED_MULTITHREADED
2283 if (schedule_action(__get_from_jb
, data
))
2285 __get_from_jb(data
);
2289 static int schedule_delivery(struct iax_frame
*fr
, int updatehistory
, int fromtrunk
, unsigned int *tsout
)
2295 /* Attempt to recover wrapped timestamps */
2296 unwrap_timestamp(fr
);
2299 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
2300 if ( !fromtrunk
&& !ast_tvzero(iaxs
[fr
->callno
]->rxcore
))
2301 fr
->af
.delivery
= ast_tvadd(iaxs
[fr
->callno
]->rxcore
, ast_samp2tv(fr
->ts
, 1000));
2304 ast_log(LOG_DEBUG
, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
2306 fr
->af
.delivery
= ast_tv(0,0);
2309 type
= JB_TYPE_CONTROL
;
2312 if(fr
->af
.frametype
== AST_FRAME_VOICE
) {
2313 type
= JB_TYPE_VOICE
;
2314 len
= ast_codec_get_samples(&fr
->af
) / 8;
2315 } else if(fr
->af
.frametype
== AST_FRAME_CNG
) {
2316 type
= JB_TYPE_SILENCE
;
2319 if ( (!ast_test_flag(iaxs
[fr
->callno
], IAX_USEJITTERBUF
)) ) {
2326 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
2327 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
2328 if( (!ast_test_flag(iaxs
[fr
->callno
], IAX_FORCEJITTERBUF
)) &&
2329 iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
) &&
2330 (ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->tech
->properties
& AST_CHAN_TP_WANTSJITTER
)) {
2333 /* deliver any frames in the jb */
2334 while(jb_getall(iaxs
[fr
->callno
]->jb
,&frame
) == JB_OK
)
2335 __do_deliver(frame
.data
);
2337 jb_reset(iaxs
[fr
->callno
]->jb
);
2339 if (iaxs
[fr
->callno
]->jbid
> -1)
2340 ast_sched_del(sched
, iaxs
[fr
->callno
]->jbid
);
2342 iaxs
[fr
->callno
]->jbid
= -1;
2344 /* deliver this frame now */
2351 /* insert into jitterbuffer */
2352 /* TODO: Perhaps we could act immediately if it's not droppable and late */
2353 ret
= jb_put(iaxs
[fr
->callno
]->jb
, fr
, type
, len
, fr
->ts
,
2354 calc_rxstamp(iaxs
[fr
->callno
],fr
->ts
));
2355 if (ret
== JB_DROP
) {
2357 } else if (ret
== JB_SCHED
) {
2358 update_jbsched(iaxs
[fr
->callno
]);
2363 /* Free our iax frame */
2364 iax2_frame_free(fr
);
2370 static int iax2_transmit(struct iax_frame
*fr
)
2372 /* Lock the queue and place this packet at the end */
2373 /* By setting this to 0, the network thread will send it for us, and
2374 queue retransmission if necessary */
2376 AST_LIST_LOCK(&iaxq
.queue
);
2377 AST_LIST_INSERT_TAIL(&iaxq
.queue
, fr
, list
);
2379 AST_LIST_UNLOCK(&iaxq
.queue
);
2380 /* Wake up the network and scheduler thread */
2381 pthread_kill(netthreadid
, SIGURG
);
2382 signal_condition(&sched_lock
, &sched_cond
);
2388 static int iax2_digit_begin(struct ast_channel
*c
, char digit
)
2390 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_DTMF_BEGIN
, digit
, 0, NULL
, 0, -1);
2393 static int iax2_digit_end(struct ast_channel
*c
, char digit
, unsigned int duration
)
2395 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_DTMF_END
, digit
, 0, NULL
, 0, -1);
2398 static int iax2_sendtext(struct ast_channel
*c
, const char *text
)
2401 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_TEXT
,
2402 0, 0, (unsigned char *)text
, strlen(text
) + 1, -1);
2405 static int iax2_sendimage(struct ast_channel
*c
, struct ast_frame
*img
)
2407 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_IMAGE
, img
->subclass
, 0, img
->data
, img
->datalen
, -1);
2410 static int iax2_sendhtml(struct ast_channel
*c
, int subclass
, const char *data
, int datalen
)
2412 return send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_HTML
, subclass
, 0, (unsigned char *)data
, datalen
, -1);
2415 static int iax2_fixup(struct ast_channel
*oldchannel
, struct ast_channel
*newchan
)
2417 unsigned short callno
= PTR_TO_CALLNO(newchan
->tech_pvt
);
2418 ast_mutex_lock(&iaxsl
[callno
]);
2420 iaxs
[callno
]->owner
= newchan
;
2422 ast_log(LOG_WARNING
, "Uh, this isn't a good sign...\n");
2423 ast_mutex_unlock(&iaxsl
[callno
]);
2427 static struct iax2_peer
*realtime_peer(const char *peername
, struct sockaddr_in
*sin
)
2429 struct ast_variable
*var
;
2430 struct ast_variable
*tmp
;
2431 struct iax2_peer
*peer
=NULL
;
2432 time_t regseconds
= 0, nowtime
;
2436 var
= ast_load_realtime("iaxpeers", "name", peername
, NULL
);
2439 sprintf(porta
, "%d", ntohs(sin
->sin_port
));
2440 var
= ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin
->sin_addr
), "port", porta
, NULL
);
2442 /* We'll need the peer name in order to build the structure! */
2443 for (tmp
= var
; tmp
; tmp
= tmp
->next
) {
2444 if (!strcasecmp(tmp
->name
, "name"))
2445 peername
= tmp
->value
;
2452 peer
= build_peer(peername
, var
, NULL
, ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
) ? 0 : 1);
2455 ast_variables_destroy(var
);
2459 for (tmp
= var
; tmp
; tmp
= tmp
->next
) {
2460 /* Make sure it's not a user only... */
2461 if (!strcasecmp(tmp
->name
, "type")) {
2462 if (strcasecmp(tmp
->value
, "friend") &&
2463 strcasecmp(tmp
->value
, "peer")) {
2464 /* Whoops, we weren't supposed to exist! */
2469 } else if (!strcasecmp(tmp
->name
, "regseconds")) {
2470 ast_get_time_t(tmp
->value
, ®seconds
, 0, NULL
);
2471 } else if (!strcasecmp(tmp
->name
, "ipaddr")) {
2472 inet_aton(tmp
->value
, &(peer
->addr
.sin_addr
));
2473 } else if (!strcasecmp(tmp
->name
, "port")) {
2474 peer
->addr
.sin_port
= htons(atoi(tmp
->value
));
2475 } else if (!strcasecmp(tmp
->name
, "host")) {
2476 if (!strcasecmp(tmp
->value
, "dynamic"))
2481 ast_variables_destroy(var
);
2486 if (ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
)) {
2487 ast_copy_flags(peer
, &globalflags
, IAX_RTAUTOCLEAR
|IAX_RTCACHEFRIENDS
);
2488 if (ast_test_flag(peer
, IAX_RTAUTOCLEAR
)) {
2489 if (peer
->expire
> -1)
2490 ast_sched_del(sched
, peer
->expire
);
2491 peer
->expire
= ast_sched_add(sched
, (global_rtautoclear
) * 1000, expire_registry
, (void*)peer
->name
);
2493 AST_LIST_LOCK(&peers
);
2494 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
2495 AST_LIST_UNLOCK(&peers
);
2496 if (ast_test_flag(peer
, IAX_DYNAMIC
))
2497 reg_source_db(peer
);
2499 ast_set_flag(peer
, IAX_TEMPONLY
);
2502 if (!ast_test_flag(&globalflags
, IAX_RTIGNOREREGEXPIRE
) && dynamic
) {
2504 if ((nowtime
- regseconds
) > IAX_DEFAULT_REG_EXPIRE
) {
2505 memset(&peer
->addr
, 0, sizeof(peer
->addr
));
2506 realtime_update_peer(peer
->name
, &peer
->addr
, 0);
2508 ast_log(LOG_DEBUG
, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
2509 peername
, (int)(nowtime
- regseconds
), (int)regseconds
, (int)nowtime
);
2513 ast_log(LOG_DEBUG
, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
2514 peername
, (int)(nowtime
- regseconds
), (int)regseconds
, (int)nowtime
);
2521 static struct iax2_user
*realtime_user(const char *username
)
2523 struct ast_variable
*var
;
2524 struct ast_variable
*tmp
;
2525 struct iax2_user
*user
=NULL
;
2527 var
= ast_load_realtime("iaxusers", "name", username
, NULL
);
2533 /* Make sure it's not a peer only... */
2534 if (!strcasecmp(tmp
->name
, "type")) {
2535 if (strcasecmp(tmp
->value
, "friend") &&
2536 strcasecmp(tmp
->value
, "user")) {
2543 user
= build_user(username
, var
, NULL
, !ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
));
2545 ast_variables_destroy(var
);
2550 if (ast_test_flag((&globalflags
), IAX_RTCACHEFRIENDS
)) {
2551 ast_set_flag(user
, IAX_RTCACHEFRIENDS
);
2552 AST_LIST_LOCK(&users
);
2553 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
2554 AST_LIST_UNLOCK(&users
);
2556 ast_set_flag(user
, IAX_TEMPONLY
);
2562 static void realtime_update_peer(const char *peername
, struct sockaddr_in
*sin
, time_t regtime
)
2565 char regseconds
[20];
2567 snprintf(regseconds
, sizeof(regseconds
), "%d", (int)regtime
);
2568 snprintf(port
, sizeof(port
), "%d", ntohs(sin
->sin_port
));
2569 ast_update_realtime("iaxpeers", "name", peername
,
2570 "ipaddr", ast_inet_ntoa(sin
->sin_addr
), "port", port
,
2571 "regseconds", regseconds
, NULL
);
2574 struct create_addr_info
{
2587 char context
[AST_MAX_CONTEXT
];
2588 char peercontext
[AST_MAX_CONTEXT
];
2589 char mohinterpret
[MAX_MUSICCLASS
];
2590 char mohsuggest
[MAX_MUSICCLASS
];
2593 static int create_addr(const char *peername
, struct sockaddr_in
*sin
, struct create_addr_info
*cai
)
2595 struct ast_hostent ahp
;
2597 struct iax2_peer
*peer
;
2599 ast_clear_flag(cai
, IAX_SENDANI
| IAX_TRUNK
);
2600 cai
->sockfd
= defaultsockfd
;
2602 sin
->sin_family
= AF_INET
;
2604 if (!(peer
= find_peer(peername
, 1))) {
2607 hp
= ast_gethostbyname(peername
, &ahp
);
2609 memcpy(&sin
->sin_addr
, hp
->h_addr
, sizeof(sin
->sin_addr
));
2610 sin
->sin_port
= htons(IAX_DEFAULT_PORTNO
);
2611 /* use global iax prefs for unknown peer/user */
2612 ast_codec_pref_convert(&prefs
, cai
->prefs
, sizeof(cai
->prefs
), 1);
2615 ast_log(LOG_WARNING
, "No such host: %s\n", peername
);
2622 /* if the peer has no address (current or default), return failure */
2623 if (!(peer
->addr
.sin_addr
.s_addr
|| peer
->defaddr
.sin_addr
.s_addr
)) {
2624 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2629 /* if the peer is being monitored and is currently unreachable, return failure */
2630 if (peer
->maxms
&& ((peer
->lastms
> peer
->maxms
) || (peer
->lastms
< 0))) {
2631 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2636 ast_copy_flags(cai
, peer
, IAX_SENDANI
| IAX_TRUNK
| IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
2637 cai
->maxtime
= peer
->maxms
;
2638 cai
->capability
= peer
->capability
;
2639 cai
->encmethods
= peer
->encmethods
;
2640 cai
->sockfd
= peer
->sockfd
;
2641 cai
->adsi
= peer
->adsi
;
2642 ast_codec_pref_convert(&peer
->prefs
, cai
->prefs
, sizeof(cai
->prefs
), 1);
2643 ast_copy_string(cai
->context
, peer
->context
, sizeof(cai
->context
));
2644 ast_copy_string(cai
->peercontext
, peer
->peercontext
, sizeof(cai
->peercontext
));
2645 ast_copy_string(cai
->username
, peer
->username
, sizeof(cai
->username
));
2646 ast_copy_string(cai
->timezone
, peer
->zonetag
, sizeof(cai
->timezone
));
2647 ast_copy_string(cai
->outkey
, peer
->outkey
, sizeof(cai
->outkey
));
2648 ast_copy_string(cai
->mohinterpret
, peer
->mohinterpret
, sizeof(cai
->mohinterpret
));
2649 ast_copy_string(cai
->mohsuggest
, peer
->mohsuggest
, sizeof(cai
->mohsuggest
));
2650 if (ast_strlen_zero(peer
->dbsecret
)) {
2651 ast_copy_string(cai
->secret
, peer
->secret
, sizeof(cai
->secret
));
2656 family
= ast_strdupa(peer
->dbsecret
);
2657 key
= strchr(family
, '/');
2660 if (!key
|| ast_db_get(family
, key
, cai
->secret
, sizeof(cai
->secret
))) {
2661 ast_log(LOG_WARNING
, "Unable to retrieve database password for family/key '%s'!\n", peer
->dbsecret
);
2662 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2668 if (peer
->addr
.sin_addr
.s_addr
) {
2669 sin
->sin_addr
= peer
->addr
.sin_addr
;
2670 sin
->sin_port
= peer
->addr
.sin_port
;
2672 sin
->sin_addr
= peer
->defaddr
.sin_addr
;
2673 sin
->sin_port
= peer
->defaddr
.sin_port
;
2676 if (ast_test_flag(peer
, IAX_TEMPONLY
))
2682 static void __auto_congest(void *nothing
)
2684 int callno
= PTR_TO_CALLNO(nothing
);
2685 struct ast_frame f
= { AST_FRAME_CONTROL
, AST_CONTROL_CONGESTION
};
2686 ast_mutex_lock(&iaxsl
[callno
]);
2688 iaxs
[callno
]->initid
= -1;
2689 iax2_queue_frame(callno
, &f
);
2690 ast_log(LOG_NOTICE
, "Auto-congesting call due to slow response\n");
2692 ast_mutex_unlock(&iaxsl
[callno
]);
2695 static int auto_congest(void *data
)
2697 #ifdef SCHED_MULTITHREADED
2698 if (schedule_action(__auto_congest
, data
))
2700 __auto_congest(data
);
2704 static unsigned int iax2_datetime(const char *tz
)
2710 localtime_r(&t
, &tm
);
2711 if (!ast_strlen_zero(tz
))
2712 ast_localtime(&t
, &tm
, tz
);
2713 tmp
= (tm
.tm_sec
>> 1) & 0x1f; /* 5 bits of seconds */
2714 tmp
|= (tm
.tm_min
& 0x3f) << 5; /* 6 bits of minutes */
2715 tmp
|= (tm
.tm_hour
& 0x1f) << 11; /* 5 bits of hours */
2716 tmp
|= (tm
.tm_mday
& 0x1f) << 16; /* 5 bits of day of month */
2717 tmp
|= ((tm
.tm_mon
+ 1) & 0xf) << 21; /* 4 bits of month */
2718 tmp
|= ((tm
.tm_year
- 100) & 0x7f) << 25; /* 7 bits of year */
2722 struct parsed_dial_string
{
2734 * \brief Parses an IAX dial string into its component parts.
2735 * \param data the string to be parsed
2736 * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
2739 * This function parses the string and fills the structure
2740 * with pointers to its component parts. The input string
2743 * \note This function supports both plaintext passwords and RSA
2744 * key names; if the password string is formatted as '[keyname]',
2745 * then the keyname will be placed into the key field, and the
2746 * password field will be set to NULL.
2748 * \note The dial string format is:
2749 * [username[:password]@]peer[:port][/exten[@@context]][/options]
2751 static void parse_dial_string(char *data
, struct parsed_dial_string
*pds
)
2753 if (ast_strlen_zero(data
))
2756 pds
->peer
= strsep(&data
, "/");
2757 pds
->exten
= strsep(&data
, "/");
2758 pds
->options
= data
;
2762 pds
->exten
= strsep(&data
, "@");
2763 pds
->context
= data
;
2766 if (strchr(pds
->peer
, '@')) {
2768 pds
->username
= strsep(&data
, "@");
2772 if (pds
->username
) {
2773 data
= pds
->username
;
2774 pds
->username
= strsep(&data
, ":");
2775 pds
->password
= data
;
2779 pds
->peer
= strsep(&data
, ":");
2782 /* check for a key name wrapped in [] in the secret position, if found,
2783 move it to the key field instead
2785 if (pds
->password
&& (pds
->password
[0] == '[')) {
2786 pds
->key
= ast_strip_quoted(pds
->password
, "[", "]");
2787 pds
->password
= NULL
;
2791 static int iax2_call(struct ast_channel
*c
, char *dest
, int timeout
)
2793 struct sockaddr_in sin
;
2794 char *l
=NULL
, *n
=NULL
, *tmpstr
;
2795 struct iax_ie_data ied
;
2796 char *defaultrdest
= "s";
2797 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
2798 struct parsed_dial_string pds
;
2799 struct create_addr_info cai
;
2801 if ((c
->_state
!= AST_STATE_DOWN
) && (c
->_state
!= AST_STATE_RESERVED
)) {
2802 ast_log(LOG_WARNING
, "Channel is already in use (%s)?\n", c
->name
);
2806 memset(&cai
, 0, sizeof(cai
));
2807 cai
.encmethods
= iax2_encryption
;
2809 memset(&pds
, 0, sizeof(pds
));
2810 tmpstr
= ast_strdupa(dest
);
2811 parse_dial_string(tmpstr
, &pds
);
2814 pds
.exten
= defaultrdest
;
2816 if (create_addr(pds
.peer
, &sin
, &cai
)) {
2817 ast_log(LOG_WARNING
, "No address associated with '%s'\n", pds
.peer
);
2821 if (!pds
.username
&& !ast_strlen_zero(cai
.username
))
2822 pds
.username
= cai
.username
;
2823 if (!pds
.password
&& !ast_strlen_zero(cai
.secret
))
2824 pds
.password
= cai
.secret
;
2825 if (!pds
.key
&& !ast_strlen_zero(cai
.outkey
))
2826 pds
.key
= cai
.outkey
;
2827 if (!pds
.context
&& !ast_strlen_zero(cai
.peercontext
))
2828 pds
.context
= cai
.peercontext
;
2830 /* Keep track of the context for outgoing calls too */
2831 ast_copy_string(c
->context
, cai
.context
, sizeof(c
->context
));
2834 sin
.sin_port
= htons(atoi(pds
.port
));
2837 n
= c
->cid
.cid_name
;
2839 /* Now build request */
2840 memset(&ied
, 0, sizeof(ied
));
2842 /* On new call, first IE MUST be IAX version of caller */
2843 iax_ie_append_short(&ied
, IAX_IE_VERSION
, IAX_PROTO_VERSION
);
2844 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, pds
.exten
);
2845 if (pds
.options
&& strchr(pds
.options
, 'a')) {
2846 /* Request auto answer */
2847 iax_ie_append(&ied
, IAX_IE_AUTOANSWER
);
2850 iax_ie_append_str(&ied
, IAX_IE_CODEC_PREFS
, cai
.prefs
);
2853 iax_ie_append_str(&ied
, IAX_IE_CALLING_NUMBER
, l
);
2854 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, c
->cid
.cid_pres
);
2857 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, c
->cid
.cid_pres
);
2859 iax_ie_append_byte(&ied
, IAX_IE_CALLINGPRES
, AST_PRES_NUMBER_NOT_AVAILABLE
);
2862 iax_ie_append_byte(&ied
, IAX_IE_CALLINGTON
, c
->cid
.cid_ton
);
2863 iax_ie_append_short(&ied
, IAX_IE_CALLINGTNS
, c
->cid
.cid_tns
);
2866 iax_ie_append_str(&ied
, IAX_IE_CALLING_NAME
, n
);
2867 if (ast_test_flag(iaxs
[callno
], IAX_SENDANI
) && c
->cid
.cid_ani
)
2868 iax_ie_append_str(&ied
, IAX_IE_CALLING_ANI
, c
->cid
.cid_ani
);
2870 if (!ast_strlen_zero(c
->language
))
2871 iax_ie_append_str(&ied
, IAX_IE_LANGUAGE
, c
->language
);
2872 if (!ast_strlen_zero(c
->cid
.cid_dnid
))
2873 iax_ie_append_str(&ied
, IAX_IE_DNID
, c
->cid
.cid_dnid
);
2874 if (!ast_strlen_zero(c
->cid
.cid_rdnis
))
2875 iax_ie_append_str(&ied
, IAX_IE_RDNIS
, c
->cid
.cid_rdnis
);
2878 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, pds
.context
);
2881 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, pds
.username
);
2884 iax_ie_append_short(&ied
, IAX_IE_ENCRYPTION
, cai
.encmethods
);
2886 ast_mutex_lock(&iaxsl
[callno
]);
2888 if (!ast_strlen_zero(c
->context
))
2889 ast_string_field_set(iaxs
[callno
], context
, c
->context
);
2892 ast_string_field_set(iaxs
[callno
], username
, pds
.username
);
2894 iaxs
[callno
]->encmethods
= cai
.encmethods
;
2896 iaxs
[callno
]->adsi
= cai
.adsi
;
2898 ast_string_field_set(iaxs
[callno
], mohinterpret
, cai
.mohinterpret
);
2899 ast_string_field_set(iaxs
[callno
], mohsuggest
, cai
.mohsuggest
);
2902 ast_string_field_set(iaxs
[callno
], outkey
, pds
.key
);
2904 ast_string_field_set(iaxs
[callno
], secret
, pds
.password
);
2906 iax_ie_append_int(&ied
, IAX_IE_FORMAT
, c
->nativeformats
);
2907 iax_ie_append_int(&ied
, IAX_IE_CAPABILITY
, iaxs
[callno
]->capability
);
2908 iax_ie_append_short(&ied
, IAX_IE_ADSICPE
, c
->adsicpe
);
2909 iax_ie_append_int(&ied
, IAX_IE_DATETIME
, iax2_datetime(cai
.timezone
));
2911 if (iaxs
[callno
]->maxtime
) {
2912 /* Initialize pingtime and auto-congest time */
2913 iaxs
[callno
]->pingtime
= iaxs
[callno
]->maxtime
/ 2;
2914 iaxs
[callno
]->initid
= ast_sched_add(sched
, iaxs
[callno
]->maxtime
* 2, auto_congest
, CALLNO_TO_PTR(callno
));
2915 } else if (autokill
) {
2916 iaxs
[callno
]->pingtime
= autokill
/ 2;
2917 iaxs
[callno
]->initid
= ast_sched_add(sched
, autokill
* 2, auto_congest
, CALLNO_TO_PTR(callno
));
2920 /* send the command using the appropriate socket for this peer */
2921 iaxs
[callno
]->sockfd
= cai
.sockfd
;
2923 /* Transmit the string in a "NEW" request */
2924 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_NEW
, 0, ied
.buf
, ied
.pos
, -1);
2926 ast_mutex_unlock(&iaxsl
[callno
]);
2927 ast_setstate(c
, AST_STATE_RINGING
);
2932 static int iax2_hangup(struct ast_channel
*c
)
2934 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
2936 struct iax_ie_data ied
;
2937 memset(&ied
, 0, sizeof(ied
));
2938 ast_mutex_lock(&iaxsl
[callno
]);
2939 if (callno
&& iaxs
[callno
]) {
2940 ast_log(LOG_DEBUG
, "We're hanging up %s now...\n", c
->name
);
2941 alreadygone
= ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
);
2942 /* Send the hangup unless we have had a transmission error or are already gone */
2943 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, (unsigned char)c
->hangupcause
);
2944 if (!iaxs
[callno
]->error
&& !alreadygone
)
2945 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_HANGUP
, 0, ied
.buf
, ied
.pos
, -1);
2946 /* Explicitly predestroy it */
2947 iax2_predestroy(callno
);
2948 /* If we were already gone to begin with, destroy us now */
2950 ast_log(LOG_DEBUG
, "Really destroying %s now...\n", c
->name
);
2951 iax2_destroy(callno
);
2954 ast_mutex_unlock(&iaxsl
[callno
]);
2955 if (option_verbose
> 2)
2956 ast_verbose(VERBOSE_PREFIX_3
"Hungup '%s'\n", c
->name
);
2960 static int iax2_setoption(struct ast_channel
*c
, int option
, void *data
, int datalen
)
2962 struct ast_option_header
*h
;
2966 case AST_OPTION_TXGAIN
:
2967 case AST_OPTION_RXGAIN
:
2968 /* these two cannot be sent, because they require a result */
2972 if (!(h
= ast_malloc(datalen
+ sizeof(*h
))))
2975 h
->flag
= AST_OPTION_FLAG_REQUEST
;
2976 h
->option
= htons(option
);
2977 memcpy(h
->data
, data
, datalen
);
2978 res
= send_command_locked(PTR_TO_CALLNO(c
->tech_pvt
), AST_FRAME_CONTROL
,
2979 AST_CONTROL_OPTION
, 0, (unsigned char *) h
,
2980 datalen
+ sizeof(*h
), -1);
2986 static struct ast_frame
*iax2_read(struct ast_channel
*c
)
2988 ast_log(LOG_NOTICE
, "I should never be called!\n");
2989 return &ast_null_frame
;
2992 static int iax2_start_transfer(unsigned short callno0
, unsigned short callno1
, int mediaonly
)
2995 struct iax_ie_data ied0
;
2996 struct iax_ie_data ied1
;
2997 unsigned int transferid
= (unsigned int)ast_random();
2998 memset(&ied0
, 0, sizeof(ied0
));
2999 iax_ie_append_addr(&ied0
, IAX_IE_APPARENT_ADDR
, &iaxs
[callno1
]->addr
);
3000 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[callno1
]->peercallno
);
3001 iax_ie_append_int(&ied0
, IAX_IE_TRANSFERID
, transferid
);
3003 memset(&ied1
, 0, sizeof(ied1
));
3004 iax_ie_append_addr(&ied1
, IAX_IE_APPARENT_ADDR
, &iaxs
[callno0
]->addr
);
3005 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[callno0
]->peercallno
);
3006 iax_ie_append_int(&ied1
, IAX_IE_TRANSFERID
, transferid
);
3008 res
= send_command(iaxs
[callno0
], AST_FRAME_IAX
, IAX_COMMAND_TXREQ
, 0, ied0
.buf
, ied0
.pos
, -1);
3011 res
= send_command(iaxs
[callno1
], AST_FRAME_IAX
, IAX_COMMAND_TXREQ
, 0, ied1
.buf
, ied1
.pos
, -1);
3014 iaxs
[callno0
]->transferring
= mediaonly
? TRANSFER_MBEGIN
: TRANSFER_BEGIN
;
3015 iaxs
[callno1
]->transferring
= mediaonly
? TRANSFER_MBEGIN
: TRANSFER_BEGIN
;
3019 static void lock_both(unsigned short callno0
, unsigned short callno1
)
3021 ast_mutex_lock(&iaxsl
[callno0
]);
3022 while (ast_mutex_trylock(&iaxsl
[callno1
])) {
3023 ast_mutex_unlock(&iaxsl
[callno0
]);
3025 ast_mutex_lock(&iaxsl
[callno0
]);
3029 static void unlock_both(unsigned short callno0
, unsigned short callno1
)
3031 ast_mutex_unlock(&iaxsl
[callno1
]);
3032 ast_mutex_unlock(&iaxsl
[callno0
]);
3035 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
)
3037 struct ast_channel
*cs
[3];
3038 struct ast_channel
*who
, *other
;
3041 int transferstarted
=0;
3042 struct ast_frame
*f
;
3043 unsigned short callno0
= PTR_TO_CALLNO(c0
->tech_pvt
);
3044 unsigned short callno1
= PTR_TO_CALLNO(c1
->tech_pvt
);
3045 struct timeval waittimer
= {0, 0}, tv
;
3047 lock_both(callno0
, callno1
);
3048 /* Put them in native bridge mode */
3049 if (!flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
)) {
3050 iaxs
[callno0
]->bridgecallno
= callno1
;
3051 iaxs
[callno1
]->bridgecallno
= callno0
;
3053 unlock_both(callno0
, callno1
);
3055 /* If not, try to bridge until we can execute a transfer, if we can */
3058 for (/* ever */;;) {
3059 /* Check in case we got masqueraded into */
3060 if ((c0
->tech
!= &iax2_tech
) || (c1
->tech
!= &iax2_tech
)) {
3061 if (option_verbose
> 2)
3062 ast_verbose(VERBOSE_PREFIX_3
"Can't masquerade, we're different...\n");
3063 /* Remove from native mode */
3064 if (c0
->tech
== &iax2_tech
) {
3065 ast_mutex_lock(&iaxsl
[callno0
]);
3066 iaxs
[callno0
]->bridgecallno
= 0;
3067 ast_mutex_unlock(&iaxsl
[callno0
]);
3069 if (c1
->tech
== &iax2_tech
) {
3070 ast_mutex_lock(&iaxsl
[callno1
]);
3071 iaxs
[callno1
]->bridgecallno
= 0;
3072 ast_mutex_unlock(&iaxsl
[callno1
]);
3074 return AST_BRIDGE_FAILED_NOWARN
;
3076 if (c0
->nativeformats
!= c1
->nativeformats
) {
3077 if (option_verbose
> 2) {
3080 ast_getformatname_multiple(buf0
, sizeof(buf0
) -1, c0
->nativeformats
);
3081 ast_getformatname_multiple(buf1
, sizeof(buf1
) -1, c1
->nativeformats
);
3082 ast_verbose(VERBOSE_PREFIX_3
"Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0
->nativeformats
, buf0
, c1
->nativeformats
, buf1
);
3084 /* Remove from native mode */
3085 lock_both(callno0
, callno1
);
3086 iaxs
[callno0
]->bridgecallno
= 0;
3087 iaxs
[callno1
]->bridgecallno
= 0;
3088 unlock_both(callno0
, callno1
);
3089 return AST_BRIDGE_FAILED_NOWARN
;
3091 /* check if transfered and if we really want native bridging */
3092 if (!transferstarted
&& !ast_test_flag(iaxs
[callno0
], IAX_NOTRANSFER
) && !ast_test_flag(iaxs
[callno1
], IAX_NOTRANSFER
)) {
3093 /* Try the transfer */
3094 if (iax2_start_transfer(callno0
, callno1
, (flags
& (AST_BRIDGE_DTMF_CHANNEL_0
| AST_BRIDGE_DTMF_CHANNEL_1
)) ||
3095 ast_test_flag(iaxs
[callno0
], IAX_TRANSFERMEDIA
) | ast_test_flag(iaxs
[callno1
], IAX_TRANSFERMEDIA
)))
3096 ast_log(LOG_WARNING
, "Unable to start the transfer\n");
3097 transferstarted
= 1;
3099 if ((iaxs
[callno0
]->transferring
== TRANSFER_RELEASED
) && (iaxs
[callno1
]->transferring
== TRANSFER_RELEASED
)) {
3100 /* Call has been transferred. We're no longer involved */
3101 gettimeofday(&tv
, NULL
);
3102 if (ast_tvzero(waittimer
)) {
3104 } else if (tv
.tv_sec
- waittimer
.tv_sec
> IAX_LINGER_TIMEOUT
) {
3105 c0
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3106 c1
->_softhangup
|= AST_SOFTHANGUP_DEV
;
3109 res
= AST_BRIDGE_COMPLETE
;
3114 who
= ast_waitfor_n(cs
, 2, &to
);
3115 if (timeoutms
> -1) {
3116 timeoutms
-= (1000 - to
);
3122 res
= AST_BRIDGE_RETRY
;
3125 if (ast_check_hangup(c0
) || ast_check_hangup(c1
)) {
3126 res
= AST_BRIDGE_FAILED
;
3135 res
= AST_BRIDGE_COMPLETE
;
3138 if ((f
->frametype
== AST_FRAME_CONTROL
) && !(flags
& AST_BRIDGE_IGNORE_SIGS
)) {
3141 res
= AST_BRIDGE_COMPLETE
;
3144 other
= (who
== c0
) ? c1
: c0
; /* the 'other' channel */
3145 if ((f
->frametype
== AST_FRAME_VOICE
) ||
3146 (f
->frametype
== AST_FRAME_TEXT
) ||
3147 (f
->frametype
== AST_FRAME_VIDEO
) ||
3148 (f
->frametype
== AST_FRAME_IMAGE
) ||
3149 (f
->frametype
== AST_FRAME_DTMF
)) {
3150 /* monitored dtmf take out of the bridge.
3151 * check if we monitor the specific source.
3153 int monitored_source
= (who
== c0
) ? AST_BRIDGE_DTMF_CHANNEL_0
: AST_BRIDGE_DTMF_CHANNEL_1
;
3154 if (f
->frametype
== AST_FRAME_DTMF
&& (flags
& monitored_source
)) {
3157 res
= AST_BRIDGE_COMPLETE
;
3158 /* Remove from native mode */
3161 /* everything else goes to the other side */
3162 ast_write(other
, f
);
3165 /* Swap who gets priority */
3170 lock_both(callno0
, callno1
);
3172 iaxs
[callno0
]->bridgecallno
= 0;
3174 iaxs
[callno1
]->bridgecallno
= 0;
3175 unlock_both(callno0
, callno1
);
3179 static int iax2_answer(struct ast_channel
*c
)
3181 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3183 ast_log(LOG_DEBUG
, "Answering IAX2 call\n");
3184 return send_command_locked(callno
, AST_FRAME_CONTROL
, AST_CONTROL_ANSWER
, 0, NULL
, 0, -1);
3187 static int iax2_indicate(struct ast_channel
*c
, int condition
, const void *data
, size_t datalen
)
3189 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3190 struct chan_iax2_pvt
*pvt
;
3193 if (option_debug
&& iaxdebug
)
3194 ast_log(LOG_DEBUG
, "Indicating condition %d\n", condition
);
3196 ast_mutex_lock(&iaxsl
[callno
]);
3198 if (!strcasecmp(pvt
->mohinterpret
, "passthrough")) {
3199 res
= send_command(pvt
, AST_FRAME_CONTROL
, condition
, 0, data
, datalen
, -1);
3200 ast_mutex_unlock(&iaxsl
[callno
]);
3204 switch (condition
) {
3205 case AST_CONTROL_HOLD
:
3206 ast_moh_start(c
, data
, pvt
->mohinterpret
);
3208 case AST_CONTROL_UNHOLD
:
3212 res
= send_command(pvt
, AST_FRAME_CONTROL
, condition
, 0, data
, datalen
, -1);
3215 ast_mutex_unlock(&iaxsl
[callno
]);
3220 static int iax2_transfer(struct ast_channel
*c
, const char *dest
)
3222 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
3223 struct iax_ie_data ied
;
3224 char tmp
[256], *context
;
3225 ast_copy_string(tmp
, dest
, sizeof(tmp
));
3226 context
= strchr(tmp
, '@');
3231 memset(&ied
, 0, sizeof(ied
));
3232 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, tmp
);
3234 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, context
);
3236 ast_log(LOG_DEBUG
, "Transferring '%s' to '%s'\n", c
->name
, dest
);
3237 return send_command_locked(callno
, AST_FRAME_IAX
, IAX_COMMAND_TRANSFER
, 0, ied
.buf
, ied
.pos
, -1);
3240 static int iax2_getpeertrunk(struct sockaddr_in sin
)
3242 struct iax2_peer
*peer
= NULL
;
3245 AST_LIST_LOCK(&peers
);
3246 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
3247 if ((peer
->addr
.sin_addr
.s_addr
== sin
.sin_addr
.s_addr
) &&
3248 (peer
->addr
.sin_port
== sin
.sin_port
)) {
3249 res
= ast_test_flag(peer
, IAX_TRUNK
);
3253 AST_LIST_UNLOCK(&peers
);
3258 /*! \brief Create new call, interface with the PBX core */
3259 static struct ast_channel
*ast_iax2_new(int callno
, int state
, int capability
)
3261 struct ast_channel
*tmp
;
3262 struct chan_iax2_pvt
*i
;
3263 struct ast_variable
*v
= NULL
;
3265 if (!(i
= iaxs
[callno
])) {
3266 ast_log(LOG_WARNING
, "No IAX2 pvt found for callno '%d' !\n", callno
);
3270 /* Don't hold call lock */
3271 ast_mutex_unlock(&iaxsl
[callno
]);
3272 tmp
= ast_channel_alloc(1, state
, i
->cid_num
, i
->cid_name
, "IAX2/%s-%d", i
->host
, i
->callno
);
3273 ast_mutex_lock(&iaxsl
[callno
]);
3276 tmp
->tech
= &iax2_tech
;
3277 /* We can support any format by default, until we get restricted */
3278 tmp
->nativeformats
= capability
;
3279 tmp
->readformat
= ast_best_codec(capability
);
3280 tmp
->writeformat
= ast_best_codec(capability
);
3281 tmp
->tech_pvt
= CALLNO_TO_PTR(i
->callno
);
3283 /* Don't use ast_set_callerid() here because it will
3284 * generate a NewCallerID event before the NewChannel event */
3285 tmp
->cid
.cid_num
= ast_strdup(i
->cid_num
);
3286 tmp
->cid
.cid_name
= ast_strdup(i
->cid_name
);
3287 if (!ast_strlen_zero(i
->ani
))
3288 tmp
->cid
.cid_ani
= ast_strdup(i
->ani
);
3290 tmp
->cid
.cid_ani
= ast_strdup(i
->cid_num
);
3291 tmp
->cid
.cid_dnid
= ast_strdup(i
->dnid
);
3292 tmp
->cid
.cid_rdnis
= ast_strdup(i
->rdnis
);
3293 tmp
->cid
.cid_pres
= i
->calling_pres
;
3294 tmp
->cid
.cid_ton
= i
->calling_ton
;
3295 tmp
->cid
.cid_tns
= i
->calling_tns
;
3296 if (!ast_strlen_zero(i
->language
))
3297 ast_string_field_set(tmp
, language
, i
->language
);
3298 if (!ast_strlen_zero(i
->accountcode
))
3299 ast_string_field_set(tmp
, accountcode
, i
->accountcode
);
3301 tmp
->amaflags
= i
->amaflags
;
3302 ast_copy_string(tmp
->context
, i
->context
, sizeof(tmp
->context
));
3303 ast_copy_string(tmp
->exten
, i
->exten
, sizeof(tmp
->exten
));
3305 tmp
->adsicpe
= i
->peeradsicpe
;
3307 tmp
->adsicpe
= AST_ADSI_UNAVAILABLE
;
3309 i
->capability
= capability
;
3310 if (state
!= AST_STATE_DOWN
) {
3311 if (ast_pbx_start(tmp
)) {
3312 ast_log(LOG_WARNING
, "Unable to start PBX on %s\n", tmp
->name
);
3319 for (v
= i
->vars
; v
; v
= v
->next
)
3320 pbx_builtin_setvar_helper(tmp
, v
->name
, v
->value
);
3322 ast_module_ref(ast_module_info
->self
);
3327 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer
*tpeer
, int sampms
, struct timeval
*tv
)
3329 unsigned long int mssincetx
; /* unsigned to handle overflows */
3332 tpeer
->trunkact
= *tv
;
3333 mssincetx
= ast_tvdiff_ms(*tv
, tpeer
->lasttxtime
);
3334 if (mssincetx
> 5000 || ast_tvzero(tpeer
->txtrunktime
)) {
3335 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
3336 tpeer
->txtrunktime
= *tv
;
3337 tpeer
->lastsent
= 999999;
3339 /* Update last transmit time now */
3340 tpeer
->lasttxtime
= *tv
;
3342 /* Calculate ms offset */
3343 ms
= ast_tvdiff_ms(*tv
, tpeer
->txtrunktime
);
3344 /* Predict from last value */
3345 pred
= tpeer
->lastsent
+ sampms
;
3346 if (abs(ms
- pred
) < MAX_TIMESTAMP_SKEW
)
3349 /* We never send the same timestamp twice, so fudge a little if we must */
3350 if (ms
== tpeer
->lastsent
)
3351 ms
= tpeer
->lastsent
+ 1;
3352 tpeer
->lastsent
= ms
;
3356 static unsigned int fix_peerts(struct timeval
*tv
, int callno
, unsigned int ts
)
3358 long ms
; /* NOT unsigned */
3359 if (ast_tvzero(iaxs
[callno
]->rxcore
)) {
3360 /* Initialize rxcore time if appropriate */
3361 gettimeofday(&iaxs
[callno
]->rxcore
, NULL
);
3362 /* Round to nearest 20ms so traces look pretty */
3363 iaxs
[callno
]->rxcore
.tv_usec
-= iaxs
[callno
]->rxcore
.tv_usec
% 20000;
3365 /* Calculate difference between trunk and channel */
3366 ms
= ast_tvdiff_ms(*tv
, iaxs
[callno
]->rxcore
);
3367 /* Return as the sum of trunk time and the difference between trunk and real time */
3371 static unsigned int calc_timestamp(struct chan_iax2_pvt
*p
, unsigned int ts
, struct ast_frame
*f
)
3377 struct timeval
*delivery
= NULL
;
3380 /* What sort of frame do we have?: voice is self-explanatory
3381 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
3382 non-genuine frames are CONTROL frames [ringing etc], DTMF
3383 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
3384 the others need a timestamp slaved to the voice frames so that they go in sequence
3387 if (f
->frametype
== AST_FRAME_VOICE
) {
3389 delivery
= &f
->delivery
;
3390 } else if (f
->frametype
== AST_FRAME_IAX
) {
3392 } else if (f
->frametype
== AST_FRAME_CNG
) {
3396 if (ast_tvzero(p
->offset
)) {
3397 gettimeofday(&p
->offset
, NULL
);
3398 /* Round to nearest 20ms for nice looking traces */
3399 p
->offset
.tv_usec
-= p
->offset
.tv_usec
% 20000;
3401 /* If the timestamp is specified, just send it as is */
3404 /* If we have a time that the frame arrived, always use it to make our timestamp */
3405 if (delivery
&& !ast_tvzero(*delivery
)) {
3406 ms
= ast_tvdiff_ms(*delivery
, p
->offset
);
3407 if (option_debug
> 2 && iaxdebug
)
3408 ast_log(LOG_DEBUG
, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p
->callno
, iaxs
[p
->callno
]->peercallno
);
3410 ms
= ast_tvdiff_ms(ast_tvnow(), p
->offset
);
3414 /* On a voice frame, use predicted values if appropriate */
3415 if (p
->notsilenttx
&& abs(ms
- p
->nextpred
) <= MAX_TIMESTAMP_SKEW
) {
3416 /* Adjust our txcore, keeping voice and non-voice synchronized */
3418 When we send voice, we usually send "calculated" timestamps worked out
3419 on the basis of the number of samples sent. When we send other frames,
3420 we usually send timestamps worked out from the real clock.
3421 The problem is that they can tend to drift out of step because the
3422 source channel's clock and our clock may not be exactly at the same rate.
3423 We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
3424 for this call. Moving it adjusts timestamps for non-voice frames.
3425 We make the adjustment in the style of a moving average. Each time we
3426 adjust p->offset by 10% of the difference between our clock-derived
3427 timestamp and the predicted timestamp. That's why you see "10000"
3428 below even though IAX2 timestamps are in milliseconds.
3429 The use of a moving average avoids offset moving too radically.
3430 Generally, "adjust" roams back and forth around 0, with offset hardly
3431 changing at all. But if a consistent different starts to develop it
3432 will be eliminated over the course of 10 frames (200-300msecs)
3434 adjust
= (ms
- p
->nextpred
);
3436 p
->offset
= ast_tvsub(p
->offset
, ast_samp2tv(abs(adjust
), 10000));
3437 else if (adjust
> 0)
3438 p
->offset
= ast_tvadd(p
->offset
, ast_samp2tv(adjust
, 10000));
3441 p
->nextpred
= ms
; /*f->samples / 8;*/
3442 if (p
->nextpred
<= p
->lastsent
)
3443 p
->nextpred
= p
->lastsent
+ 3;
3447 /* in this case, just use the actual
3448 * time, since we're either way off
3449 * (shouldn't happen), or we're ending a
3450 * silent period -- and seed the next
3451 * predicted time. Also, round ms to the
3452 * next multiple of frame size (so our
3453 * silent periods are multiples of
3454 * frame size too) */
3456 if (iaxdebug
&& abs(ms
- p
->nextpred
) > MAX_TIMESTAMP_SKEW
)
3457 ast_log(LOG_DEBUG
, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
3458 abs(ms
- p
->nextpred
), MAX_TIMESTAMP_SKEW
);
3460 if (f
->samples
>= 8) /* check to make sure we dont core dump */
3462 int diff
= ms
% (f
->samples
/ 8);
3464 ms
+= f
->samples
/8 - diff
;
3471 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
3472 it's a genuine frame */
3474 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
3475 if (ms
<= p
->lastsent
)
3476 ms
= p
->lastsent
+ 3;
3477 } else if (abs(ms
- p
->lastsent
) <= MAX_TIMESTAMP_SKEW
) {
3478 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
3479 ms
= p
->lastsent
+ 3;
3485 p
->nextpred
= p
->nextpred
+ f
->samples
/ 8;
3489 static unsigned int calc_rxstamp(struct chan_iax2_pvt
*p
, unsigned int offset
)
3491 /* Returns where in "receive time" we are. That is, how many ms
3492 since we received (or would have received) the frame with timestamp 0 */
3496 #endif /* IAXTESTS */
3497 /* Setup rxcore if necessary */
3498 if (ast_tvzero(p
->rxcore
)) {
3499 p
->rxcore
= ast_tvnow();
3500 if (option_debug
&& iaxdebug
)
3501 ast_log(LOG_DEBUG
, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
3502 p
->callno
, (int)(p
->rxcore
.tv_sec
), (int)(p
->rxcore
.tv_usec
), offset
);
3503 p
->rxcore
= ast_tvsub(p
->rxcore
, ast_samp2tv(offset
, 1000));
3505 if (option_debug
&& iaxdebug
)
3506 ast_log(LOG_DEBUG
, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
3507 p
->callno
, (int)(p
->rxcore
.tv_sec
),(int)( p
->rxcore
.tv_usec
));
3511 ms
= ast_tvdiff_ms(ast_tvnow(), p
->rxcore
);
3514 if (!test_jitpct
|| ((100.0 * ast_random() / (RAND_MAX
+ 1.0)) < test_jitpct
)) {
3515 jit
= (int)((float)test_jit
* ast_random() / (RAND_MAX
+ 1.0));
3516 if ((int)(2.0 * ast_random() / (RAND_MAX
+ 1.0)))
3525 #endif /* IAXTESTS */
3529 static struct iax2_trunk_peer
*find_tpeer(struct sockaddr_in
*sin
, int fd
)
3531 struct iax2_trunk_peer
*tpeer
;
3533 /* Finds and locks trunk peer */
3534 ast_mutex_lock(&tpeerlock
);
3535 for (tpeer
= tpeers
; tpeer
; tpeer
= tpeer
->next
) {
3536 /* We don't lock here because tpeer->addr *never* changes */
3537 if (!inaddrcmp(&tpeer
->addr
, sin
)) {
3538 ast_mutex_lock(&tpeer
->lock
);
3543 if ((tpeer
= ast_calloc(1, sizeof(*tpeer
)))) {
3544 ast_mutex_init(&tpeer
->lock
);
3545 tpeer
->lastsent
= 9999;
3546 memcpy(&tpeer
->addr
, sin
, sizeof(tpeer
->addr
));
3547 tpeer
->trunkact
= ast_tvnow();
3548 ast_mutex_lock(&tpeer
->lock
);
3549 tpeer
->next
= tpeers
;
3553 setsockopt(tpeer
->sockfd
, SOL_SOCKET
, SO_NO_CHECK
, &nochecksums
, sizeof(nochecksums
));
3555 ast_log(LOG_DEBUG
, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer
->addr
.sin_addr
), ntohs(tpeer
->addr
.sin_port
));
3558 ast_mutex_unlock(&tpeerlock
);
3562 static int iax2_trunk_queue(struct chan_iax2_pvt
*pvt
, struct iax_frame
*fr
)
3564 struct ast_frame
*f
;
3565 struct iax2_trunk_peer
*tpeer
;
3567 struct ast_iax2_meta_trunk_entry
*met
;
3568 struct ast_iax2_meta_trunk_mini
*mtm
;
3571 tpeer
= find_tpeer(&pvt
->addr
, pvt
->sockfd
);
3573 if (tpeer
->trunkdatalen
+ f
->datalen
+ 4 >= tpeer
->trunkdataalloc
) {
3574 /* Need to reallocate space */
3575 if (tpeer
->trunkdataalloc
< MAX_TRUNKDATA
) {
3576 if (!(tmp
= ast_realloc(tpeer
->trunkdata
, tpeer
->trunkdataalloc
+ DEFAULT_TRUNKDATA
+ IAX2_TRUNK_PREFACE
))) {
3577 ast_mutex_unlock(&tpeer
->lock
);
3581 tpeer
->trunkdataalloc
+= DEFAULT_TRUNKDATA
;
3582 tpeer
->trunkdata
= tmp
;
3583 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
);
3585 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
));
3586 ast_mutex_unlock(&tpeer
->lock
);
3591 /* Append to meta frame */
3592 ptr
= tpeer
->trunkdata
+ IAX2_TRUNK_PREFACE
+ tpeer
->trunkdatalen
;
3593 if (ast_test_flag(&globalflags
, IAX_TRUNKTIMESTAMPS
)) {
3594 mtm
= (struct ast_iax2_meta_trunk_mini
*)ptr
;
3595 mtm
->len
= htons(f
->datalen
);
3596 mtm
->mini
.callno
= htons(pvt
->callno
);
3597 mtm
->mini
.ts
= htons(0xffff & fr
->ts
);
3598 ptr
+= sizeof(struct ast_iax2_meta_trunk_mini
);
3599 tpeer
->trunkdatalen
+= sizeof(struct ast_iax2_meta_trunk_mini
);
3601 met
= (struct ast_iax2_meta_trunk_entry
*)ptr
;
3602 /* Store call number and length in meta header */
3603 met
->callno
= htons(pvt
->callno
);
3604 met
->len
= htons(f
->datalen
);
3605 /* Advance pointers/decrease length past trunk entry header */
3606 ptr
+= sizeof(struct ast_iax2_meta_trunk_entry
);
3607 tpeer
->trunkdatalen
+= sizeof(struct ast_iax2_meta_trunk_entry
);
3609 /* Copy actual trunk data */
3610 memcpy(ptr
, f
->data
, f
->datalen
);
3611 tpeer
->trunkdatalen
+= f
->datalen
;
3614 ast_mutex_unlock(&tpeer
->lock
);
3619 static void build_enc_keys(const unsigned char *digest
, aes_encrypt_ctx
*ecx
, aes_decrypt_ctx
*dcx
)
3621 aes_encrypt_key128(digest
, ecx
);
3622 aes_decrypt_key128(digest
, dcx
);
3625 static void memcpy_decrypt(unsigned char *dst
, const unsigned char *src
, int len
, aes_decrypt_ctx
*dcx
)
3628 /* Debug with "fake encryption" */
3631 ast_log(LOG_WARNING
, "len should be multiple of 16, not %d!\n", len
);
3633 dst
[x
] = src
[x
] ^ 0xff;
3635 unsigned char lastblock
[16] = { 0 };
3638 aes_decrypt(src
, dst
, dcx
);
3640 dst
[x
] ^= lastblock
[x
];
3641 memcpy(lastblock
, src
, sizeof(lastblock
));
3649 static void memcpy_encrypt(unsigned char *dst
, const unsigned char *src
, int len
, aes_encrypt_ctx
*ecx
)
3652 /* Debug with "fake encryption" */
3655 ast_log(LOG_WARNING
, "len should be multiple of 16, not %d!\n", len
);
3657 dst
[x
] = src
[x
] ^ 0xff;
3659 unsigned char curblock
[16] = { 0 };
3663 curblock
[x
] ^= src
[x
];
3664 aes_encrypt(curblock
, dst
, ecx
);
3665 memcpy(curblock
, dst
, sizeof(curblock
));
3673 static int decode_frame(aes_decrypt_ctx
*dcx
, struct ast_iax2_full_hdr
*fh
, struct ast_frame
*f
, int *datalen
)
3676 unsigned char *workspace
;
3678 workspace
= alloca(*datalen
);
3679 memset(f
, 0, sizeof(*f
));
3680 if (ntohs(fh
->scallno
) & IAX_FLAG_FULL
) {
3681 struct ast_iax2_full_enc_hdr
*efh
= (struct ast_iax2_full_enc_hdr
*)fh
;
3682 if (*datalen
< 16 + sizeof(struct ast_iax2_full_hdr
))
3685 memcpy_decrypt(workspace
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
), dcx
);
3687 padding
= 16 + (workspace
[15] & 0xf);
3688 if (option_debug
&& iaxdebug
)
3689 ast_log(LOG_DEBUG
, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen
, padding
, workspace
[15]);
3690 if (*datalen
< padding
+ sizeof(struct ast_iax2_full_hdr
))
3693 *datalen
-= padding
;
3694 memcpy(efh
->encdata
, workspace
+ padding
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
));
3695 f
->frametype
= fh
->type
;
3696 if (f
->frametype
== AST_FRAME_VIDEO
) {
3697 f
->subclass
= uncompress_subclass(fh
->csub
& ~0x40) | ((fh
->csub
>> 6) & 0x1);
3699 f
->subclass
= uncompress_subclass(fh
->csub
);
3702 struct ast_iax2_mini_enc_hdr
*efh
= (struct ast_iax2_mini_enc_hdr
*)fh
;
3703 if (option_debug
&& iaxdebug
)
3704 ast_log(LOG_DEBUG
, "Decoding mini with length %d\n", *datalen
);
3705 if (*datalen
< 16 + sizeof(struct ast_iax2_mini_hdr
))
3708 memcpy_decrypt(workspace
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
), dcx
);
3709 padding
= 16 + (workspace
[15] & 0x0f);
3710 if (*datalen
< padding
+ sizeof(struct ast_iax2_mini_hdr
))
3712 *datalen
-= padding
;
3713 memcpy(efh
->encdata
, workspace
+ padding
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
));
3718 static int encrypt_frame(aes_encrypt_ctx
*ecx
, struct ast_iax2_full_hdr
*fh
, unsigned char *poo
, int *datalen
)
3721 unsigned char *workspace
;
3722 workspace
= alloca(*datalen
+ 32);
3725 if (ntohs(fh
->scallno
) & IAX_FLAG_FULL
) {
3726 struct ast_iax2_full_enc_hdr
*efh
= (struct ast_iax2_full_enc_hdr
*)fh
;
3727 if (option_debug
&& iaxdebug
)
3728 ast_log(LOG_DEBUG
, "Encoding full frame %d/%d with length %d\n", fh
->type
, fh
->csub
, *datalen
);
3729 padding
= 16 - ((*datalen
- sizeof(struct ast_iax2_full_enc_hdr
)) % 16);
3730 padding
= 16 + (padding
& 0xf);
3731 memcpy(workspace
, poo
, padding
);
3732 memcpy(workspace
+ padding
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
));
3733 workspace
[15] &= 0xf0;
3734 workspace
[15] |= (padding
& 0xf);
3735 if (option_debug
&& iaxdebug
)
3736 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]);
3737 *datalen
+= padding
;
3738 memcpy_encrypt(efh
->encdata
, workspace
, *datalen
- sizeof(struct ast_iax2_full_enc_hdr
), ecx
);
3739 if (*datalen
>= 32 + sizeof(struct ast_iax2_full_enc_hdr
))
3740 memcpy(poo
, workspace
+ *datalen
- 32, 32);
3742 struct ast_iax2_mini_enc_hdr
*efh
= (struct ast_iax2_mini_enc_hdr
*)fh
;
3743 if (option_debug
&& iaxdebug
)
3744 ast_log(LOG_DEBUG
, "Encoding mini frame with length %d\n", *datalen
);
3745 padding
= 16 - ((*datalen
- sizeof(struct ast_iax2_mini_enc_hdr
)) % 16);
3746 padding
= 16 + (padding
& 0xf);
3747 memcpy(workspace
, poo
, padding
);
3748 memcpy(workspace
+ padding
, efh
->encdata
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
));
3749 workspace
[15] &= 0xf0;
3750 workspace
[15] |= (padding
& 0x0f);
3751 *datalen
+= padding
;
3752 memcpy_encrypt(efh
->encdata
, workspace
, *datalen
- sizeof(struct ast_iax2_mini_enc_hdr
), ecx
);
3753 if (*datalen
>= 32 + sizeof(struct ast_iax2_mini_enc_hdr
))
3754 memcpy(poo
, workspace
+ *datalen
- 32, 32);
3759 static int decrypt_frame(int callno
, struct ast_iax2_full_hdr
*fh
, struct ast_frame
*f
, int *datalen
)
3762 if (!ast_test_flag(iaxs
[callno
], IAX_KEYPOPULATED
)) {
3763 /* Search for possible keys, given secrets */
3764 struct MD5Context md5
;
3765 unsigned char digest
[16];
3766 char *tmppw
, *stringp
;
3768 tmppw
= ast_strdupa(iaxs
[callno
]->secret
);
3770 while ((tmppw
= strsep(&stringp
, ";"))) {
3772 MD5Update(&md5
, (unsigned char *)iaxs
[callno
]->challenge
, strlen(iaxs
[callno
]->challenge
));
3773 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
3774 MD5Final(digest
, &md5
);
3775 build_enc_keys(digest
, &iaxs
[callno
]->ecx
, &iaxs
[callno
]->dcx
);
3776 res
= decode_frame(&iaxs
[callno
]->dcx
, fh
, f
, datalen
);
3778 ast_set_flag(iaxs
[callno
], IAX_KEYPOPULATED
);
3783 res
= decode_frame(&iaxs
[callno
]->dcx
, fh
, f
, datalen
);
3787 static int iax2_send(struct chan_iax2_pvt
*pvt
, struct ast_frame
*f
, unsigned int ts
, int seqno
, int now
, int transfer
, int final
)
3789 /* Queue a packet for delivery on a given private structure. Use "ts" for
3790 timestamp, or calculate if ts is 0. Send immediately without retransmission
3791 or delayed, with retransmission */
3792 struct ast_iax2_full_hdr
*fh
;
3793 struct ast_iax2_mini_hdr
*mh
;
3794 struct ast_iax2_video_hdr
*vh
;
3796 struct iax_frame fr2
;
3797 unsigned char buffer
[4096];
3799 struct iax_frame
*fr
;
3802 unsigned int lastsent
;
3806 ast_log(LOG_WARNING
, "No private structure for packet?\n");
3810 lastsent
= pvt
->lastsent
;
3812 /* Calculate actual timestamp */
3813 fts
= calc_timestamp(pvt
, ts
, f
);
3815 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
3816 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
3817 * increment the "predicted timestamps" for voice, if we're predecting */
3818 if(f
->frametype
== AST_FRAME_VOICE
&& f
->datalen
== 0)
3822 if ((ast_test_flag(pvt
, IAX_TRUNK
) ||
3823 (((fts
& 0xFFFF0000L
) == (lastsent
& 0xFFFF0000L
)) ||
3824 ((fts
& 0xFFFF0000L
) == ((lastsent
+ 0x10000) & 0xFFFF0000L
))))
3825 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
3826 (f
->frametype
== AST_FRAME_VOICE
)
3827 /* is a voice frame */ &&
3828 (f
->subclass
== pvt
->svoiceformat
)
3829 /* is the same type */ ) {
3830 /* Force immediate rather than delayed transmission */
3832 /* Mark that mini-style frame is appropriate */
3835 if (((fts
& 0xFFFF8000L
) == (lastsent
& 0xFFFF8000L
)) &&
3836 (f
->frametype
== AST_FRAME_VIDEO
) &&
3837 ((f
->subclass
& ~0x1) == pvt
->svideoformat
)) {
3841 /* Allocate an iax_frame */
3845 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
));
3847 ast_log(LOG_WARNING
, "Out of memory\n");
3850 /* Copy our prospective frame into our immediate or retransmitted wrapper */
3851 iax_frame_wrap(fr
, f
);
3854 fr
->callno
= pvt
->callno
;
3855 fr
->transfer
= transfer
;
3858 /* We need a full frame */
3862 fr
->oseqno
= pvt
->oseqno
++;
3863 fr
->iseqno
= pvt
->iseqno
;
3864 fh
= (struct ast_iax2_full_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_full_hdr
));
3865 fh
->scallno
= htons(fr
->callno
| IAX_FLAG_FULL
);
3866 fh
->ts
= htonl(fr
->ts
);
3867 fh
->oseqno
= fr
->oseqno
;
3871 fh
->iseqno
= fr
->iseqno
;
3872 /* Keep track of the last thing we've acknowledged */
3874 pvt
->aseqno
= fr
->iseqno
;
3875 fh
->type
= fr
->af
.frametype
& 0xFF;
3876 if (fr
->af
.frametype
== AST_FRAME_VIDEO
)
3877 fh
->csub
= compress_subclass(fr
->af
.subclass
& ~0x1) | ((fr
->af
.subclass
& 0x1) << 6);
3879 fh
->csub
= compress_subclass(fr
->af
.subclass
);
3881 fr
->dcallno
= pvt
->transfercallno
;
3883 fr
->dcallno
= pvt
->peercallno
;
3884 fh
->dcallno
= htons(fr
->dcallno
);
3885 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_full_hdr
);
3888 /* Retry after 2x the ping time has passed */
3889 fr
->retrytime
= pvt
->pingtime
* 2;
3890 if (fr
->retrytime
< MIN_RETRY_TIME
)
3891 fr
->retrytime
= MIN_RETRY_TIME
;
3892 if (fr
->retrytime
> MAX_RETRY_TIME
)
3893 fr
->retrytime
= MAX_RETRY_TIME
;
3894 /* Acks' don't get retried */
3895 if ((f
->frametype
== AST_FRAME_IAX
) && (f
->subclass
== IAX_COMMAND_ACK
))
3897 else if (f
->frametype
== AST_FRAME_VOICE
)
3898 pvt
->svoiceformat
= f
->subclass
;
3899 else if (f
->frametype
== AST_FRAME_VIDEO
)
3900 pvt
->svideoformat
= f
->subclass
& ~0x1;
3901 if (ast_test_flag(pvt
, IAX_ENCRYPTED
)) {
3902 if (ast_test_flag(pvt
, IAX_KEYPOPULATED
)) {
3905 iax_showframe(fr
, NULL
, 2, &pvt
->transfer
, fr
->datalen
- sizeof(struct ast_iax2_full_hdr
));
3907 iax_showframe(fr
, NULL
, 2, &pvt
->addr
, fr
->datalen
- sizeof(struct ast_iax2_full_hdr
));
3909 encrypt_frame(&pvt
->ecx
, fh
, pvt
->semirand
, &fr
->datalen
);
3911 ast_log(LOG_WARNING
, "Supposed to send packet encrypted, but no key?\n");
3915 res
= send_packet(fr
);
3917 res
= iax2_transmit(fr
);
3919 if (ast_test_flag(pvt
, IAX_TRUNK
)) {
3920 iax2_trunk_queue(pvt
, fr
);
3922 } else if (fr
->af
.frametype
== AST_FRAME_VIDEO
) {
3923 /* Video frame have no sequence number */
3926 vh
= (struct ast_iax2_video_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_video_hdr
));
3928 vh
->callno
= htons(0x8000 | fr
->callno
);
3929 vh
->ts
= htons((fr
->ts
& 0x7FFF) | (fr
->af
.subclass
& 0x1 ? 0x8000 : 0));
3930 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_video_hdr
);
3933 res
= send_packet(fr
);
3935 /* Mini-frames have no sequence number */
3938 /* Mini frame will do */
3939 mh
= (struct ast_iax2_mini_hdr
*)(fr
->af
.data
- sizeof(struct ast_iax2_mini_hdr
));
3940 mh
->callno
= htons(fr
->callno
);
3941 mh
->ts
= htons(fr
->ts
& 0xFFFF);
3942 fr
->datalen
= fr
->af
.datalen
+ sizeof(struct ast_iax2_mini_hdr
);
3945 if (pvt
->transferring
== TRANSFER_MEDIAPASS
)
3947 if (ast_test_flag(pvt
, IAX_ENCRYPTED
)) {
3948 if (ast_test_flag(pvt
, IAX_KEYPOPULATED
)) {
3949 encrypt_frame(&pvt
->ecx
, (struct ast_iax2_full_hdr
*)mh
, pvt
->semirand
, &fr
->datalen
);
3951 ast_log(LOG_WARNING
, "Supposed to send packet encrypted, but no key?\n");
3953 res
= send_packet(fr
);
3959 static int iax2_show_users(int fd
, int argc
, char *argv
[])
3962 int havepattern
= 0;
3964 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
3965 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
3967 struct iax2_user
*user
= NULL
;
3973 if (!strcasecmp(argv
[3], "like")) {
3974 if (regcomp(®exbuf
, argv
[4], REG_EXTENDED
| REG_NOSUB
))
3975 return RESULT_SHOWUSAGE
;
3978 return RESULT_SHOWUSAGE
;
3982 return RESULT_SHOWUSAGE
;
3985 ast_cli(fd
, FORMAT
, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
3986 AST_LIST_LOCK(&users
);
3987 AST_LIST_TRAVERSE(&users
, user
, entry
) {
3988 if (havepattern
&& regexec(®exbuf
, user
->name
, 0, NULL
, 0))
3991 if (!ast_strlen_zero(user
->secret
)) {
3992 ast_copy_string(auth
,user
->secret
,sizeof(auth
));
3993 } else if (!ast_strlen_zero(user
->inkeys
)) {
3994 snprintf(auth
, sizeof(auth
), "Key: %-15.15s ", user
->inkeys
);
3996 ast_copy_string(auth
, "-no secret-", sizeof(auth
));
3998 if(ast_test_flag(user
,IAX_CODEC_NOCAP
))
4000 else if(ast_test_flag(user
,IAX_CODEC_NOPREFS
))
4003 pstr
= ast_test_flag(user
,IAX_CODEC_USER_FIRST
) ? "Caller" : "Host";
4005 ast_cli(fd
, FORMAT2
, user
->name
, auth
, user
->authmethods
,
4006 user
->contexts
? user
->contexts
->context
: context
,
4007 user
->ha
? "Yes" : "No", pstr
);
4010 AST_LIST_UNLOCK(&users
);
4015 return RESULT_SUCCESS
;
4020 static int __iax2_show_peers(int manager
, int fd
, struct mansession
*s
, int argc
, char *argv
[])
4023 int havepattern
= 0;
4024 int total_peers
= 0;
4025 int online_peers
= 0;
4026 int offline_peers
= 0;
4027 int unmonitored_peers
= 0;
4029 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
4030 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
4032 struct iax2_peer
*peer
= NULL
;
4034 int registeredonly
=0;
4035 char *term
= manager
? "\r\n" : "\n";
4039 if (!strcasecmp(argv
[3], "registered"))
4042 return RESULT_SHOWUSAGE
;
4043 if (!strcasecmp(argv
[4], "like")) {
4044 if (regcomp(®exbuf
, argv
[5], REG_EXTENDED
| REG_NOSUB
))
4045 return RESULT_SHOWUSAGE
;
4048 return RESULT_SHOWUSAGE
;
4051 if (!strcasecmp(argv
[3], "like")) {
4052 if (regcomp(®exbuf
, argv
[4], REG_EXTENDED
| REG_NOSUB
))
4053 return RESULT_SHOWUSAGE
;
4056 return RESULT_SHOWUSAGE
;
4059 if (!strcasecmp(argv
[3], "registered"))
4062 return RESULT_SHOWUSAGE
;
4067 return RESULT_SHOWUSAGE
;
4072 astman_append(s
, FORMAT2
, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term
);
4074 ast_cli(fd
, FORMAT2
, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term
);
4076 AST_LIST_LOCK(&peers
);
4077 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
4083 if (registeredonly
&& !peer
->addr
.sin_addr
.s_addr
)
4085 if (havepattern
&& regexec(®exbuf
, peer
->name
, 0, NULL
, 0))
4088 if (!ast_strlen_zero(peer
->username
))
4089 snprintf(name
, sizeof(name
), "%s/%s", peer
->name
, peer
->username
);
4091 ast_copy_string(name
, peer
->name
, sizeof(name
));
4093 retstatus
= peer_status(peer
, status
, sizeof(status
));
4096 else if (!retstatus
)
4099 unmonitored_peers
++;
4101 ast_copy_string(nm
, ast_inet_ntoa(peer
->mask
), sizeof(nm
));
4103 snprintf(srch
, sizeof(srch
), FORMAT
, name
,
4104 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "(Unspecified)",
4105 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4107 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4108 peer
->encmethods
? "(E)" : " ", status
, term
);
4111 astman_append(s
, 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
);
4118 ast_cli(fd
, FORMAT
, name
,
4119 peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "(Unspecified)",
4120 ast_test_flag(peer
, IAX_DYNAMIC
) ? "(D)" : "(S)",
4122 ntohs(peer
->addr
.sin_port
), ast_test_flag(peer
, IAX_TRUNK
) ? "(T)" : " ",
4123 peer
->encmethods
? "(E)" : " ", status
, term
);
4126 AST_LIST_UNLOCK(&peers
);
4129 astman_append(s
,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers
, online_peers
, offline_peers
, unmonitored_peers
, term
);
4131 ast_cli(fd
,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers
, online_peers
, offline_peers
, unmonitored_peers
, term
);
4136 return RESULT_SUCCESS
;
4141 static int iax2_show_threads(int fd
, int argc
, char *argv
[])
4143 struct iax2_thread
*thread
= NULL
;
4145 int threadcount
= 0, dynamiccount
= 0;
4149 return RESULT_SHOWUSAGE
;
4151 ast_cli(fd
, "IAX2 Thread Information\n");
4153 ast_cli(fd
, "Idle Threads:\n");
4154 AST_LIST_LOCK(&idle_list
);
4155 AST_LIST_TRAVERSE(&idle_list
, thread
, list
) {
4156 #ifdef DEBUG_SCHED_MULTITHREAD
4157 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4158 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4160 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d\n",
4161 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4165 AST_LIST_UNLOCK(&idle_list
);
4166 ast_cli(fd
, "Active Threads:\n");
4167 AST_LIST_LOCK(&active_list
);
4168 AST_LIST_TRAVERSE(&active_list
, thread
, list
) {
4169 if (thread
->type
== IAX_TYPE_DYNAMIC
)
4173 #ifdef DEBUG_SCHED_MULTITHREAD
4174 ast_cli(fd
, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
4175 type
, thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4177 ast_cli(fd
, "Thread %c%d: state=%d, update=%d, actions=%d\n",
4178 type
, thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4182 AST_LIST_UNLOCK(&active_list
);
4183 ast_cli(fd
, "Dynamic Threads:\n");
4184 AST_LIST_LOCK(&dynamic_list
);
4185 AST_LIST_TRAVERSE(&dynamic_list
, thread
, list
) {
4186 #ifdef DEBUG_SCHED_MULTITHREAD
4187 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4188 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
, thread
->curfunc
);
4190 ast_cli(fd
, "Thread %d: state=%d, update=%d, actions=%d\n",
4191 thread
->threadnum
, thread
->iostate
, (int)(t
- thread
->checktime
), thread
->actions
);
4195 AST_LIST_UNLOCK(&dynamic_list
);
4196 ast_cli(fd
, "%d of %d threads accounted for with %d dynamic threads\n", threadcount
, iaxthreadcount
, dynamiccount
);
4197 return RESULT_SUCCESS
;
4200 static int iax2_show_peers(int fd
, int argc
, char *argv
[])
4202 return __iax2_show_peers(0, fd
, NULL
, argc
, argv
);
4204 static int manager_iax2_show_netstats(struct mansession
*s
, const struct message
*m
)
4206 ast_cli_netstats(s
, -1, 0);
4207 astman_append(s
, "\r\n");
4208 return RESULT_SUCCESS
;
4211 static int iax2_show_firmware(int fd
, int argc
, char *argv
[])
4213 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
4214 #if !defined(__FreeBSD__)
4215 #define FORMAT "%-15.15s %-15d %-15d\n"
4216 #else /* __FreeBSD__ */
4217 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */
4218 #endif /* __FreeBSD__ */
4219 struct iax_firmware
*cur
;
4220 if ((argc
!= 3) && (argc
!= 4))
4221 return RESULT_SHOWUSAGE
;
4222 ast_mutex_lock(&waresl
.lock
);
4224 ast_cli(fd
, FORMAT2
, "Device", "Version", "Size");
4225 for (cur
= waresl
.wares
;cur
;cur
= cur
->next
) {
4226 if ((argc
== 3) || (!strcasecmp(argv
[3], (char *)cur
->fwh
->devname
)))
4227 ast_cli(fd
, FORMAT
, cur
->fwh
->devname
, ntohs(cur
->fwh
->version
),
4228 (int)ntohl(cur
->fwh
->datalen
));
4230 ast_mutex_unlock(&waresl
.lock
);
4231 return RESULT_SUCCESS
;
4236 /* JDG: callback to display iax peers in manager */
4237 static int manager_iax2_show_peers(struct mansession
*s
, const struct message
*m
)
4239 char *a
[] = { "iax2", "show", "users" };
4241 const char *id
= astman_get_header(m
,"ActionID");
4243 if (!ast_strlen_zero(id
))
4244 astman_append(s
, "ActionID: %s\r\n",id
);
4245 ret
= __iax2_show_peers(1, -1, s
, 3, a
);
4246 astman_append(s
, "\r\n\r\n" );
4250 static char *regstate2str(int regstate
)
4253 case REG_STATE_UNREGISTERED
:
4254 return "Unregistered";
4255 case REG_STATE_REGSENT
:
4256 return "Request Sent";
4257 case REG_STATE_AUTHSENT
:
4258 return "Auth. Sent";
4259 case REG_STATE_REGISTERED
:
4260 return "Registered";
4261 case REG_STATE_REJECTED
:
4263 case REG_STATE_TIMEOUT
:
4265 case REG_STATE_NOAUTH
:
4266 return "No Authentication";
4272 static int iax2_show_registry(int fd
, int argc
, char *argv
[])
4274 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
4275 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
4276 struct iax2_registry
*reg
= NULL
;
4281 return RESULT_SHOWUSAGE
;
4282 ast_cli(fd
, FORMAT2
, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
4283 AST_LIST_LOCK(®istrations
);
4284 AST_LIST_TRAVERSE(®istrations
, reg
, entry
) {
4285 snprintf(host
, sizeof(host
), "%s:%d", ast_inet_ntoa(reg
->addr
.sin_addr
), ntohs(reg
->addr
.sin_port
));
4286 if (reg
->us
.sin_addr
.s_addr
)
4287 snprintf(perceived
, sizeof(perceived
), "%s:%d", ast_inet_ntoa(reg
->us
.sin_addr
), ntohs(reg
->us
.sin_port
));
4289 ast_copy_string(perceived
, "<Unregistered>", sizeof(perceived
));
4290 ast_cli(fd
, FORMAT
, host
,
4291 (reg
->dnsmgr
) ? "Y" : "N",
4292 reg
->username
, perceived
, reg
->refresh
, regstate2str(reg
->regstate
));
4294 AST_LIST_UNLOCK(®istrations
);
4295 return RESULT_SUCCESS
;
4300 static int iax2_show_channels(int fd
, int argc
, char *argv
[])
4302 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
4303 #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"
4304 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
4309 return RESULT_SHOWUSAGE
;
4310 ast_cli(fd
, FORMAT2
, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
4311 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
4312 ast_mutex_lock(&iaxsl
[x
]);
4314 int lag
, jitter
, localdelay
;
4317 if(ast_test_flag(iaxs
[x
], IAX_USEJITTERBUF
)) {
4318 jb_getinfo(iaxs
[x
]->jb
, &jbinfo
);
4319 jitter
= jbinfo
.jitter
;
4320 localdelay
= jbinfo
.current
- jbinfo
.min
;
4325 lag
= iaxs
[x
]->remote_rr
.delay
;
4327 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4328 ast_inet_ntoa(iaxs
[x
]->addr
.sin_addr
),
4329 S_OR(iaxs
[x
]->username
, "(None)"),
4330 iaxs
[x
]->callno
, iaxs
[x
]->peercallno
,
4331 iaxs
[x
]->oseqno
, iaxs
[x
]->iseqno
,
4335 ast_getformatname(iaxs
[x
]->voiceformat
) );
4338 ast_mutex_unlock(&iaxsl
[x
]);
4340 ast_cli(fd
, "%d active IAX channel%s\n", numchans
, (numchans
!= 1) ? "s" : "");
4341 return RESULT_SUCCESS
;
4347 static int ast_cli_netstats(struct mansession
*s
, int fd
, int limit_fmt
)
4351 for (x
=0;x
<IAX_MAX_CALLS
;x
++) {
4352 ast_mutex_lock(&iaxsl
[x
]);
4354 int localjitter
, localdelay
, locallost
, locallosspct
, localdropped
, localooo
;
4358 if(ast_test_flag(iaxs
[x
], IAX_USEJITTERBUF
)) {
4359 jb_getinfo(iaxs
[x
]->jb
, &jbinfo
);
4360 localjitter
= jbinfo
.jitter
;
4361 localdelay
= jbinfo
.current
- jbinfo
.min
;
4362 locallost
= jbinfo
.frames_lost
;
4363 locallosspct
= jbinfo
.losspct
/1000;
4364 localdropped
= jbinfo
.frames_dropped
;
4365 localooo
= jbinfo
.frames_ooo
;
4375 fmt
= "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
4377 fmt
= "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
4380 astman_append(s
, fmt
,
4381 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4389 iaxs
[x
]->frames_received
/1000,
4390 iaxs
[x
]->remote_rr
.jitter
,
4391 iaxs
[x
]->remote_rr
.delay
,
4392 iaxs
[x
]->remote_rr
.losscnt
,
4393 iaxs
[x
]->remote_rr
.losspct
,
4394 iaxs
[x
]->remote_rr
.dropped
,
4395 iaxs
[x
]->remote_rr
.ooo
,
4396 iaxs
[x
]->remote_rr
.packets
/1000);
4399 iaxs
[x
]->owner
? iaxs
[x
]->owner
->name
: "(None)",
4407 iaxs
[x
]->frames_received
/1000,
4408 iaxs
[x
]->remote_rr
.jitter
,
4409 iaxs
[x
]->remote_rr
.delay
,
4410 iaxs
[x
]->remote_rr
.losscnt
,
4411 iaxs
[x
]->remote_rr
.losspct
,
4412 iaxs
[x
]->remote_rr
.dropped
,
4413 iaxs
[x
]->remote_rr
.ooo
,
4414 iaxs
[x
]->remote_rr
.packets
/1000
4418 ast_mutex_unlock(&iaxsl
[x
]);
4423 static int iax2_show_netstats(int fd
, int argc
, char *argv
[])
4427 return RESULT_SHOWUSAGE
;
4428 ast_cli(fd
, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
4429 ast_cli(fd
, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
4430 numchans
= ast_cli_netstats(NULL
, fd
, 1);
4431 ast_cli(fd
, "%d active IAX channel%s\n", numchans
, (numchans
!= 1) ? "s" : "");
4432 return RESULT_SUCCESS
;
4435 static int iax2_do_debug(int fd
, int argc
, char *argv
[])
4437 if (argc
< 2 || argc
> 3)
4438 return RESULT_SHOWUSAGE
;
4440 ast_cli(fd
, "IAX2 Debugging Enabled\n");
4441 return RESULT_SUCCESS
;
4444 static int iax2_do_trunk_debug(int fd
, int argc
, char *argv
[])
4446 if (argc
< 3 || argc
> 4)
4447 return RESULT_SHOWUSAGE
;
4449 ast_cli(fd
, "IAX2 Trunk Debug Requested\n");
4450 return RESULT_SUCCESS
;
4453 static int iax2_do_jb_debug(int fd
, int argc
, char *argv
[])
4455 if (argc
< 3 || argc
> 4)
4456 return RESULT_SHOWUSAGE
;
4457 jb_setoutput(jb_error_output
, jb_warning_output
, jb_debug_output
);
4458 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Enabled\n");
4459 return RESULT_SUCCESS
;
4462 static int iax2_no_debug(int fd
, int argc
, char *argv
[])
4464 if (argc
< 3 || argc
> 4)
4465 return RESULT_SHOWUSAGE
;
4467 ast_cli(fd
, "IAX2 Debugging Disabled\n");
4468 return RESULT_SUCCESS
;
4471 static int iax2_no_trunk_debug(int fd
, int argc
, char *argv
[])
4473 if (argc
< 4 || argc
> 5)
4474 return RESULT_SHOWUSAGE
;
4476 ast_cli(fd
, "IAX2 Trunk Debugging Disabled\n");
4477 return RESULT_SUCCESS
;
4480 static int iax2_no_jb_debug(int fd
, int argc
, char *argv
[])
4482 if (argc
< 4 || argc
> 5)
4483 return RESULT_SHOWUSAGE
;
4484 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
4485 jb_debug_output("\n");
4486 ast_cli(fd
, "IAX2 Jitterbuffer Debugging Disabled\n");
4487 return RESULT_SUCCESS
;
4490 static int iax2_write(struct ast_channel
*c
, struct ast_frame
*f
)
4492 unsigned short callno
= PTR_TO_CALLNO(c
->tech_pvt
);
4494 ast_mutex_lock(&iaxsl
[callno
]);
4496 /* If there's an outstanding error, return failure now */
4497 if (!iaxs
[callno
]->error
) {
4498 if (ast_test_flag(iaxs
[callno
], IAX_ALREADYGONE
))
4500 /* Don't waste bandwidth sending null frames */
4501 else if (f
->frametype
== AST_FRAME_NULL
)
4503 else if ((f
->frametype
== AST_FRAME_VOICE
) && ast_test_flag(iaxs
[callno
], IAX_QUELCH
))
4505 else if (!ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_STARTED
))
4508 /* Simple, just queue for transmission */
4509 res
= iax2_send(iaxs
[callno
], f
, 0, -1, 0, 0, 0);
4511 ast_log(LOG_DEBUG
, "Write error: %s\n", strerror(errno
));
4514 /* If it's already gone, just return */
4515 ast_mutex_unlock(&iaxsl
[callno
]);
4519 static int __send_command(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
,
4520 int now
, int transfer
, int final
)
4522 struct ast_frame f
= { 0, };
4525 f
.subclass
= command
;
4526 f
.datalen
= datalen
;
4527 f
.src
= __FUNCTION__
;
4528 f
.data
= (void *) data
;
4530 return iax2_send(i
, &f
, ts
, seqno
, now
, transfer
, final
);
4533 static int send_command(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4535 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 0, 0, 0);
4538 static int send_command_locked(unsigned short callno
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
, int seqno
)
4541 ast_mutex_lock(&iaxsl
[callno
]);
4542 res
= send_command(iaxs
[callno
], type
, command
, ts
, data
, datalen
, seqno
);
4543 ast_mutex_unlock(&iaxsl
[callno
]);
4547 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
)
4549 /* It is assumed that the callno has already been locked */
4550 iax2_predestroy(i
->callno
);
4551 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 0, 0, 1);
4554 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
)
4556 return __send_command(i
, type
, command
, ts
, data
, datalen
, seqno
, 1, 0, 0);
4559 static int send_command_transfer(struct chan_iax2_pvt
*i
, char type
, int command
, unsigned int ts
, const unsigned char *data
, int datalen
)
4561 return __send_command(i
, type
, command
, ts
, data
, datalen
, 0, 0, 1, 0);
4564 static int apply_context(struct iax2_context
*con
, const char *context
)
4567 if (!strcmp(con
->context
, context
) || !strcmp(con
->context
, "*"))
4575 static int check_access(int callno
, struct sockaddr_in
*sin
, struct iax_ies
*ies
)
4577 /* Start pessimistic */
4580 struct iax2_user
*user
= NULL
, *best
= NULL
;
4582 int gotcapability
= 0;
4583 struct ast_variable
*v
= NULL
, *tmpvar
= NULL
;
4587 if (ies
->called_number
)
4588 ast_string_field_set(iaxs
[callno
], exten
, ies
->called_number
);
4589 if (ies
->calling_number
) {
4590 ast_shrink_phone_number(ies
->calling_number
);
4591 ast_string_field_set(iaxs
[callno
], cid_num
, ies
->calling_number
);
4593 if (ies
->calling_name
)
4594 ast_string_field_set(iaxs
[callno
], cid_name
, ies
->calling_name
);
4595 if (ies
->calling_ani
)
4596 ast_string_field_set(iaxs
[callno
], ani
, ies
->calling_ani
);
4598 ast_string_field_set(iaxs
[callno
], dnid
, ies
->dnid
);
4600 ast_string_field_set(iaxs
[callno
], rdnis
, ies
->rdnis
);
4601 if (ies
->called_context
)
4602 ast_string_field_set(iaxs
[callno
], context
, ies
->called_context
);
4604 ast_string_field_set(iaxs
[callno
], language
, ies
->language
);
4606 ast_string_field_set(iaxs
[callno
], username
, ies
->username
);
4607 if (ies
->calling_ton
> -1)
4608 iaxs
[callno
]->calling_ton
= ies
->calling_ton
;
4609 if (ies
->calling_tns
> -1)
4610 iaxs
[callno
]->calling_tns
= ies
->calling_tns
;
4611 if (ies
->calling_pres
> -1)
4612 iaxs
[callno
]->calling_pres
= ies
->calling_pres
;
4614 iaxs
[callno
]->peerformat
= ies
->format
;
4616 iaxs
[callno
]->peeradsicpe
= ies
->adsicpe
;
4617 if (ies
->capability
) {
4619 iaxs
[callno
]->peercapability
= ies
->capability
;
4622 version
= ies
->version
;
4624 /* Use provided preferences until told otherwise for actual preferences */
4625 if(ies
->codec_prefs
) {
4626 ast_codec_pref_convert(&iaxs
[callno
]->rprefs
, ies
->codec_prefs
, 32, 0);
4627 ast_codec_pref_convert(&iaxs
[callno
]->prefs
, ies
->codec_prefs
, 32, 0);
4631 iaxs
[callno
]->peercapability
= iaxs
[callno
]->peerformat
;
4632 if (version
> IAX_PROTO_VERSION
) {
4633 ast_log(LOG_WARNING
, "Peer '%s' has too new a protocol version (%d) for me\n",
4634 ast_inet_ntoa(sin
->sin_addr
), version
);
4637 /* Search the userlist for a compatible entry, and fill in the rest */
4638 AST_LIST_LOCK(&users
);
4639 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4640 if ((ast_strlen_zero(iaxs
[callno
]->username
) || /* No username specified */
4641 !strcmp(iaxs
[callno
]->username
, user
->name
)) /* Or this username specified */
4642 && ast_apply_ha(user
->ha
, sin
) /* Access is permitted from this IP */
4643 && (ast_strlen_zero(iaxs
[callno
]->context
) || /* No context specified */
4644 apply_context(user
->contexts
, iaxs
[callno
]->context
))) { /* Context is permitted */
4645 if (!ast_strlen_zero(iaxs
[callno
]->username
)) {
4646 /* Exact match, stop right now. */
4649 } else if (ast_strlen_zero(user
->secret
) && ast_strlen_zero(user
->inkeys
)) {
4650 /* No required authentication */
4652 /* There was host authentication and we passed, bonus! */
4653 if (bestscore
< 4) {
4658 /* No host access, but no secret, either, not bad */
4659 if (bestscore
< 3) {
4666 /* Authentication, but host access too, eh, it's something.. */
4667 if (bestscore
< 2) {
4672 /* Authentication and no host access... This is our baseline */
4673 if (bestscore
< 1) {
4681 AST_LIST_UNLOCK(&users
);
4683 if (!user
&& !ast_strlen_zero(iaxs
[callno
]->username
)) {
4684 user
= realtime_user(iaxs
[callno
]->username
);
4685 if (user
&& !ast_strlen_zero(iaxs
[callno
]->context
) && /* No context specified */
4686 !apply_context(user
->contexts
, iaxs
[callno
]->context
)) { /* Context is permitted */
4692 /* We found our match (use the first) */
4694 for (v
= user
->vars
; v
; v
= v
->next
) {
4695 if((tmpvar
= ast_variable_new(v
->name
, v
->value
))) {
4696 tmpvar
->next
= iaxs
[callno
]->vars
;
4697 iaxs
[callno
]->vars
= tmpvar
;
4700 /* If a max AUTHREQ restriction is in place, activate it */
4701 if (user
->maxauthreq
> 0)
4702 ast_set_flag(iaxs
[callno
], IAX_MAXAUTHREQ
);
4703 iaxs
[callno
]->prefs
= user
->prefs
;
4704 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_USER_FIRST
);
4705 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_NOPREFS
);
4706 ast_copy_flags(iaxs
[callno
], user
, IAX_CODEC_NOCAP
);
4707 iaxs
[callno
]->encmethods
= user
->encmethods
;
4708 /* Store the requested username if not specified */
4709 if (ast_strlen_zero(iaxs
[callno
]->username
))
4710 ast_string_field_set(iaxs
[callno
], username
, user
->name
);
4711 /* Store whether this is a trunked call, too, of course, and move if appropriate */
4712 ast_copy_flags(iaxs
[callno
], user
, IAX_TRUNK
);
4713 iaxs
[callno
]->capability
= user
->capability
;
4714 /* And use the default context */
4715 if (ast_strlen_zero(iaxs
[callno
]->context
)) {
4717 ast_string_field_set(iaxs
[callno
], context
, user
->contexts
->context
);
4719 ast_string_field_set(iaxs
[callno
], context
, context
);
4721 /* And any input keys */
4722 ast_string_field_set(iaxs
[callno
], inkeys
, user
->inkeys
);
4723 /* And the permitted authentication methods */
4724 iaxs
[callno
]->authmethods
= user
->authmethods
;
4725 iaxs
[callno
]->adsi
= user
->adsi
;
4726 /* If they have callerid, override the given caller id. Always store the ANI */
4727 if (!ast_strlen_zero(iaxs
[callno
]->cid_num
) || !ast_strlen_zero(iaxs
[callno
]->cid_name
)) {
4728 if (ast_test_flag(user
, IAX_HASCALLERID
)) {
4729 iaxs
[callno
]->calling_tns
= 0;
4730 iaxs
[callno
]->calling_ton
= 0;
4731 ast_string_field_set(iaxs
[callno
], cid_num
, user
->cid_num
);
4732 ast_string_field_set(iaxs
[callno
], cid_name
, user
->cid_name
);
4733 iaxs
[callno
]->calling_pres
= AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN
;
4735 if (ast_strlen_zero(iaxs
[callno
]->ani
))
4736 ast_string_field_set(iaxs
[callno
], ani
, user
->cid_num
);
4738 iaxs
[callno
]->calling_pres
= AST_PRES_NUMBER_NOT_AVAILABLE
;
4740 if (!ast_strlen_zero(user
->accountcode
))
4741 ast_string_field_set(iaxs
[callno
], accountcode
, user
->accountcode
);
4742 if (!ast_strlen_zero(user
->mohinterpret
))
4743 ast_string_field_set(iaxs
[callno
], mohinterpret
, user
->mohinterpret
);
4744 if (!ast_strlen_zero(user
->mohsuggest
))
4745 ast_string_field_set(iaxs
[callno
], mohsuggest
, user
->mohsuggest
);
4747 iaxs
[callno
]->amaflags
= user
->amaflags
;
4748 if (!ast_strlen_zero(user
->language
))
4749 ast_string_field_set(iaxs
[callno
], language
, user
->language
);
4750 ast_copy_flags(iaxs
[callno
], user
, IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
4751 /* Keep this check last */
4752 if (!ast_strlen_zero(user
->dbsecret
)) {
4753 char *family
, *key
=NULL
;
4755 family
= ast_strdupa(user
->dbsecret
);
4756 key
= strchr(family
, '/');
4761 if (!key
|| ast_db_get(family
, key
, buf
, sizeof(buf
)))
4762 ast_log(LOG_WARNING
, "Unable to retrieve database password for family/key '%s'!\n", user
->dbsecret
);
4764 ast_string_field_set(iaxs
[callno
], secret
, buf
);
4766 ast_string_field_set(iaxs
[callno
], secret
, user
->secret
);
4767 if (ast_test_flag(user
, IAX_TEMPONLY
))
4771 ast_set2_flag(iaxs
[callno
], iax2_getpeertrunk(*sin
), IAX_TRUNK
);
4775 static int raw_hangup(struct sockaddr_in
*sin
, unsigned short src
, unsigned short dst
, int sockfd
)
4777 struct ast_iax2_full_hdr fh
;
4778 fh
.scallno
= htons(src
| IAX_FLAG_FULL
);
4779 fh
.dcallno
= htons(dst
);
4783 fh
.type
= AST_FRAME_IAX
;
4784 fh
.csub
= compress_subclass(IAX_COMMAND_INVAL
);
4786 iax_showframe(NULL
, &fh
, 0, sin
, 0);
4790 ast_log(LOG_DEBUG
, "Raw Hangup %s:%d, src=%d, dst=%d\n",
4791 ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), src
, dst
);
4792 return sendto(sockfd
, &fh
, sizeof(fh
), 0, (struct sockaddr
*)sin
, sizeof(*sin
));
4795 static void merge_encryption(struct chan_iax2_pvt
*p
, unsigned int enc
)
4797 /* Select exactly one common encryption if there are any */
4798 p
->encmethods
&= enc
;
4799 if (p
->encmethods
) {
4800 if (p
->encmethods
& IAX_ENCRYPT_AES128
)
4801 p
->encmethods
= IAX_ENCRYPT_AES128
;
4807 static int authenticate_request(struct chan_iax2_pvt
*p
)
4809 struct iax2_user
*user
= NULL
;
4810 struct iax_ie_data ied
;
4811 int res
= -1, authreq_restrict
= 0;
4814 memset(&ied
, 0, sizeof(ied
));
4816 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
4817 if (ast_test_flag(p
, IAX_MAXAUTHREQ
)) {
4818 AST_LIST_LOCK(&users
);
4819 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4820 if (!strcmp(user
->name
, p
->username
)) {
4821 if (user
->curauthreq
== user
->maxauthreq
)
4822 authreq_restrict
= 1;
4828 AST_LIST_UNLOCK(&users
);
4831 /* If the AUTHREQ limit test failed, send back an error */
4832 if (authreq_restrict
) {
4833 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Unauthenticated call limit reached");
4834 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_CALL_REJECTED
);
4835 send_command_final(p
, AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied
.buf
, ied
.pos
, -1);
4839 iax_ie_append_short(&ied
, IAX_IE_AUTHMETHODS
, p
->authmethods
);
4840 if (p
->authmethods
& (IAX_AUTH_MD5
| IAX_AUTH_RSA
)) {
4841 snprintf(challenge
, sizeof(challenge
), "%d", (int)ast_random());
4842 ast_string_field_set(p
, challenge
, challenge
);
4843 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
4844 iax_ie_append_str(&ied
, IAX_IE_CHALLENGE
, p
->challenge
);
4847 iax_ie_append_short(&ied
, IAX_IE_ENCRYPTION
, p
->encmethods
);
4849 iax_ie_append_str(&ied
,IAX_IE_USERNAME
, p
->username
);
4851 res
= send_command(p
, AST_FRAME_IAX
, IAX_COMMAND_AUTHREQ
, 0, ied
.buf
, ied
.pos
, -1);
4854 ast_set_flag(p
, IAX_ENCRYPTED
);
4859 static int authenticate_verify(struct chan_iax2_pvt
*p
, struct iax_ies
*ies
)
4861 char requeststr
[256];
4862 char md5secret
[256] = "";
4863 char secret
[256] = "";
4864 char rsasecret
[256] = "";
4867 struct iax2_user
*user
= NULL
;
4869 AST_LIST_LOCK(&users
);
4870 AST_LIST_TRAVERSE(&users
, user
, entry
) {
4871 if (!strcmp(user
->name
, p
->username
))
4875 if (ast_test_flag(p
, IAX_MAXAUTHREQ
)) {
4877 ast_clear_flag(p
, IAX_MAXAUTHREQ
);
4879 ast_string_field_set(p
, host
, user
->name
);
4881 AST_LIST_UNLOCK(&users
);
4883 if (!ast_test_flag(&p
->state
, IAX_STATE_AUTHENTICATED
))
4886 ast_copy_string(secret
, ies
->password
, sizeof(secret
));
4887 if (ies
->md5_result
)
4888 ast_copy_string(md5secret
, ies
->md5_result
, sizeof(md5secret
));
4889 if (ies
->rsa_result
)
4890 ast_copy_string(rsasecret
, ies
->rsa_result
, sizeof(rsasecret
));
4891 if ((p
->authmethods
& IAX_AUTH_RSA
) && !ast_strlen_zero(rsasecret
) && !ast_strlen_zero(p
->inkeys
)) {
4892 struct ast_key
*key
;
4896 ast_copy_string(tmpkey
, p
->inkeys
, sizeof(tmpkey
));
4898 keyn
= strsep(&stringp
, ":");
4900 key
= ast_key_get(keyn
, AST_KEY_PUBLIC
);
4901 if (key
&& !ast_check_signature(key
, p
->challenge
, rsasecret
)) {
4905 ast_log(LOG_WARNING
, "requested inkey '%s' for RSA authentication does not exist\n", keyn
);
4906 keyn
= strsep(&stringp
, ":");
4908 } else if (p
->authmethods
& IAX_AUTH_MD5
) {
4909 struct MD5Context md5
;
4910 unsigned char digest
[16];
4911 char *tmppw
, *stringp
;
4913 tmppw
= ast_strdupa(p
->secret
);
4915 while((tmppw
= strsep(&stringp
, ";"))) {
4917 MD5Update(&md5
, (unsigned char *)p
->challenge
, strlen(p
->challenge
));
4918 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
4919 MD5Final(digest
, &md5
);
4920 /* If they support md5, authenticate with it. */
4922 sprintf(requeststr
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
4923 if (!strcasecmp(requeststr
, md5secret
)) {
4928 } else if (p
->authmethods
& IAX_AUTH_PLAINTEXT
) {
4929 if (!strcmp(secret
, p
->secret
))
4935 /*! \brief Verify inbound registration */
4936 static int register_verify(int callno
, struct sockaddr_in
*sin
, struct iax_ies
*ies
)
4938 char requeststr
[256] = "";
4939 char peer
[256] = "";
4940 char md5secret
[256] = "";
4941 char rsasecret
[256] = "";
4942 char secret
[256] = "";
4943 struct iax2_peer
*p
;
4944 struct ast_key
*key
;
4949 ast_clear_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
| IAX_STATE_UNCHANGED
);
4950 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
4952 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
4954 ast_copy_string(secret
, ies
->password
, sizeof(secret
));
4955 if (ies
->md5_result
)
4956 ast_copy_string(md5secret
, ies
->md5_result
, sizeof(md5secret
));
4957 if (ies
->rsa_result
)
4958 ast_copy_string(rsasecret
, ies
->rsa_result
, sizeof(rsasecret
));
4960 expire
= ies
->refresh
;
4962 if (ast_strlen_zero(peer
)) {
4963 ast_log(LOG_NOTICE
, "Empty registration from %s\n", ast_inet_ntoa(sin
->sin_addr
));
4967 /* SLD: first call to lookup peer during registration */
4968 p
= find_peer(peer
, 1);
4972 ast_log(LOG_NOTICE
, "No registration for peer '%s' (from %s)\n", peer
, ast_inet_ntoa(sin
->sin_addr
));
4976 if (!ast_test_flag(p
, IAX_DYNAMIC
)) {
4978 ast_log(LOG_NOTICE
, "Peer '%s' is not dynamic (from %s)\n", peer
, ast_inet_ntoa(sin
->sin_addr
));
4979 if (ast_test_flag(p
, IAX_TEMPONLY
))
4984 if (!ast_apply_ha(p
->ha
, sin
)) {
4986 ast_log(LOG_NOTICE
, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
);
4987 if (ast_test_flag(p
, IAX_TEMPONLY
))
4991 if (!inaddrcmp(&p
->addr
, sin
))
4992 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_UNCHANGED
);
4993 ast_string_field_set(iaxs
[callno
], secret
, p
->secret
);
4994 ast_string_field_set(iaxs
[callno
], inkeys
, p
->inkeys
);
4995 /* Check secret against what we have on file */
4996 if (!ast_strlen_zero(rsasecret
) && (p
->authmethods
& IAX_AUTH_RSA
) && !ast_strlen_zero(iaxs
[callno
]->challenge
)) {
4997 if (!ast_strlen_zero(p
->inkeys
)) {
5000 ast_copy_string(tmpkeys
, p
->inkeys
, sizeof(tmpkeys
));
5002 keyn
= strsep(&stringp
, ":");
5004 key
= ast_key_get(keyn
, AST_KEY_PUBLIC
);
5005 if (key
&& !ast_check_signature(key
, iaxs
[callno
]->challenge
, rsasecret
)) {
5006 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5009 ast_log(LOG_WARNING
, "requested inkey '%s' does not exist\n", keyn
);
5010 keyn
= strsep(&stringp
, ":");
5014 ast_log(LOG_NOTICE
, "Host %s failed RSA authentication with inkeys '%s'\n", peer
, p
->inkeys
);
5015 if (ast_test_flag(p
, IAX_TEMPONLY
))
5021 ast_log(LOG_NOTICE
, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer
);
5022 if (ast_test_flag(p
, IAX_TEMPONLY
))
5026 } else if (!ast_strlen_zero(md5secret
) && (p
->authmethods
& IAX_AUTH_MD5
) && !ast_strlen_zero(iaxs
[callno
]->challenge
)) {
5027 struct MD5Context md5
;
5028 unsigned char digest
[16];
5029 char *tmppw
, *stringp
;
5031 tmppw
= ast_strdupa(p
->secret
);
5033 while((tmppw
= strsep(&stringp
, ";"))) {
5035 MD5Update(&md5
, (unsigned char *)iaxs
[callno
]->challenge
, strlen(iaxs
[callno
]->challenge
));
5036 MD5Update(&md5
, (unsigned char *)tmppw
, strlen(tmppw
));
5037 MD5Final(digest
, &md5
);
5039 sprintf(requeststr
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
5040 if (!strcasecmp(requeststr
, md5secret
))
5044 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5047 ast_log(LOG_NOTICE
, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
, requeststr
, md5secret
);
5048 if (ast_test_flag(p
, IAX_TEMPONLY
))
5052 } else if (!ast_strlen_zero(secret
) && (p
->authmethods
& IAX_AUTH_PLAINTEXT
)) {
5053 /* They've provided a plain text password and we support that */
5054 if (strcmp(secret
, p
->secret
)) {
5056 ast_log(LOG_NOTICE
, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin
->sin_addr
), p
->name
);
5057 if (ast_test_flag(p
, IAX_TEMPONLY
))
5061 ast_set_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
);
5062 } else if (!ast_strlen_zero(md5secret
) || !ast_strlen_zero(secret
)) {
5064 ast_log(LOG_NOTICE
, "Inappropriate authentication received\n");
5065 if (ast_test_flag(p
, IAX_TEMPONLY
))
5069 ast_string_field_set(iaxs
[callno
], peer
, peer
);
5070 /* Choose lowest expiry number */
5071 if (expire
&& (expire
< iaxs
[callno
]->expiry
))
5072 iaxs
[callno
]->expiry
= expire
;
5074 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5076 if (ast_test_flag(p
, IAX_TEMPONLY
))
5082 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
)
5086 if (!ast_strlen_zero(keyn
)) {
5087 if (!(authmethods
& IAX_AUTH_RSA
)) {
5088 if (ast_strlen_zero(secret
))
5089 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
));
5090 } else if (ast_strlen_zero(challenge
)) {
5091 ast_log(LOG_NOTICE
, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin
->sin_addr
));
5094 struct ast_key
*key
;
5095 key
= ast_key_get(keyn
, AST_KEY_PRIVATE
);
5097 ast_log(LOG_NOTICE
, "Unable to find private key '%s'\n", keyn
);
5099 if (ast_sign(key
, (char*)challenge
, sig
)) {
5100 ast_log(LOG_NOTICE
, "Unable to sign challenge with key\n");
5103 iax_ie_append_str(ied
, IAX_IE_RSA_RESULT
, sig
);
5110 if (res
&& !ast_strlen_zero(secret
)) {
5111 if ((authmethods
& IAX_AUTH_MD5
) && !ast_strlen_zero(challenge
)) {
5112 struct MD5Context md5
;
5113 unsigned char digest
[16];
5116 MD5Update(&md5
, (unsigned char *)challenge
, strlen(challenge
));
5117 MD5Update(&md5
, (unsigned char *)secret
, strlen(secret
));
5118 MD5Final(digest
, &md5
);
5119 /* If they support md5, authenticate with it. */
5121 sprintf(digres
+ (x
<< 1), "%2.2x", digest
[x
]); /* safe */
5123 build_enc_keys(digest
, ecx
, dcx
);
5124 iax_ie_append_str(ied
, IAX_IE_MD5_RESULT
, digres
);
5126 } else if (authmethods
& IAX_AUTH_PLAINTEXT
) {
5127 iax_ie_append_str(ied
, IAX_IE_PASSWORD
, secret
);
5130 ast_log(LOG_NOTICE
, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin
->sin_addr
), authmethods
);
5135 static int authenticate_reply(struct chan_iax2_pvt
*p
, struct sockaddr_in
*sin
, struct iax_ies
*ies
, const char *override
, const char *okey
)
5137 struct iax2_peer
*peer
= NULL
;
5138 /* Start pessimistic */
5140 int authmethods
= 0;
5141 struct iax_ie_data ied
;
5143 memset(&ied
, 0, sizeof(ied
));
5146 ast_string_field_set(p
, username
, ies
->username
);
5148 ast_string_field_set(p
, challenge
, ies
->challenge
);
5149 if (ies
->authmethods
)
5150 authmethods
= ies
->authmethods
;
5151 if (authmethods
& IAX_AUTH_MD5
)
5152 merge_encryption(p
, ies
->encmethods
);
5156 /* Check for override RSA authentication first */
5157 if (!ast_strlen_zero(override
) || !ast_strlen_zero(okey
)) {
5158 /* Normal password authentication */
5159 res
= authenticate(p
->challenge
, override
, okey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5161 AST_LIST_LOCK(&peers
);
5162 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
5163 if ((ast_strlen_zero(p
->peer
) || !strcmp(p
->peer
, peer
->name
))
5164 /* No peer specified at our end, or this is the peer */
5165 && (ast_strlen_zero(peer
->username
) || (!strcmp(peer
->username
, p
->username
)))
5166 /* No username specified in peer rule, or this is the right username */
5167 && (!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
)))
5168 /* No specified host, or this is our host */
5170 res
= authenticate(p
->challenge
, peer
->secret
, peer
->outkey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5175 AST_LIST_UNLOCK(&peers
);
5177 /* We checked our list and didn't find one. It's unlikely, but possible,
5178 that we're trying to authenticate *to* a realtime peer */
5179 if ((peer
= realtime_peer(p
->peer
, NULL
))) {
5180 res
= authenticate(p
->challenge
, peer
->secret
,peer
->outkey
, authmethods
, &ied
, sin
, &p
->ecx
, &p
->dcx
);
5181 if (ast_test_flag(peer
, IAX_TEMPONLY
))
5186 if (ies
->encmethods
)
5187 ast_set_flag(p
, IAX_ENCRYPTED
| IAX_KEYPOPULATED
);
5189 res
= send_command(p
, AST_FRAME_IAX
, IAX_COMMAND_AUTHREP
, 0, ied
.buf
, ied
.pos
, -1);
5193 static int iax2_do_register(struct iax2_registry
*reg
);
5195 static void __iax2_do_register_s(void *data
)
5197 struct iax2_registry
*reg
= data
;
5199 iax2_do_register(reg
);
5202 static int iax2_do_register_s(void *data
)
5204 #ifdef SCHED_MULTITHREADED
5205 if (schedule_action(__iax2_do_register_s
, data
))
5207 __iax2_do_register_s(data
);
5211 static int try_transfer(struct chan_iax2_pvt
*pvt
, struct iax_ies
*ies
)
5215 struct iax_ie_data ied
;
5216 struct sockaddr_in
new;
5219 memset(&ied
, 0, sizeof(ied
));
5220 if (ies
->apparent_addr
)
5221 bcopy(ies
->apparent_addr
, &new, sizeof(new));
5223 newcall
= ies
->callno
;
5224 if (!newcall
|| !new.sin_addr
.s_addr
|| !new.sin_port
) {
5225 ast_log(LOG_WARNING
, "Invalid transfer request\n");
5228 pvt
->transfercallno
= newcall
;
5229 memcpy(&pvt
->transfer
, &new, sizeof(pvt
->transfer
));
5230 inet_aton(newip
, &pvt
->transfer
.sin_addr
);
5231 pvt
->transfer
.sin_family
= AF_INET
;
5232 pvt
->transferring
= TRANSFER_BEGIN
;
5233 pvt
->transferid
= ies
->transferid
;
5234 if (ies
->transferid
)
5235 iax_ie_append_int(&ied
, IAX_IE_TRANSFERID
, ies
->transferid
);
5236 send_command_transfer(pvt
, AST_FRAME_IAX
, IAX_COMMAND_TXCNT
, 0, ied
.buf
, ied
.pos
);
5240 static int complete_dpreply(struct chan_iax2_pvt
*pvt
, struct iax_ies
*ies
)
5242 char exten
[256] = "";
5243 int status
= CACHE_FLAG_UNKNOWN
;
5244 int expiry
= iaxdefaultdpcache
;
5247 struct iax2_dpcache
*dp
, *prev
;
5249 if (ies
->called_number
)
5250 ast_copy_string(exten
, ies
->called_number
, sizeof(exten
));
5252 if (ies
->dpstatus
& IAX_DPSTATUS_EXISTS
)
5253 status
= CACHE_FLAG_EXISTS
;
5254 else if (ies
->dpstatus
& IAX_DPSTATUS_CANEXIST
)
5255 status
= CACHE_FLAG_CANEXIST
;
5256 else if (ies
->dpstatus
& IAX_DPSTATUS_NONEXISTENT
)
5257 status
= CACHE_FLAG_NONEXISTENT
;
5259 if (ies
->dpstatus
& IAX_DPSTATUS_IGNOREPAT
) {
5260 /* Don't really do anything with this */
5263 expiry
= ies
->refresh
;
5264 if (ies
->dpstatus
& IAX_DPSTATUS_MATCHMORE
)
5265 matchmore
= CACHE_FLAG_MATCHMORE
;
5266 ast_mutex_lock(&dpcache_lock
);
5268 dp
= pvt
->dpentries
;
5270 if (!strcmp(dp
->exten
, exten
)) {
5273 prev
->peer
= dp
->peer
;
5275 pvt
->dpentries
= dp
->peer
;
5278 dp
->expiry
.tv_sec
= dp
->orig
.tv_sec
+ expiry
;
5279 if (dp
->flags
& CACHE_FLAG_PENDING
) {
5280 dp
->flags
&= ~CACHE_FLAG_PENDING
;
5281 dp
->flags
|= status
;
5282 dp
->flags
|= matchmore
;
5284 /* Wake up waiters */
5285 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
5286 if (dp
->waiters
[x
] > -1)
5287 write(dp
->waiters
[x
], "asdf", 4);
5292 ast_mutex_unlock(&dpcache_lock
);
5296 static int complete_transfer(int callno
, struct iax_ies
*ies
)
5299 struct chan_iax2_pvt
*pvt
= iaxs
[callno
];
5300 struct iax_frame
*cur
;
5304 peercallno
= ies
->callno
;
5306 if (peercallno
< 1) {
5307 ast_log(LOG_WARNING
, "Invalid transfer request\n");
5310 memcpy(&pvt
->addr
, &pvt
->transfer
, sizeof(pvt
->addr
));
5311 memset(&pvt
->transfer
, 0, sizeof(pvt
->transfer
));
5312 /* Reset sequence numbers */
5317 pvt
->peercallno
= peercallno
;
5318 pvt
->transferring
= TRANSFER_NONE
;
5319 pvt
->svoiceformat
= -1;
5320 pvt
->voiceformat
= 0;
5321 pvt
->svideoformat
= -1;
5322 pvt
->videoformat
= 0;
5323 pvt
->transfercallno
= -1;
5324 memset(&pvt
->rxcore
, 0, sizeof(pvt
->rxcore
));
5325 memset(&pvt
->offset
, 0, sizeof(pvt
->offset
));
5326 /* reset jitterbuffer */
5327 while(jb_getall(pvt
->jb
,&frame
) == JB_OK
)
5328 iax2_frame_free(frame
.data
);
5334 pvt
->pingtime
= DEFAULT_RETRY_TIME
;
5335 AST_LIST_LOCK(&iaxq
.queue
);
5336 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
5337 /* We must cancel any packets that would have been transmitted
5338 because now we're talking to someone new. It's okay, they
5339 were transmitted to someone that didn't care anyway. */
5340 if (callno
== cur
->callno
)
5343 AST_LIST_UNLOCK(&iaxq
.queue
);
5347 /*! \brief Acknowledgment received for OUR registration */
5348 static int iax2_ack_registry(struct iax_ies
*ies
, struct sockaddr_in
*sin
, int callno
)
5350 struct iax2_registry
*reg
;
5351 /* Start pessimistic */
5352 char peer
[256] = "";
5355 char ourip
[256] = "<Unspecified>";
5356 struct sockaddr_in oldus
;
5357 struct sockaddr_in us
;
5360 memset(&us
, 0, sizeof(us
));
5361 if (ies
->apparent_addr
)
5362 bcopy(ies
->apparent_addr
, &us
, sizeof(us
));
5364 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
5366 refresh
= ies
->refresh
;
5367 if (ies
->calling_number
) {
5368 /* We don't do anything with it really, but maybe we should */
5370 reg
= iaxs
[callno
]->reg
;
5372 ast_log(LOG_WARNING
, "Registry acknowledge on unknown registry '%s'\n", peer
);
5375 memcpy(&oldus
, ®
->us
, sizeof(oldus
));
5376 oldmsgs
= reg
->messages
;
5377 if (inaddrcmp(®
->addr
, sin
)) {
5378 ast_log(LOG_WARNING
, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin
->sin_addr
));
5381 memcpy(®
->us
, &us
, sizeof(reg
->us
));
5382 if (ies
->msgcount
>= 0)
5383 reg
->messages
= ies
->msgcount
& 0xffff; /* only low 16 bits are used in the transmission of the IE */
5384 /* always refresh the registration at the interval requested by the server
5385 we are registering to
5387 reg
->refresh
= refresh
;
5388 if (reg
->expire
> -1)
5389 ast_sched_del(sched
, reg
->expire
);
5390 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
5391 if (inaddrcmp(&oldus
, ®
->us
) || (reg
->messages
!= oldmsgs
)) {
5392 if (option_verbose
> 2) {
5393 if (reg
->messages
> 255)
5394 snprintf(msgstatus
, sizeof(msgstatus
), " with %d new and %d old messages waiting", reg
->messages
& 0xff, reg
->messages
>> 8);
5395 else if (reg
->messages
> 1)
5396 snprintf(msgstatus
, sizeof(msgstatus
), " with %d new messages waiting\n", reg
->messages
);
5397 else if (reg
->messages
> 0)
5398 snprintf(msgstatus
, sizeof(msgstatus
), " with 1 new message waiting\n");
5400 snprintf(msgstatus
, sizeof(msgstatus
), " with no messages waiting\n");
5401 snprintf(ourip
, sizeof(ourip
), "%s:%d", ast_inet_ntoa(reg
->us
.sin_addr
), ntohs(reg
->us
.sin_port
));
5402 ast_verbose(VERBOSE_PREFIX_3
"Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin
->sin_addr
), ourip
, msgstatus
);
5404 manager_event(EVENT_FLAG_SYSTEM
, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin
->sin_addr
));
5406 reg
->regstate
= REG_STATE_REGISTERED
;
5410 static int iax2_register(char *value
, int lineno
)
5412 struct iax2_registry
*reg
;
5414 char *username
, *hostname
, *secret
;
5420 ast_copy_string(copy
, value
, sizeof(copy
));
5422 username
= strsep(&stringp
, "@");
5423 hostname
= strsep(&stringp
, "@");
5425 ast_log(LOG_WARNING
, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno
);
5429 username
= strsep(&stringp
, ":");
5430 secret
= strsep(&stringp
, ":");
5432 hostname
= strsep(&stringp
, ":");
5433 porta
= strsep(&stringp
, ":");
5435 if (porta
&& !atoi(porta
)) {
5436 ast_log(LOG_WARNING
, "%s is not a valid port number at line %d\n", porta
, lineno
);
5439 if (!(reg
= ast_calloc(1, sizeof(*reg
))))
5441 if (ast_dnsmgr_lookup(hostname
, ®
->addr
.sin_addr
, ®
->dnsmgr
) < 0) {
5445 ast_copy_string(reg
->username
, username
, sizeof(reg
->username
));
5447 ast_copy_string(reg
->secret
, secret
, sizeof(reg
->secret
));
5449 reg
->refresh
= IAX_DEFAULT_REG_EXPIRE
;
5450 reg
->addr
.sin_family
= AF_INET
;
5451 reg
->addr
.sin_port
= porta
? htons(atoi(porta
)) : htons(IAX_DEFAULT_PORTNO
);
5452 AST_LIST_LOCK(®istrations
);
5453 AST_LIST_INSERT_HEAD(®istrations
, reg
, entry
);
5454 AST_LIST_UNLOCK(®istrations
);
5459 static void register_peer_exten(struct iax2_peer
*peer
, int onoff
)
5462 char *stringp
, *ext
;
5463 if (!ast_strlen_zero(regcontext
)) {
5464 ast_copy_string(multi
, S_OR(peer
->regexten
, peer
->name
), sizeof(multi
));
5466 while((ext
= strsep(&stringp
, "&"))) {
5468 if (!ast_exists_extension(NULL
, regcontext
, ext
, 1, NULL
))
5469 ast_add_extension(regcontext
, 1, ext
, 1, NULL
, NULL
,
5470 "Noop", ast_strdup(peer
->name
), ast_free
, "IAX2");
5472 ast_context_remove_extension(regcontext
, ext
, 1, NULL
);
5476 static void prune_peers(void);
5478 static void __expire_registry(void *data
)
5481 struct iax2_peer
*p
= NULL
;
5483 /* Go through and grab this peer... and if it needs to be removed... then do it */
5484 AST_LIST_LOCK(&peers
);
5485 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers
, p
, entry
) {
5486 if (!strcasecmp(p
->name
, name
)) {
5491 AST_LIST_TRAVERSE_SAFE_END
5492 AST_LIST_UNLOCK(&peers
);
5494 /* Peer is already gone for whatever reason */
5498 ast_log(LOG_DEBUG
, "Expiring registration for peer '%s'\n", p
->name
);
5499 if (ast_test_flag((&globalflags
), IAX_RTUPDATE
) && (ast_test_flag(p
, IAX_TEMPONLY
|IAX_RTCACHEFRIENDS
)))
5500 realtime_update_peer(p
->name
, &p
->addr
, 0);
5501 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p
->name
);
5502 /* Reset the address */
5503 memset(&p
->addr
, 0, sizeof(p
->addr
));
5504 /* Reset expiry value */
5505 p
->expiry
= min_reg_expire
;
5506 if (!ast_test_flag(p
, IAX_TEMPONLY
))
5507 ast_db_del("IAX/Registry", p
->name
);
5508 register_peer_exten(p
, 0);
5509 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5511 iax2_regfunk(p
->name
, 0);
5513 if (ast_test_flag(p
, IAX_RTAUTOCLEAR
)) {
5514 ast_set_flag(p
, IAX_DELME
);
5519 static int expire_registry(void *data
)
5521 #ifdef SCHED_MULTITHREADED
5522 if (schedule_action(__expire_registry
, data
))
5524 __expire_registry(data
);
5528 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
);
5530 static void reg_source_db(struct iax2_peer
*p
)
5535 if (!ast_test_flag(p
, IAX_TEMPONLY
) && (!ast_db_get("IAX/Registry", p
->name
, data
, sizeof(data
)))) {
5536 c
= strchr(data
, ':');
5540 if (inet_aton(data
, &in
)) {
5545 if (option_verbose
> 2)
5546 ast_verbose(VERBOSE_PREFIX_3
"Seeding '%s' at %s:%d for %d\n", p
->name
,
5547 ast_inet_ntoa(in
), atoi(c
), atoi(d
));
5548 iax2_poke_peer(p
, 0);
5549 p
->expiry
= atoi(d
);
5550 memset(&p
->addr
, 0, sizeof(p
->addr
));
5551 p
->addr
.sin_family
= AF_INET
;
5552 p
->addr
.sin_addr
= in
;
5553 p
->addr
.sin_port
= htons(atoi(c
));
5555 ast_sched_del(sched
, p
->expire
);
5556 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5557 p
->expire
= ast_sched_add(sched
, (p
->expiry
+ 10) * 1000, expire_registry
, (void *)p
->name
);
5559 iax2_regfunk(p
->name
, 1);
5560 register_peer_exten(p
, 1);
5568 static int update_registry(const char *name
, struct sockaddr_in
*sin
, int callno
, char *devtype
, int fd
, unsigned short refresh
)
5570 /* Called from IAX thread only, with proper iaxsl lock */
5571 struct iax_ie_data ied
;
5572 struct iax2_peer
*p
;
5577 memset(&ied
, 0, sizeof(ied
));
5579 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
5580 if (!(p
= find_peer(name
, 1))) {
5581 ast_log(LOG_WARNING
, "No such peer '%s'\n", name
);
5585 if (ast_test_flag((&globalflags
), IAX_RTUPDATE
) && (ast_test_flag(p
, IAX_TEMPONLY
|IAX_RTCACHEFRIENDS
))) {
5586 if (sin
->sin_addr
.s_addr
) {
5589 realtime_update_peer(name
, sin
, nowtime
);
5591 realtime_update_peer(name
, sin
, 0);
5594 if (inaddrcmp(&p
->addr
, sin
)) {
5596 iax2_regfunk(p
->name
, 1);
5597 /* Stash the IP address from which they registered */
5598 memcpy(&p
->addr
, sin
, sizeof(p
->addr
));
5599 snprintf(data
, sizeof(data
), "%s:%d:%d", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
), p
->expiry
);
5600 if (!ast_test_flag(p
, IAX_TEMPONLY
) && sin
->sin_addr
.s_addr
) {
5601 ast_db_put("IAX/Registry", p
->name
, data
);
5602 if (option_verbose
> 2)
5603 ast_verbose(VERBOSE_PREFIX_3
"Registered IAX2 '%s' (%s) at %s:%d\n", p
->name
,
5604 ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin
->sin_addr
), ntohs(sin
->sin_port
));
5605 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p
->name
);
5606 register_peer_exten(p
, 1);
5607 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5608 } else if (!ast_test_flag(p
, IAX_TEMPONLY
)) {
5609 if (option_verbose
> 2)
5610 ast_verbose(VERBOSE_PREFIX_3
"Unregistered IAX2 '%s' (%s)\n", p
->name
,
5611 ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_AUTHENTICATED
) ? "AUTHENTICATED" : "UNAUTHENTICATED");
5612 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p
->name
);
5613 register_peer_exten(p
, 0);
5614 ast_db_del("IAX/Registry", p
->name
);
5615 ast_device_state_changed("IAX2/%s", p
->name
); /* Activate notification */
5617 /* Update the host */
5618 /* Verify that the host is really there */
5619 iax2_poke_peer(p
, callno
);
5622 /* Make sure our call still exists, an INVAL at the right point may make it go away */
5626 /* Store socket fd */
5628 /* Setup the expiry */
5630 ast_sched_del(sched
, p
->expire
);
5631 /* treat an unspecified refresh interval as the minimum */
5633 refresh
= min_reg_expire
;
5634 if (refresh
> max_reg_expire
) {
5635 ast_log(LOG_NOTICE
, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5636 p
->name
, max_reg_expire
, refresh
);
5637 p
->expiry
= max_reg_expire
;
5638 } else if (refresh
< min_reg_expire
) {
5639 ast_log(LOG_NOTICE
, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5640 p
->name
, min_reg_expire
, refresh
);
5641 p
->expiry
= min_reg_expire
;
5643 p
->expiry
= refresh
;
5645 if (p
->expiry
&& sin
->sin_addr
.s_addr
)
5646 p
->expire
= ast_sched_add(sched
, (p
->expiry
+ 10) * 1000, expire_registry
, (void *)p
->name
);
5647 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, p
->name
);
5648 iax_ie_append_int(&ied
, IAX_IE_DATETIME
, iax2_datetime(p
->zonetag
));
5649 if (sin
->sin_addr
.s_addr
) {
5650 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, p
->expiry
);
5651 iax_ie_append_addr(&ied
, IAX_IE_APPARENT_ADDR
, &p
->addr
);
5652 if (!ast_strlen_zero(p
->mailbox
)) {
5654 ast_app_inboxcount(p
->mailbox
, &new, &old
);
5659 msgcount
= (old
<< 8) | new;
5660 iax_ie_append_short(&ied
, IAX_IE_MSGCOUNT
, msgcount
);
5662 if (ast_test_flag(p
, IAX_HASCALLERID
)) {
5663 iax_ie_append_str(&ied
, IAX_IE_CALLING_NUMBER
, p
->cid_num
);
5664 iax_ie_append_str(&ied
, IAX_IE_CALLING_NAME
, p
->cid_name
);
5667 version
= iax_check_version(devtype
);
5669 iax_ie_append_short(&ied
, IAX_IE_FIRMWAREVER
, version
);
5670 if (ast_test_flag(p
, IAX_TEMPONLY
))
5672 return send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGACK
, 0, ied
.buf
, ied
.pos
, -1);
5675 static int registry_authrequest(const char *name
, int callno
)
5677 struct iax_ie_data ied
;
5678 struct iax2_peer
*p
;
5680 /* SLD: third call to find_peer in registration */
5681 p
= find_peer(name
, 1);
5683 memset(&ied
, 0, sizeof(ied
));
5684 iax_ie_append_short(&ied
, IAX_IE_AUTHMETHODS
, p
->authmethods
);
5685 if (p
->authmethods
& (IAX_AUTH_RSA
| IAX_AUTH_MD5
)) {
5686 /* Build the challenge */
5687 snprintf(challenge
, sizeof(challenge
), "%d", (int)ast_random());
5688 ast_string_field_set(iaxs
[callno
], challenge
, challenge
);
5689 /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */
5690 iax_ie_append_str(&ied
, IAX_IE_CHALLENGE
, iaxs
[callno
]->challenge
);
5692 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, name
);
5693 if (ast_test_flag(p
, IAX_TEMPONLY
))
5695 return send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGAUTH
, 0, ied
.buf
, ied
.pos
, -1);;
5697 ast_log(LOG_WARNING
, "No such peer '%s'\n", name
);
5701 static int registry_rerequest(struct iax_ies
*ies
, int callno
, struct sockaddr_in
*sin
)
5703 struct iax2_registry
*reg
;
5704 /* Start pessimistic */
5705 struct iax_ie_data ied
;
5706 char peer
[256] = "";
5707 char challenge
[256] = "";
5709 int authmethods
= 0;
5710 if (ies
->authmethods
)
5711 authmethods
= ies
->authmethods
;
5713 ast_copy_string(peer
, ies
->username
, sizeof(peer
));
5715 ast_copy_string(challenge
, ies
->challenge
, sizeof(challenge
));
5716 memset(&ied
, 0, sizeof(ied
));
5717 reg
= iaxs
[callno
]->reg
;
5719 if (inaddrcmp(®
->addr
, sin
)) {
5720 ast_log(LOG_WARNING
, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin
->sin_addr
));
5723 if (ast_strlen_zero(reg
->secret
)) {
5724 ast_log(LOG_NOTICE
, "No secret associated with peer '%s'\n", reg
->username
);
5725 reg
->regstate
= REG_STATE_NOAUTH
;
5728 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, reg
->username
);
5729 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, reg
->refresh
);
5730 if (reg
->secret
[0] == '[') {
5732 ast_copy_string(tmpkey
, reg
->secret
+ 1, sizeof(tmpkey
));
5733 tmpkey
[strlen(tmpkey
) - 1] = '\0';
5734 res
= authenticate(challenge
, NULL
, tmpkey
, authmethods
, &ied
, sin
, NULL
, NULL
);
5736 res
= authenticate(challenge
, reg
->secret
, NULL
, authmethods
, &ied
, sin
, NULL
, NULL
);
5738 reg
->regstate
= REG_STATE_AUTHSENT
;
5739 return send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_REGREQ
, 0, ied
.buf
, ied
.pos
, -1);
5742 ast_log(LOG_WARNING
, "Registry acknowledge on unknown registery '%s'\n", peer
);
5744 ast_log(LOG_NOTICE
, "Can't reregister without a reg\n");
5748 static void stop_stuff(int callno
)
5750 iax2_destroy_helper(iaxs
[callno
]);
5753 static void __auth_reject(void *nothing
)
5755 /* Called from IAX thread only, without iaxs lock */
5756 int callno
= (int)(long)(nothing
);
5757 struct iax_ie_data ied
;
5758 ast_mutex_lock(&iaxsl
[callno
]);
5760 memset(&ied
, 0, sizeof(ied
));
5761 if (iaxs
[callno
]->authfail
== IAX_COMMAND_REGREJ
) {
5762 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Registration Refused");
5763 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_REJECTED
);
5764 } else if (iaxs
[callno
]->authfail
== IAX_COMMAND_REJECT
) {
5765 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "No authority found");
5766 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_NOT_SUBSCRIBED
);
5768 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, iaxs
[callno
]->authfail
, 0, ied
.buf
, ied
.pos
, -1);
5770 ast_mutex_unlock(&iaxsl
[callno
]);
5773 static int auth_reject(void *data
)
5775 int callno
= (int)(long)(data
);
5776 ast_mutex_lock(&iaxsl
[callno
]);
5778 iaxs
[callno
]->authid
= -1;
5779 ast_mutex_unlock(&iaxsl
[callno
]);
5780 #ifdef SCHED_MULTITHREADED
5781 if (schedule_action(__auth_reject
, data
))
5783 __auth_reject(data
);
5787 static int auth_fail(int callno
, int failcode
)
5789 /* Schedule sending the authentication failure in one second, to prevent
5791 ast_mutex_lock(&iaxsl
[callno
]);
5793 iaxs
[callno
]->authfail
= failcode
;
5795 if (iaxs
[callno
]->authid
> -1)
5796 ast_sched_del(sched
, iaxs
[callno
]->authid
);
5797 iaxs
[callno
]->authid
= ast_sched_add(sched
, 1000, auth_reject
, (void *)(long)callno
);
5799 auth_reject((void *)(long)callno
);
5801 ast_mutex_unlock(&iaxsl
[callno
]);
5805 static void __auto_hangup(void *nothing
)
5807 /* Called from IAX thread only, without iaxs lock */
5808 int callno
= (int)(long)(nothing
);
5809 struct iax_ie_data ied
;
5810 ast_mutex_lock(&iaxsl
[callno
]);
5812 memset(&ied
, 0, sizeof(ied
));
5813 iax_ie_append_str(&ied
, IAX_IE_CAUSE
, "Timeout");
5814 iax_ie_append_byte(&ied
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_USER_RESPONSE
);
5815 send_command_final(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_HANGUP
, 0, ied
.buf
, ied
.pos
, -1);
5817 ast_mutex_unlock(&iaxsl
[callno
]);
5820 static int auto_hangup(void *data
)
5822 int callno
= (int)(long)(data
);
5823 ast_mutex_lock(&iaxsl
[callno
]);
5825 iaxs
[callno
]->autoid
= -1;
5827 ast_mutex_unlock(&iaxsl
[callno
]);
5828 #ifdef SCHED_MULTITHREADED
5829 if (schedule_action(__auto_hangup
, data
))
5831 __auto_hangup(data
);
5835 static void iax2_dprequest(struct iax2_dpcache
*dp
, int callno
)
5837 struct iax_ie_data ied
;
5838 /* Auto-hangup with 30 seconds of inactivity */
5839 if (iaxs
[callno
]->autoid
> -1)
5840 ast_sched_del(sched
, iaxs
[callno
]->autoid
);
5841 iaxs
[callno
]->autoid
= ast_sched_add(sched
, 30000, auto_hangup
, (void *)(long)callno
);
5842 memset(&ied
, 0, sizeof(ied
));
5843 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, dp
->exten
);
5844 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_DPREQ
, 0, ied
.buf
, ied
.pos
, -1);
5845 dp
->flags
|= CACHE_FLAG_TRANSMITTED
;
5848 static int iax2_vnak(int callno
)
5850 return send_command_immediate(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_VNAK
, 0, NULL
, 0, iaxs
[callno
]->iseqno
);
5853 static void vnak_retransmit(int callno
, int last
)
5855 struct iax_frame
*f
;
5857 AST_LIST_LOCK(&iaxq
.queue
);
5858 AST_LIST_TRAVERSE(&iaxq
.queue
, f
, list
) {
5859 /* Send a copy immediately */
5860 if ((f
->callno
== callno
) && iaxs
[f
->callno
] &&
5861 (f
->oseqno
>= last
)) {
5865 AST_LIST_UNLOCK(&iaxq
.queue
);
5868 static void __iax2_poke_peer_s(void *data
)
5870 struct iax2_peer
*peer
= data
;
5871 iax2_poke_peer(peer
, 0);
5874 static int iax2_poke_peer_s(void *data
)
5876 struct iax2_peer
*peer
= data
;
5877 peer
->pokeexpire
= -1;
5878 #ifdef SCHED_MULTITHREADED
5879 if (schedule_action(__iax2_poke_peer_s
, data
))
5881 __iax2_poke_peer_s(data
);
5885 static int send_trunk(struct iax2_trunk_peer
*tpeer
, struct timeval
*now
)
5888 struct iax_frame
*fr
;
5889 struct ast_iax2_meta_hdr
*meta
;
5890 struct ast_iax2_meta_trunk_hdr
*mth
;
5893 /* Point to frame */
5894 fr
= (struct iax_frame
*)tpeer
->trunkdata
;
5895 /* Point to meta data */
5896 meta
= (struct ast_iax2_meta_hdr
*)fr
->afdata
;
5897 mth
= (struct ast_iax2_meta_trunk_hdr
*)meta
->data
;
5898 if (tpeer
->trunkdatalen
) {
5899 /* We're actually sending a frame, so fill the meta trunk header and meta header */
5901 meta
->metacmd
= IAX_META_TRUNK
;
5902 if (ast_test_flag(&globalflags
, IAX_TRUNKTIMESTAMPS
))
5903 meta
->cmddata
= IAX_META_TRUNK_MINI
;
5905 meta
->cmddata
= IAX_META_TRUNK_SUPERMINI
;
5906 mth
->ts
= htonl(calc_txpeerstamp(tpeer
, trunkfreq
, now
));
5907 /* And the rest of the ast_iax2 header */
5908 fr
->direction
= DIRECTION_OUTGRESS
;
5911 /* Any appropriate call will do */
5912 fr
->data
= fr
->afdata
;
5913 fr
->datalen
= tpeer
->trunkdatalen
+ sizeof(struct ast_iax2_meta_hdr
) + sizeof(struct ast_iax2_meta_trunk_hdr
);
5914 res
= transmit_trunk(fr
, &tpeer
->addr
, tpeer
->sockfd
);
5915 calls
= tpeer
->calls
;
5917 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
));
5919 /* Reset transmit trunk side data */
5920 tpeer
->trunkdatalen
= 0;
5928 static inline int iax2_trunk_expired(struct iax2_trunk_peer
*tpeer
, struct timeval
*now
)
5930 /* Drop when trunk is about 5 seconds idle */
5931 if (now
->tv_sec
> tpeer
->trunkact
.tv_sec
+ 5)
5936 static int timing_read(int *id
, int fd
, short events
, void *cbdata
)
5940 struct iax2_trunk_peer
*tpeer
, *prev
= NULL
, *drop
=NULL
;
5948 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA
);
5949 gettimeofday(&now
, NULL
);
5950 if (events
& AST_IO_PRI
) {
5952 /* Great, this is a timing interface, just call the ioctl */
5953 if (ioctl(fd
, ZT_TIMERACK
, &x
))
5954 ast_log(LOG_WARNING
, "Unable to acknowledge zap timer\n");
5958 /* Read and ignore from the pseudo channel for timing */
5959 res
= read(fd
, buf
, sizeof(buf
));
5961 ast_log(LOG_WARNING
, "Unable to read from timing fd\n");
5965 /* For each peer that supports trunking... */
5966 ast_mutex_lock(&tpeerlock
);
5971 ast_mutex_lock(&tpeer
->lock
);
5972 /* We can drop a single tpeer per pass. That makes all this logic
5973 substantially easier */
5974 if (!drop
&& iax2_trunk_expired(tpeer
, &now
)) {
5975 /* Take it out of the list, but don't free it yet, because it
5978 prev
->next
= tpeer
->next
;
5980 tpeers
= tpeer
->next
;
5983 res
= send_trunk(tpeer
, &now
);
5985 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
);
5989 ast_mutex_unlock(&tpeer
->lock
);
5991 tpeer
= tpeer
->next
;
5993 ast_mutex_unlock(&tpeerlock
);
5995 ast_mutex_lock(&drop
->lock
);
5996 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
5997 because by the time they could get tpeerlock, we've already grabbed it */
5998 ast_log(LOG_DEBUG
, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop
->addr
.sin_addr
), ntohs(drop
->addr
.sin_port
));
5999 free(drop
->trunkdata
);
6000 ast_mutex_unlock(&drop
->lock
);
6001 ast_mutex_destroy(&drop
->lock
);
6006 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed
, totalcalls
);
6013 char context
[AST_MAX_EXTENSION
];
6014 char callednum
[AST_MAX_EXTENSION
];
6018 static void dp_lookup(int callno
, const char *context
, const char *callednum
, const char *callerid
, int skiplock
)
6020 unsigned short dpstatus
= 0;
6021 struct iax_ie_data ied1
;
6024 memset(&ied1
, 0, sizeof(ied1
));
6025 mm
= ast_matchmore_extension(NULL
, context
, callednum
, 1, callerid
);
6026 /* Must be started */
6027 if (!strcmp(callednum
, ast_parking_ext()) || ast_exists_extension(NULL
, context
, callednum
, 1, callerid
)) {
6028 dpstatus
= IAX_DPSTATUS_EXISTS
;
6029 } else if (ast_canmatch_extension(NULL
, context
, callednum
, 1, callerid
)) {
6030 dpstatus
= IAX_DPSTATUS_CANEXIST
;
6032 dpstatus
= IAX_DPSTATUS_NONEXISTENT
;
6034 if (ast_ignore_pattern(context
, callednum
))
6035 dpstatus
|= IAX_DPSTATUS_IGNOREPAT
;
6037 dpstatus
|= IAX_DPSTATUS_MATCHMORE
;
6039 ast_mutex_lock(&iaxsl
[callno
]);
6041 iax_ie_append_str(&ied1
, IAX_IE_CALLED_NUMBER
, callednum
);
6042 iax_ie_append_short(&ied1
, IAX_IE_DPSTATUS
, dpstatus
);
6043 iax_ie_append_short(&ied1
, IAX_IE_REFRESH
, iaxdefaultdpcache
);
6044 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_DPREP
, 0, ied1
.buf
, ied1
.pos
, -1);
6047 ast_mutex_unlock(&iaxsl
[callno
]);
6050 static void *dp_lookup_thread(void *data
)
6052 /* Look up for dpreq */
6053 struct dpreq_data
*dpr
= data
;
6054 dp_lookup(dpr
->callno
, dpr
->context
, dpr
->callednum
, dpr
->callerid
, 0);
6056 free(dpr
->callerid
);
6061 static void spawn_dp_lookup(int callno
, const char *context
, const char *callednum
, const char *callerid
)
6063 pthread_t newthread
;
6064 struct dpreq_data
*dpr
;
6065 pthread_attr_t attr
;
6067 if (!(dpr
= ast_calloc(1, sizeof(*dpr
))))
6070 pthread_attr_init(&attr
);
6071 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
6073 dpr
->callno
= callno
;
6074 ast_copy_string(dpr
->context
, context
, sizeof(dpr
->context
));
6075 ast_copy_string(dpr
->callednum
, callednum
, sizeof(dpr
->callednum
));
6077 dpr
->callerid
= ast_strdup(callerid
);
6078 if (ast_pthread_create(&newthread
, &attr
, dp_lookup_thread
, dpr
)) {
6079 ast_log(LOG_WARNING
, "Unable to start lookup thread!\n");
6082 pthread_attr_destroy(&attr
);
6086 struct ast_channel
*chan1
;
6087 struct ast_channel
*chan2
;
6090 static void *iax_park_thread(void *stuff
)
6092 struct ast_channel
*chan1
, *chan2
;
6094 struct ast_frame
*f
;
6101 f
= ast_read(chan1
);
6104 res
= ast_park_call(chan1
, chan2
, 0, &ext
);
6106 ast_log(LOG_NOTICE
, "Parked on extension '%d'\n", ext
);
6110 static int iax_park(struct ast_channel
*chan1
, struct ast_channel
*chan2
)
6113 struct ast_channel
*chan1m
, *chan2m
;
6115 chan1m
= ast_channel_alloc(0, AST_STATE_DOWN
, 0, 0, "Parking/%s", chan1
->name
);
6116 chan2m
= ast_channel_alloc(0, AST_STATE_DOWN
, 0, 0, "IAXPeer/%s",chan2
->name
);
6117 if (chan2m
&& chan1m
) {
6118 /* Make formats okay */
6119 chan1m
->readformat
= chan1
->readformat
;
6120 chan1m
->writeformat
= chan1
->writeformat
;
6121 ast_channel_masquerade(chan1m
, chan1
);
6122 /* Setup the extensions and such */
6123 ast_copy_string(chan1m
->context
, chan1
->context
, sizeof(chan1m
->context
));
6124 ast_copy_string(chan1m
->exten
, chan1
->exten
, sizeof(chan1m
->exten
));
6125 chan1m
->priority
= chan1
->priority
;
6127 /* We make a clone of the peer channel too, so we can play
6128 back the announcement */
6129 /* Make formats okay */
6130 chan2m
->readformat
= chan2
->readformat
;
6131 chan2m
->writeformat
= chan2
->writeformat
;
6132 ast_channel_masquerade(chan2m
, chan2
);
6133 /* Setup the extensions and such */
6134 ast_copy_string(chan2m
->context
, chan2
->context
, sizeof(chan2m
->context
));
6135 ast_copy_string(chan2m
->exten
, chan2
->exten
, sizeof(chan2m
->exten
));
6136 chan2m
->priority
= chan2
->priority
;
6137 if (ast_do_masquerade(chan2m
)) {
6138 ast_log(LOG_WARNING
, "Masquerade failed :(\n");
6149 if ((d
= ast_calloc(1, sizeof(*d
)))) {
6150 pthread_attr_t attr
;
6152 pthread_attr_init(&attr
);
6153 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
6157 if (!ast_pthread_create_background(&th
, &attr
, iax_park_thread
, d
)) {
6158 pthread_attr_destroy(&attr
);
6161 pthread_attr_destroy(&attr
);
6168 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
);
6170 static int check_provisioning(struct sockaddr_in
*sin
, int sockfd
, char *si
, unsigned int ver
)
6172 unsigned int ourver
;
6174 snprintf(rsi
, sizeof(rsi
), "si-%s", si
);
6175 if (iax_provision_version(&ourver
, rsi
, 1))
6178 ast_log(LOG_DEBUG
, "Service identifier '%s', we think '%08x', they think '%08x'\n", si
, ourver
, ver
);
6180 iax2_provision(sin
, sockfd
, NULL
, rsi
, 1);
6184 static void construct_rr(struct chan_iax2_pvt
*pvt
, struct iax_ie_data
*iep
)
6187 jb_getinfo(pvt
->jb
, &stats
);
6189 memset(iep
, 0, sizeof(*iep
));
6191 iax_ie_append_int(iep
,IAX_IE_RR_JITTER
, stats
.jitter
);
6192 if(stats
.frames_in
== 0) stats
.frames_in
= 1;
6193 iax_ie_append_int(iep
,IAX_IE_RR_LOSS
, ((0xff & (stats
.losspct
/1000)) << 24 | (stats
.frames_lost
& 0x00ffffff)));
6194 iax_ie_append_int(iep
,IAX_IE_RR_PKTS
, stats
.frames_in
);
6195 iax_ie_append_short(iep
,IAX_IE_RR_DELAY
, stats
.current
- stats
.min
);
6196 iax_ie_append_int(iep
,IAX_IE_RR_DROPPED
, stats
.frames_dropped
);
6197 iax_ie_append_int(iep
,IAX_IE_RR_OOO
, stats
.frames_ooo
);
6200 static void save_rr(struct iax_frame
*fr
, struct iax_ies
*ies
)
6202 iaxs
[fr
->callno
]->remote_rr
.jitter
= ies
->rr_jitter
;
6203 iaxs
[fr
->callno
]->remote_rr
.losspct
= ies
->rr_loss
>> 24;
6204 iaxs
[fr
->callno
]->remote_rr
.losscnt
= ies
->rr_loss
& 0xffffff;
6205 iaxs
[fr
->callno
]->remote_rr
.packets
= ies
->rr_pkts
;
6206 iaxs
[fr
->callno
]->remote_rr
.delay
= ies
->rr_delay
;
6207 iaxs
[fr
->callno
]->remote_rr
.dropped
= ies
->rr_dropped
;
6208 iaxs
[fr
->callno
]->remote_rr
.ooo
= ies
->rr_ooo
;
6211 static int socket_read(int *id
, int fd
, short events
, void *cbdata
)
6213 struct iax2_thread
*thread
;
6216 static time_t last_errtime
=0;
6218 thread
= find_idle_thread();
6220 len
= sizeof(thread
->iosin
);
6222 thread
->iores
= recvfrom(fd
, thread
->buf
, sizeof(thread
->buf
), 0,(struct sockaddr
*) &thread
->iosin
, &len
);
6223 if (thread
->iores
< 0) {
6224 if (errno
!= ECONNREFUSED
&& errno
!= EAGAIN
)
6225 ast_log(LOG_WARNING
, "Error: %s\n", strerror(errno
));
6227 insert_idle_thread(thread
);
6230 if (test_losspct
&& ((100.0 * ast_random() / (RAND_MAX
+ 1.0)) < test_losspct
)) { /* simulate random loss condition */
6231 insert_idle_thread(thread
);
6234 /* Mark as ready and send on its way */
6235 thread
->iostate
= IAX_IOSTATE_READY
;
6236 #ifdef DEBUG_SCHED_MULTITHREAD
6237 ast_copy_string(thread
->curfunc
, "socket_process", sizeof(thread
->curfunc
));
6239 signal_condition(&thread
->lock
, &thread
->cond
);
6242 if (t
!= last_errtime
)
6243 ast_log(LOG_NOTICE
, "Out of idle IAX2 threads for I/O, pausing!\n");
6250 static int socket_process(struct iax2_thread
*thread
)
6252 struct sockaddr_in sin
;
6254 int updatehistory
=1;
6255 int new = NEW_PREVENT
;
6258 struct ast_iax2_full_hdr
*fh
= (struct ast_iax2_full_hdr
*)thread
->buf
;
6259 struct ast_iax2_mini_hdr
*mh
= (struct ast_iax2_mini_hdr
*)thread
->buf
;
6260 struct ast_iax2_meta_hdr
*meta
= (struct ast_iax2_meta_hdr
*)thread
->buf
;
6261 struct ast_iax2_video_hdr
*vh
= (struct ast_iax2_video_hdr
*)thread
->buf
;
6262 struct ast_iax2_meta_trunk_hdr
*mth
;
6263 struct ast_iax2_meta_trunk_entry
*mte
;
6264 struct ast_iax2_meta_trunk_mini
*mtm
;
6265 struct iax_frame
*fr
;
6266 struct iax_frame
*cur
;
6267 struct ast_frame f
= { 0, };
6268 struct ast_channel
*c
;
6269 struct iax2_dpcache
*dp
;
6270 struct iax2_peer
*peer
;
6271 struct iax2_trunk_peer
*tpeer
;
6272 struct timeval rxtrunktime
;
6274 struct iax_ie_data ied0
, ied1
;
6280 char empty
[32]=""; /* Safety measure */
6281 struct iax_frame
*duped_fr
;
6282 char host_pref_buf
[128];
6283 char caller_pref_buf
[128];
6284 struct ast_codec_pref pref
;
6285 char *using_prefs
= "mine";
6287 /* allocate an iax_frame with 4096 bytes of data buffer */
6288 fr
= alloca(sizeof(*fr
) + 4096);
6291 /* Copy frequently used parameters to the stack */
6292 res
= thread
->iores
;
6294 memcpy(&sin
, &thread
->iosin
, sizeof(sin
));
6296 if (res
< sizeof(*mh
)) {
6297 ast_log(LOG_WARNING
, "midget packet received (%d of %zd min)\n", res
, sizeof(*mh
));
6300 if ((vh
->zeros
== 0) && (ntohs(vh
->callno
) & 0x8000)) {
6301 if (res
< sizeof(*vh
)) {
6302 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
));
6306 /* This is a video frame, get call number */
6307 fr
->callno
= find_callno(ntohs(vh
->callno
) & ~0x8000, dcallno
, &sin
, new, 1, fd
);
6309 } else if ((meta
->zeros
== 0) && !(ntohs(meta
->metacmd
) & 0x8000)) {
6310 unsigned char metatype
;
6312 if (res
< sizeof(*meta
)) {
6313 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
));
6317 /* This is a meta header */
6318 switch(meta
->metacmd
) {
6319 case IAX_META_TRUNK
:
6320 if (res
< (sizeof(*meta
) + sizeof(*mth
))) {
6321 ast_log(LOG_WARNING
, "midget meta trunk packet received (%d of %zd min)\n", res
,
6322 sizeof(*meta
) + sizeof(*mth
));
6325 mth
= (struct ast_iax2_meta_trunk_hdr
*)(meta
->data
);
6326 ts
= ntohl(mth
->ts
);
6327 metatype
= meta
->cmddata
;
6328 res
-= (sizeof(*meta
) + sizeof(*mth
));
6330 tpeer
= find_tpeer(&sin
, fd
);
6332 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
));
6335 tpeer
->trunkact
= ast_tvnow();
6336 if (!ts
|| ast_tvzero(tpeer
->rxtrunktime
))
6337 tpeer
->rxtrunktime
= tpeer
->trunkact
;
6338 rxtrunktime
= tpeer
->rxtrunktime
;
6339 ast_mutex_unlock(&tpeer
->lock
);
6340 while(res
>= sizeof(*mte
)) {
6341 /* Process channels */
6342 unsigned short callno
, trunked_ts
, len
;
6344 if (metatype
== IAX_META_TRUNK_MINI
) {
6345 mtm
= (struct ast_iax2_meta_trunk_mini
*)ptr
;
6346 ptr
+= sizeof(*mtm
);
6347 res
-= sizeof(*mtm
);
6348 len
= ntohs(mtm
->len
);
6349 callno
= ntohs(mtm
->mini
.callno
);
6350 trunked_ts
= ntohs(mtm
->mini
.ts
);
6351 } else if (metatype
== IAX_META_TRUNK_SUPERMINI
) {
6352 mte
= (struct ast_iax2_meta_trunk_entry
*)ptr
;
6353 ptr
+= sizeof(*mte
);
6354 res
-= sizeof(*mte
);
6355 len
= ntohs(mte
->len
);
6356 callno
= ntohs(mte
->callno
);
6359 ast_log(LOG_WARNING
, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin
.sin_addr
), ntohs(sin
.sin_port
));
6362 /* Stop if we don't have enough data */
6365 fr
->callno
= find_callno(callno
& ~IAX_FLAG_FULL
, 0, &sin
, NEW_PREVENT
, 1, fd
);
6367 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6368 /* If it's a valid call, deliver the contents. If not, we
6369 drop it, since we don't have a scallno to use for an INVAL */
6370 /* Process as a mini frame */
6371 memset(&f
, 0, sizeof(f
));
6372 f
.frametype
= AST_FRAME_VOICE
;
6373 if (iaxs
[fr
->callno
]) {
6374 if (iaxs
[fr
->callno
]->voiceformat
> 0) {
6375 f
.subclass
= iaxs
[fr
->callno
]->voiceformat
;
6377 if (f
.datalen
>= 0) {
6381 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | (trunked_ts
& 0xffff);
6383 fr
->ts
= fix_peerts(&rxtrunktime
, fr
->callno
, ts
);
6384 /* Don't pass any packets until we're started */
6385 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6388 if (f
.datalen
&& (f
.frametype
== AST_FRAME_VOICE
))
6389 f
.samples
= ast_codec_get_samples(&f
);
6390 iax_frame_wrap(fr
, &f
);
6391 duped_fr
= iaxfrdup2(fr
);
6393 schedule_delivery(duped_fr
, updatehistory
, 1, &fr
->ts
);
6395 /* It is possible for the pvt structure to go away after we call schedule_delivery */
6396 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->last
< fr
->ts
) {
6397 iaxs
[fr
->callno
]->last
= fr
->ts
;
6399 if (option_debug
&& iaxdebug
)
6400 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
6405 ast_log(LOG_WARNING
, "Datalen < 0?\n");
6408 ast_log(LOG_WARNING
, "Received trunked frame before first full voice frame\n ");
6409 iax2_vnak(fr
->callno
);
6412 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6422 #ifdef DEBUG_SUPPORT
6423 if (iaxdebug
&& (res
>= sizeof(*fh
)))
6424 iax_showframe(NULL
, fh
, 1, &sin
, res
- sizeof(*fh
));
6426 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6427 if (res
< sizeof(*fh
)) {
6428 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
));
6432 /* Get the destination call number */
6433 dcallno
= ntohs(fh
->dcallno
) & ~IAX_FLAG_RETRANS
;
6434 /* Retrieve the type and subclass */
6435 f
.frametype
= fh
->type
;
6436 if (f
.frametype
== AST_FRAME_VIDEO
) {
6437 f
.subclass
= uncompress_subclass(fh
->csub
& ~0x40) | ((fh
->csub
>> 6) & 0x1);
6439 f
.subclass
= uncompress_subclass(fh
->csub
);
6441 if ((f
.frametype
== AST_FRAME_IAX
) && ((f
.subclass
== IAX_COMMAND_NEW
) || (f
.subclass
== IAX_COMMAND_REGREQ
) ||
6442 (f
.subclass
== IAX_COMMAND_POKE
) || (f
.subclass
== IAX_COMMAND_FWDOWNL
) ||
6443 (f
.subclass
== IAX_COMMAND_REGREL
)))
6446 /* Don't know anything about it yet */
6447 f
.frametype
= AST_FRAME_NULL
;
6452 fr
->callno
= find_callno(ntohs(mh
->callno
) & ~IAX_FLAG_FULL
, dcallno
, &sin
, new, 1, fd
);
6455 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6457 if (!fr
->callno
|| !iaxs
[fr
->callno
]) {
6458 /* A call arrived for a nonexistent destination. Unless it's an "inval"
6459 frame, reply with an inval */
6460 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6461 /* We can only raw hangup control frames */
6462 if (((f
.subclass
!= IAX_COMMAND_INVAL
) &&
6463 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6464 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6465 (f
.subclass
!= IAX_COMMAND_FWDOWNL
))||
6466 (f
.frametype
!= AST_FRAME_IAX
))
6467 raw_hangup(&sin
, ntohs(fh
->dcallno
) & ~IAX_FLAG_RETRANS
, ntohs(mh
->callno
) & ~IAX_FLAG_FULL
,
6471 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6474 if (ast_test_flag(iaxs
[fr
->callno
], IAX_ENCRYPTED
)) {
6475 if (decrypt_frame(fr
->callno
, fh
, &f
, &res
)) {
6476 ast_log(LOG_NOTICE
, "Packet Decrypt Failed!\n");
6477 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6480 #ifdef DEBUG_SUPPORT
6482 iax_showframe(NULL
, fh
, 3, &sin
, res
- sizeof(*fh
));
6486 /* count this frame */
6487 iaxs
[fr
->callno
]->frames_received
++;
6489 if (!inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) && !minivid
&&
6490 f
.subclass
!= IAX_COMMAND_TXCNT
&& /* for attended transfer */
6491 f
.subclass
!= IAX_COMMAND_TXACC
) /* for attended transfer */
6492 iaxs
[fr
->callno
]->peercallno
= (unsigned short)(ntohs(mh
->callno
) & ~IAX_FLAG_FULL
);
6493 if (ntohs(mh
->callno
) & IAX_FLAG_FULL
) {
6494 if (option_debug
&& iaxdebug
)
6495 ast_log(LOG_DEBUG
, "Received packet %d, (%d, %d)\n", fh
->oseqno
, f
.frametype
, f
.subclass
);
6496 /* Check if it's out of order (and not an ACK or INVAL) */
6497 fr
->oseqno
= fh
->oseqno
;
6498 fr
->iseqno
= fh
->iseqno
;
6499 fr
->ts
= ntohl(fh
->ts
);
6503 ast_log(LOG_DEBUG
, "Simulating frame ts resync, was %u now %u\n", fr
->ts
, fr
->ts
+ test_resync
);
6504 fr
->ts
+= test_resync
;
6506 #endif /* IAXTESTS */
6508 if ( (ntohs(fh
->dcallno
) & IAX_FLAG_RETRANS
) ||
6509 ( (f
.frametype
!= AST_FRAME_VOICE
) && ! (f
.frametype
== AST_FRAME_IAX
&&
6510 (f
.subclass
== IAX_COMMAND_NEW
||
6511 f
.subclass
== IAX_COMMAND_AUTHREQ
||
6512 f
.subclass
== IAX_COMMAND_ACCEPT
||
6513 f
.subclass
== IAX_COMMAND_REJECT
)) ) )
6515 if ((ntohs(fh
->dcallno
) & IAX_FLAG_RETRANS
) || (f
.frametype
!= AST_FRAME_VOICE
))
6517 if ((iaxs
[fr
->callno
]->iseqno
!= fr
->oseqno
) &&
6518 (iaxs
[fr
->callno
]->iseqno
||
6519 ((f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6520 (f
.subclass
!= IAX_COMMAND_TXREADY
) && /* for attended transfer */
6521 (f
.subclass
!= IAX_COMMAND_TXREL
) && /* for attended transfer */
6522 (f
.subclass
!= IAX_COMMAND_UNQUELCH
) && /* for attended transfer */
6523 (f
.subclass
!= IAX_COMMAND_TXACC
)) ||
6524 (f
.frametype
!= AST_FRAME_IAX
))) {
6526 ((f
.subclass
!= IAX_COMMAND_ACK
) &&
6527 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
6528 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6529 (f
.subclass
!= IAX_COMMAND_TXREADY
) && /* for attended transfer */
6530 (f
.subclass
!= IAX_COMMAND_TXREL
) && /* for attended transfer */
6531 (f
.subclass
!= IAX_COMMAND_UNQUELCH
) && /* for attended transfer */
6532 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6533 (f
.subclass
!= IAX_COMMAND_VNAK
)) ||
6534 (f
.frametype
!= AST_FRAME_IAX
)) {
6535 /* If it's not an ACK packet, it's out of order. */
6537 ast_log(LOG_DEBUG
, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
6538 iaxs
[fr
->callno
]->iseqno
, fr
->oseqno
, f
.frametype
, f
.subclass
);
6539 if (iaxs
[fr
->callno
]->iseqno
> fr
->oseqno
) {
6540 /* If we've already seen it, ack it XXX There's a border condition here XXX */
6541 if ((f
.frametype
!= AST_FRAME_IAX
) ||
6542 ((f
.subclass
!= IAX_COMMAND_ACK
) && (f
.subclass
!= IAX_COMMAND_INVAL
))) {
6544 ast_log(LOG_DEBUG
, "Acking anyway\n");
6545 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
6546 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
6547 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6550 /* Send a VNAK requesting retransmission */
6551 iax2_vnak(fr
->callno
);
6553 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6557 /* Increment unless it's an ACK or VNAK */
6558 if (((f
.subclass
!= IAX_COMMAND_ACK
) &&
6559 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
6560 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
6561 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
6562 (f
.subclass
!= IAX_COMMAND_VNAK
)) ||
6563 (f
.frametype
!= AST_FRAME_IAX
))
6564 iaxs
[fr
->callno
]->iseqno
++;
6567 if (res
< sizeof(*fh
)) {
6568 ast_log(LOG_WARNING
, "midget packet received (%d of %zd min)\n", res
, sizeof(*fh
));
6569 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6572 f
.datalen
= res
- sizeof(*fh
);
6574 /* Handle implicit ACKing unless this is an INVAL, and only if this is
6575 from the real peer, not the transfer peer */
6576 if (!inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) &&
6577 ((f
.subclass
!= IAX_COMMAND_INVAL
) ||
6578 (f
.frametype
!= AST_FRAME_IAX
))) {
6580 /* XXX This code is not very efficient. Surely there is a better way which still
6581 properly handles boundary conditions? XXX */
6582 /* First we have to qualify that the ACKed value is within our window */
6583 for (x
=iaxs
[fr
->callno
]->rseqno
; x
!= iaxs
[fr
->callno
]->oseqno
; x
++)
6584 if (fr
->iseqno
== x
)
6586 if ((x
!= iaxs
[fr
->callno
]->oseqno
) || (iaxs
[fr
->callno
]->oseqno
== fr
->iseqno
)) {
6587 /* The acknowledgement is within our window. Time to acknowledge everything
6589 for (x
=iaxs
[fr
->callno
]->rseqno
; x
!= fr
->iseqno
; x
++) {
6590 /* Ack the packet with the given timestamp */
6591 if (option_debug
&& iaxdebug
)
6592 ast_log(LOG_DEBUG
, "Cancelling transmission of packet %d\n", x
);
6593 AST_LIST_LOCK(&iaxq
.queue
);
6594 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
6595 /* If it's our call, and our timestamp, mark -1 retries */
6596 if ((fr
->callno
== cur
->callno
) && (x
== cur
->oseqno
)) {
6598 /* Destroy call if this is the end */
6600 if (iaxdebug
&& option_debug
)
6601 ast_log(LOG_DEBUG
, "Really destroying %d, having been acked on final message\n", fr
->callno
);
6602 iax2_destroy(fr
->callno
);
6606 AST_LIST_UNLOCK(&iaxq
.queue
);
6608 /* Note how much we've received acknowledgement for */
6609 if (iaxs
[fr
->callno
])
6610 iaxs
[fr
->callno
]->rseqno
= fr
->iseqno
;
6612 /* Stop processing now */
6613 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6617 ast_log(LOG_DEBUG
, "Received iseqno %d not within window %d->%d\n", fr
->iseqno
, iaxs
[fr
->callno
]->rseqno
, iaxs
[fr
->callno
]->oseqno
);
6619 if (inaddrcmp(&sin
, &iaxs
[fr
->callno
]->addr
) &&
6620 ((f
.frametype
!= AST_FRAME_IAX
) ||
6621 ((f
.subclass
!= IAX_COMMAND_TXACC
) &&
6622 (f
.subclass
!= IAX_COMMAND_TXCNT
)))) {
6623 /* Only messages we accept from a transfer host are TXACC and TXCNT */
6624 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6629 if (f
.frametype
== AST_FRAME_IAX
) {
6630 if (iax_parse_ies(&ies
, thread
->buf
+ sizeof(*fh
), f
.datalen
)) {
6631 ast_log(LOG_WARNING
, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin
.sin_addr
));
6632 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6637 f
.data
= thread
->buf
+ sizeof(*fh
);
6639 if (f
.frametype
== AST_FRAME_IAX
)
6643 memset(&ies
, 0, sizeof(ies
));
6645 if (f
.frametype
== AST_FRAME_VOICE
) {
6646 if (f
.subclass
!= iaxs
[fr
->callno
]->voiceformat
) {
6647 iaxs
[fr
->callno
]->voiceformat
= f
.subclass
;
6648 ast_log(LOG_DEBUG
, "Ooh, voice format changed to %d\n", f
.subclass
);
6649 if (iaxs
[fr
->callno
]->owner
) {
6652 if (ast_mutex_trylock(&iaxs
[fr
->callno
]->owner
->lock
)) {
6653 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6655 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6656 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) goto retryowner
;
6658 if (iaxs
[fr
->callno
]) {
6659 if (iaxs
[fr
->callno
]->owner
) {
6660 orignative
= iaxs
[fr
->callno
]->owner
->nativeformats
;
6661 iaxs
[fr
->callno
]->owner
->nativeformats
= f
.subclass
;
6662 if (iaxs
[fr
->callno
]->owner
->readformat
)
6663 ast_set_read_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->readformat
);
6664 iaxs
[fr
->callno
]->owner
->nativeformats
= orignative
;
6665 ast_mutex_unlock(&iaxs
[fr
->callno
]->owner
->lock
);
6668 ast_log(LOG_DEBUG
, "Neat, somebody took away the channel at a magical time but i found it!\n");
6669 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6675 if (f
.frametype
== AST_FRAME_VIDEO
) {
6676 if (f
.subclass
!= iaxs
[fr
->callno
]->videoformat
) {
6677 ast_log(LOG_DEBUG
, "Ooh, video format changed to %d\n", f
.subclass
& ~0x1);
6678 iaxs
[fr
->callno
]->videoformat
= f
.subclass
& ~0x1;
6681 if (f
.frametype
== AST_FRAME_IAX
) {
6682 if (iaxs
[fr
->callno
]->initid
> -1) {
6683 /* Don't auto congest anymore since we've gotten something usefulb ack */
6684 ast_sched_del(sched
, iaxs
[fr
->callno
]->initid
);
6685 iaxs
[fr
->callno
]->initid
= -1;
6687 /* Handle the IAX pseudo frame itself */
6688 if (option_debug
&& iaxdebug
)
6689 ast_log(LOG_DEBUG
, "IAX subclass %d received\n", f
.subclass
);
6691 /* Update last ts unless the frame's timestamp originated with us. */
6692 if (iaxs
[fr
->callno
]->last
< fr
->ts
&&
6693 f
.subclass
!= IAX_COMMAND_ACK
&&
6694 f
.subclass
!= IAX_COMMAND_PONG
&&
6695 f
.subclass
!= IAX_COMMAND_LAGRP
) {
6696 iaxs
[fr
->callno
]->last
= fr
->ts
;
6697 if (option_debug
&& iaxdebug
)
6698 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
6701 switch(f
.subclass
) {
6702 case IAX_COMMAND_ACK
:
6705 case IAX_COMMAND_QUELCH
:
6706 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6707 /* Generate Manager Hold event, if necessary*/
6708 if (iaxs
[fr
->callno
]->owner
) {
6709 manager_event(EVENT_FLAG_CALL
, "Hold",
6712 iaxs
[fr
->callno
]->owner
->name
,
6713 iaxs
[fr
->callno
]->owner
->uniqueid
);
6716 ast_set_flag(iaxs
[fr
->callno
], IAX_QUELCH
);
6717 if (ies
.musiconhold
) {
6718 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
)) {
6719 const char *mohsuggest
= iaxs
[fr
->callno
]->mohsuggest
;
6720 ast_queue_control_data(iaxs
[fr
->callno
]->owner
, AST_CONTROL_HOLD
,
6721 S_OR(mohsuggest
, NULL
),
6722 !ast_strlen_zero(mohsuggest
) ? strlen(mohsuggest
) + 1 : 0);
6727 case IAX_COMMAND_UNQUELCH
:
6728 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
6729 /* Generate Manager Unhold event, if necessary*/
6730 if (iaxs
[fr
->callno
]->owner
&& ast_test_flag(iaxs
[fr
->callno
], IAX_QUELCH
)) {
6731 manager_event(EVENT_FLAG_CALL
, "Unhold",
6734 iaxs
[fr
->callno
]->owner
->name
,
6735 iaxs
[fr
->callno
]->owner
->uniqueid
);
6738 ast_clear_flag(iaxs
[fr
->callno
], IAX_QUELCH
);
6739 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
))
6740 ast_queue_control(iaxs
[fr
->callno
]->owner
, AST_CONTROL_UNHOLD
);
6743 case IAX_COMMAND_TXACC
:
6744 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_BEGIN
) {
6745 /* Ack the packet with the given timestamp */
6746 AST_LIST_LOCK(&iaxq
.queue
);
6747 AST_LIST_TRAVERSE(&iaxq
.queue
, cur
, list
) {
6748 /* Cancel any outstanding txcnt's */
6749 if ((fr
->callno
== cur
->callno
) && (cur
->transfer
))
6752 AST_LIST_UNLOCK(&iaxq
.queue
);
6753 memset(&ied1
, 0, sizeof(ied1
));
6754 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->callno
);
6755 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREADY
, 0, ied1
.buf
, ied1
.pos
, -1);
6756 iaxs
[fr
->callno
]->transferring
= TRANSFER_READY
;
6759 case IAX_COMMAND_NEW
:
6760 /* Ignore if it's already up */
6761 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
))
6763 if (ies
.provverpres
&& ies
.serviceident
&& sin
.sin_addr
.s_addr
)
6764 check_provisioning(&sin
, fd
, ies
.serviceident
, ies
.provver
);
6765 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
6766 if (ast_test_flag(iaxs
[fr
->callno
], IAX_TRUNK
)) {
6767 fr
->callno
= make_trunk(fr
->callno
, 1);
6769 /* For security, always ack immediately */
6771 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6772 if (check_access(fr
->callno
, &sin
, &ies
)) {
6773 /* They're not allowed on */
6774 auth_fail(fr
->callno
, IAX_COMMAND_REJECT
);
6776 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
);
6779 /* This might re-enter the IAX code and need the lock */
6780 if (strcasecmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
6781 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
6782 exists
= ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
);
6783 ast_mutex_lock(&iaxsl
[fr
->callno
]);
6786 if (ast_strlen_zero(iaxs
[fr
->callno
]->secret
) && ast_strlen_zero(iaxs
[fr
->callno
]->inkeys
)) {
6787 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD") && !exists
) {
6788 memset(&ied0
, 0, sizeof(ied0
));
6789 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
6790 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
6791 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6793 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
);
6795 /* Select an appropriate format */
6797 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
6798 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
6799 using_prefs
= "reqonly";
6801 using_prefs
= "disabled";
6803 format
= iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
;
6804 memset(&pref
, 0, sizeof(pref
));
6805 strcpy(caller_pref_buf
, "disabled");
6806 strcpy(host_pref_buf
, "disabled");
6808 using_prefs
= "mine";
6809 /* If the information elements are in here... use them */
6810 if (ies
.codec_prefs
)
6811 ast_codec_pref_convert(&iaxs
[fr
->callno
]->rprefs
, ies
.codec_prefs
, 32, 0);
6812 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
6813 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
6814 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
6815 pref
= iaxs
[fr
->callno
]->rprefs
;
6816 using_prefs
= "caller";
6818 pref
= iaxs
[fr
->callno
]->prefs
;
6821 pref
= iaxs
[fr
->callno
]->prefs
;
6823 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->capability
& iaxs
[fr
->callno
]->peercapability
, 0);
6824 ast_codec_pref_string(&iaxs
[fr
->callno
]->rprefs
, caller_pref_buf
, sizeof(caller_pref_buf
) - 1);
6825 ast_codec_pref_string(&iaxs
[fr
->callno
]->prefs
, host_pref_buf
, sizeof(host_pref_buf
) - 1);
6828 if(!ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
6829 format
= iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
;
6831 memset(&ied0
, 0, sizeof(ied0
));
6832 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
6833 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
6834 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6836 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
6837 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
);
6839 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
);
6843 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
6844 if(!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
))
6847 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
6848 using_prefs
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ? "reqonly" : "disabled";
6849 memset(&pref
, 0, sizeof(pref
));
6850 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6851 strcpy(caller_pref_buf
,"disabled");
6852 strcpy(host_pref_buf
,"disabled");
6854 using_prefs
= "mine";
6855 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
6856 /* Do the opposite of what we tried above. */
6857 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
6858 pref
= iaxs
[fr
->callno
]->prefs
;
6860 pref
= iaxs
[fr
->callno
]->rprefs
;
6861 using_prefs
= "caller";
6863 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
, 1);
6865 } else /* if no codec_prefs IE do it the old way */
6866 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6871 memset(&ied0
, 0, sizeof(ied0
));
6872 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
6873 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
6874 ast_log(LOG_ERROR
, "No best format in 0x%x???\n", iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
6875 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
6877 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
);
6878 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
6884 /* No authentication required, let them in */
6885 memset(&ied1
, 0, sizeof(ied1
));
6886 iax_ie_append_int(&ied1
, IAX_IE_FORMAT
, format
);
6887 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACCEPT
, 0, ied1
.buf
, ied1
.pos
, -1);
6888 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
6889 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
6890 if (option_verbose
> 2)
6891 ast_verbose(VERBOSE_PREFIX_3
"Accepting UNAUTHENTICATED call from %s:\n"
6892 "%srequested format = %s,\n"
6893 "%srequested prefs = %s,\n"
6894 "%sactual format = %s,\n"
6895 "%shost prefs = %s,\n"
6896 "%spriority = %s\n",
6897 ast_inet_ntoa(sin
.sin_addr
),
6899 ast_getformatname(iaxs
[fr
->callno
]->peerformat
),
6903 ast_getformatname(format
),
6909 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, format
)))
6910 iax2_destroy(fr
->callno
);
6912 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
6913 /* If this is a TBD call, we're ready but now what... */
6914 if (option_verbose
> 2)
6915 ast_verbose(VERBOSE_PREFIX_3
"Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin
.sin_addr
));
6921 if (iaxs
[fr
->callno
]->authmethods
& IAX_AUTH_MD5
)
6922 merge_encryption(iaxs
[fr
->callno
],ies
.encmethods
);
6924 iaxs
[fr
->callno
]->encmethods
= 0;
6925 if (!authenticate_request(iaxs
[fr
->callno
]))
6926 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_AUTHENTICATED
);
6928 case IAX_COMMAND_DPREQ
:
6929 /* Request status in the dialplan */
6930 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
) &&
6931 !ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
) && ies
.called_number
) {
6933 /* Spawn a thread for the lookup */
6934 spawn_dp_lookup(fr
->callno
, iaxs
[fr
->callno
]->context
, ies
.called_number
, iaxs
[fr
->callno
]->cid_num
);
6936 /* Just look it up */
6937 dp_lookup(fr
->callno
, iaxs
[fr
->callno
]->context
, ies
.called_number
, iaxs
[fr
->callno
]->cid_num
, 1);
6941 case IAX_COMMAND_HANGUP
:
6942 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
6943 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received hangup\n", fr
->callno
);
6944 /* Set hangup cause according to remote */
6945 if (ies
.causecode
&& iaxs
[fr
->callno
]->owner
)
6946 iaxs
[fr
->callno
]->owner
->hangupcause
= ies
.causecode
;
6947 /* Send ack immediately, before we destroy */
6948 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6949 iax2_destroy(fr
->callno
);
6951 case IAX_COMMAND_REJECT
:
6952 /* Set hangup cause according to remote */
6953 if (ies
.causecode
&& iaxs
[fr
->callno
]->owner
)
6954 iaxs
[fr
->callno
]->owner
->hangupcause
= ies
.causecode
;
6956 if (!ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
)) {
6957 if (iaxs
[fr
->callno
]->owner
&& authdebug
)
6958 ast_log(LOG_WARNING
, "Call rejected by %s: %s\n",
6959 ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
),
6960 ies
.cause
? ies
.cause
: "<Unknown>");
6961 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received reject\n",
6964 /* Send ack immediately, before we destroy */
6965 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
,
6966 fr
->ts
, NULL
, 0, fr
->iseqno
);
6967 if (!ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
))
6968 iaxs
[fr
->callno
]->error
= EPERM
;
6969 iax2_destroy(fr
->callno
);
6971 case IAX_COMMAND_TRANSFER
:
6972 if (iaxs
[fr
->callno
]->owner
&& ast_bridged_channel(iaxs
[fr
->callno
]->owner
) && ies
.called_number
) {
6973 /* Set BLINDTRANSFER channel variables */
6974 pbx_builtin_setvar_helper(iaxs
[fr
->callno
]->owner
, "BLINDTRANSFER", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
6975 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), "BLINDTRANSFER", iaxs
[fr
->callno
]->owner
->name
);
6976 if (!strcmp(ies
.called_number
, ast_parking_ext())) {
6977 if (iax_park(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), iaxs
[fr
->callno
]->owner
)) {
6978 ast_log(LOG_WARNING
, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
6979 } else if (ast_bridged_channel(iaxs
[fr
->callno
]->owner
))
6980 ast_log(LOG_DEBUG
, "Parked call on '%s'\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
);
6982 if (ast_async_goto(ast_bridged_channel(iaxs
[fr
->callno
]->owner
), iaxs
[fr
->callno
]->context
, ies
.called_number
, 1))
6983 ast_log(LOG_WARNING
, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
,
6984 ies
.called_number
, iaxs
[fr
->callno
]->context
);
6986 ast_log(LOG_DEBUG
, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs
[fr
->callno
]->owner
)->name
,
6987 ies
.called_number
, iaxs
[fr
->callno
]->context
);
6990 ast_log(LOG_DEBUG
, "Async goto not applicable on call %d\n", fr
->callno
);
6992 case IAX_COMMAND_ACCEPT
:
6993 /* Ignore if call is already up or needs authentication or is a TBD */
6994 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
| IAX_STATE_AUTHENTICATED
))
6996 if (ast_test_flag(iaxs
[fr
->callno
], IAX_PROVISION
)) {
6997 /* Send ack immediately, before we destroy */
6998 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
6999 iax2_destroy(fr
->callno
);
7003 iaxs
[fr
->callno
]->peerformat
= ies
.format
;
7005 if (iaxs
[fr
->callno
]->owner
)
7006 iaxs
[fr
->callno
]->peerformat
= iaxs
[fr
->callno
]->owner
->nativeformats
;
7008 iaxs
[fr
->callno
]->peerformat
= iaxs
[fr
->callno
]->capability
;
7010 if (option_verbose
> 2)
7011 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
));
7012 if (!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
)) {
7013 memset(&ied0
, 0, sizeof(ied0
));
7014 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7015 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7016 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7018 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
);
7020 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7021 if (iaxs
[fr
->callno
]->owner
) {
7022 /* Switch us to use a compatible format */
7023 iaxs
[fr
->callno
]->owner
->nativeformats
= iaxs
[fr
->callno
]->peerformat
;
7024 if (option_verbose
> 2)
7025 ast_verbose(VERBOSE_PREFIX_3
"Format for call is %s\n", ast_getformatname(iaxs
[fr
->callno
]->owner
->nativeformats
));
7027 if (ast_mutex_trylock(&iaxs
[fr
->callno
]->owner
->lock
)) {
7028 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7030 ast_mutex_lock(&iaxsl
[fr
->callno
]);
7031 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) goto retryowner2
;
7034 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->owner
) {
7035 /* Setup read/write formats properly. */
7036 if (iaxs
[fr
->callno
]->owner
->writeformat
)
7037 ast_set_write_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->writeformat
);
7038 if (iaxs
[fr
->callno
]->owner
->readformat
)
7039 ast_set_read_format(iaxs
[fr
->callno
]->owner
, iaxs
[fr
->callno
]->owner
->readformat
);
7040 ast_mutex_unlock(&iaxs
[fr
->callno
]->owner
->lock
);
7044 if (iaxs
[fr
->callno
]) {
7045 ast_mutex_lock(&dpcache_lock
);
7046 dp
= iaxs
[fr
->callno
]->dpentries
;
7048 if (!(dp
->flags
& CACHE_FLAG_TRANSMITTED
)) {
7049 iax2_dprequest(dp
, fr
->callno
);
7053 ast_mutex_unlock(&dpcache_lock
);
7056 case IAX_COMMAND_POKE
:
7057 /* Send back a pong packet with the original timestamp */
7058 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_PONG
, fr
->ts
, NULL
, 0, -1);
7060 case IAX_COMMAND_PING
:
7062 struct iax_ie_data pingied
;
7063 construct_rr(iaxs
[fr
->callno
], &pingied
);
7064 /* Send back a pong packet with the original timestamp */
7065 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_PONG
, fr
->ts
, pingied
.buf
, pingied
.pos
, -1);
7068 case IAX_COMMAND_PONG
:
7069 /* Calculate ping time */
7070 iaxs
[fr
->callno
]->pingtime
= calc_timestamp(iaxs
[fr
->callno
], 0, &f
) - fr
->ts
;
7074 if (iaxs
[fr
->callno
]->peerpoke
) {
7075 peer
= iaxs
[fr
->callno
]->peerpoke
;
7076 if ((peer
->lastms
< 0) || (peer
->historicms
> peer
->maxms
)) {
7077 if (iaxs
[fr
->callno
]->pingtime
<= peer
->maxms
) {
7078 ast_log(LOG_NOTICE
, "Peer '%s' is now REACHABLE! Time: %d\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7079 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7080 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7082 } else if ((peer
->historicms
> 0) && (peer
->historicms
<= peer
->maxms
)) {
7083 if (iaxs
[fr
->callno
]->pingtime
> peer
->maxms
) {
7084 ast_log(LOG_NOTICE
, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7085 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer
->name
, iaxs
[fr
->callno
]->pingtime
);
7086 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7089 peer
->lastms
= iaxs
[fr
->callno
]->pingtime
;
7090 if (peer
->smoothing
&& (peer
->lastms
> -1))
7091 peer
->historicms
= (iaxs
[fr
->callno
]->pingtime
+ peer
->historicms
) / 2;
7092 else if (peer
->smoothing
&& peer
->lastms
< 0)
7093 peer
->historicms
= (0 + peer
->historicms
) / 2;
7095 peer
->historicms
= iaxs
[fr
->callno
]->pingtime
;
7097 /* Remove scheduled iax2_poke_noanswer */
7098 if (peer
->pokeexpire
> -1)
7099 ast_sched_del(sched
, peer
->pokeexpire
);
7100 /* Schedule the next cycle */
7101 if ((peer
->lastms
< 0) || (peer
->historicms
> peer
->maxms
))
7102 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_peer_s
, peer
);
7104 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqok
, iax2_poke_peer_s
, peer
);
7105 /* and finally send the ack */
7106 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7107 /* And wrap up the qualify call */
7108 iax2_destroy(fr
->callno
);
7111 ast_log(LOG_DEBUG
, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer
->name
, peer
->lastms
, peer
->historicms
, peer
->maxms
);
7114 case IAX_COMMAND_LAGRQ
:
7115 case IAX_COMMAND_LAGRP
:
7120 iax_frame_wrap(fr
, &f
);
7121 if(f
.subclass
== IAX_COMMAND_LAGRQ
) {
7122 /* Received a LAGRQ - echo back a LAGRP */
7123 fr
->af
.subclass
= IAX_COMMAND_LAGRP
;
7124 iax2_send(iaxs
[fr
->callno
], &fr
->af
, fr
->ts
, -1, 0, 0, 0);
7126 /* Received LAGRP in response to our LAGRQ */
7128 /* This is a reply we've been given, actually measure the difference */
7129 ts
= calc_timestamp(iaxs
[fr
->callno
], 0, &fr
->af
);
7130 iaxs
[fr
->callno
]->lag
= ts
- fr
->ts
;
7131 if (option_debug
&& iaxdebug
)
7132 ast_log(LOG_DEBUG
, "Peer %s lag measured as %dms\n",
7133 ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
), iaxs
[fr
->callno
]->lag
);
7136 case IAX_COMMAND_AUTHREQ
:
7137 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
)) {
7138 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>");
7141 if (authenticate_reply(iaxs
[fr
->callno
], &iaxs
[fr
->callno
]->addr
, &ies
, iaxs
[fr
->callno
]->secret
, iaxs
[fr
->callno
]->outkey
)) {
7142 ast_log(LOG_WARNING
,
7143 "I don't know how to authenticate %s to %s\n",
7144 ies
.username
? ies
.username
: "<unknown>", ast_inet_ntoa(iaxs
[fr
->callno
]->addr
.sin_addr
));
7147 case IAX_COMMAND_AUTHREP
:
7148 /* For security, always ack immediately */
7150 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7151 /* Ignore once we've started */
7152 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
| IAX_STATE_TBD
)) {
7153 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>");
7156 if (authenticate_verify(iaxs
[fr
->callno
], &ies
)) {
7158 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
);
7159 memset(&ied0
, 0, sizeof(ied0
));
7160 auth_fail(fr
->callno
, IAX_COMMAND_REJECT
);
7163 if (strcasecmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
7164 /* This might re-enter the IAX code and need the lock */
7165 exists
= ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
);
7168 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD") && !exists
) {
7170 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
);
7171 memset(&ied0
, 0, sizeof(ied0
));
7172 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
7173 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
7174 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7176 /* Select an appropriate format */
7177 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
7178 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7179 using_prefs
= "reqonly";
7181 using_prefs
= "disabled";
7183 format
= iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
;
7184 memset(&pref
, 0, sizeof(pref
));
7185 strcpy(caller_pref_buf
, "disabled");
7186 strcpy(host_pref_buf
, "disabled");
7188 using_prefs
= "mine";
7189 if (ies
.codec_prefs
)
7190 ast_codec_pref_convert(&iaxs
[fr
->callno
]->rprefs
, ies
.codec_prefs
, 32, 0);
7191 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
7192 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
7193 pref
= iaxs
[fr
->callno
]->rprefs
;
7194 using_prefs
= "caller";
7196 pref
= iaxs
[fr
->callno
]->prefs
;
7198 } else /* if no codec_prefs IE do it the old way */
7199 pref
= iaxs
[fr
->callno
]->prefs
;
7201 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->capability
& iaxs
[fr
->callno
]->peercapability
, 0);
7202 ast_codec_pref_string(&iaxs
[fr
->callno
]->rprefs
, caller_pref_buf
, sizeof(caller_pref_buf
) - 1);
7203 ast_codec_pref_string(&iaxs
[fr
->callno
]->prefs
, host_pref_buf
, sizeof(host_pref_buf
) - 1);
7206 if(!ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7207 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
);
7208 format
= iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
;
7212 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
7213 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
);
7215 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
);
7217 memset(&ied0
, 0, sizeof(ied0
));
7218 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7219 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7220 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7223 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
)) {
7224 if(!(iaxs
[fr
->callno
]->peerformat
& iaxs
[fr
->callno
]->capability
))
7227 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOPREFS
)) {
7228 using_prefs
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ? "reqonly" : "disabled";
7229 memset(&pref
, 0, sizeof(pref
));
7230 format
= ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
) ?
7231 iaxs
[fr
->callno
]->peerformat
: ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7232 strcpy(caller_pref_buf
,"disabled");
7233 strcpy(host_pref_buf
,"disabled");
7235 using_prefs
= "mine";
7236 if (ast_codec_pref_index(&iaxs
[fr
->callno
]->rprefs
, 0)) {
7237 /* Do the opposite of what we tried above. */
7238 if (ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_USER_FIRST
)) {
7239 pref
= iaxs
[fr
->callno
]->prefs
;
7241 pref
= iaxs
[fr
->callno
]->rprefs
;
7242 using_prefs
= "caller";
7244 format
= ast_codec_choose(&pref
, iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
, 1);
7245 } else /* if no codec_prefs IE do it the old way */
7246 format
= ast_best_codec(iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7250 ast_log(LOG_ERROR
, "No best format in 0x%x???\n", iaxs
[fr
->callno
]->peercapability
& iaxs
[fr
->callno
]->capability
);
7252 if(ast_test_flag(iaxs
[fr
->callno
], IAX_CODEC_NOCAP
))
7253 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
);
7255 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
);
7257 memset(&ied0
, 0, sizeof(ied0
));
7258 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "Unable to negotiate codec");
7259 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
);
7260 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7265 /* Authentication received */
7266 memset(&ied1
, 0, sizeof(ied1
));
7267 iax_ie_append_int(&ied1
, IAX_IE_FORMAT
, format
);
7268 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACCEPT
, 0, ied1
.buf
, ied1
.pos
, -1);
7269 if (strcmp(iaxs
[fr
->callno
]->exten
, "TBD")) {
7270 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7271 if (option_verbose
> 2)
7272 ast_verbose(VERBOSE_PREFIX_3
"Accepting AUTHENTICATED call from %s:\n"
7273 "%srequested format = %s,\n"
7274 "%srequested prefs = %s,\n"
7275 "%sactual format = %s,\n"
7276 "%shost prefs = %s,\n"
7277 "%spriority = %s\n",
7278 ast_inet_ntoa(sin
.sin_addr
),
7280 ast_getformatname(iaxs
[fr
->callno
]->peerformat
),
7284 ast_getformatname(format
),
7290 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7291 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, format
)))
7292 iax2_destroy(fr
->callno
);
7294 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
7295 /* If this is a TBD call, we're ready but now what... */
7296 if (option_verbose
> 2)
7297 ast_verbose(VERBOSE_PREFIX_3
"Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin
.sin_addr
));
7302 case IAX_COMMAND_DIAL
:
7303 if (ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
)) {
7304 ast_clear_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_TBD
);
7305 ast_string_field_set(iaxs
[fr
->callno
], exten
, ies
.called_number
? ies
.called_number
: "s");
7306 if (!ast_exists_extension(NULL
, iaxs
[fr
->callno
]->context
, iaxs
[fr
->callno
]->exten
, 1, iaxs
[fr
->callno
]->cid_num
)) {
7308 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
);
7309 memset(&ied0
, 0, sizeof(ied0
));
7310 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No such context/extension");
7311 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_NO_ROUTE_DESTINATION
);
7312 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7314 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7315 if (option_verbose
> 2)
7316 ast_verbose(VERBOSE_PREFIX_3
"Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin
.sin_addr
), iaxs
[fr
->callno
]->peerformat
);
7317 ast_set_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
);
7318 send_command(iaxs
[fr
->callno
], AST_FRAME_CONTROL
, AST_CONTROL_PROGRESS
, 0, NULL
, 0, -1);
7319 if(!(c
= ast_iax2_new(fr
->callno
, AST_STATE_RING
, iaxs
[fr
->callno
]->peerformat
)))
7320 iax2_destroy(fr
->callno
);
7324 case IAX_COMMAND_INVAL
:
7325 iaxs
[fr
->callno
]->error
= ENOTCONN
;
7326 ast_log(LOG_DEBUG
, "Immediately destroying %d, having received INVAL\n", fr
->callno
);
7327 iax2_destroy(fr
->callno
);
7329 ast_log(LOG_DEBUG
, "Destroying call %d\n", fr
->callno
);
7331 case IAX_COMMAND_VNAK
:
7332 ast_log(LOG_DEBUG
, "Received VNAK: resending outstanding frames\n");
7333 /* Force retransmission */
7334 vnak_retransmit(fr
->callno
, fr
->iseqno
);
7336 case IAX_COMMAND_REGREQ
:
7337 case IAX_COMMAND_REGREL
:
7338 /* For security, always ack immediately */
7340 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7341 if (register_verify(fr
->callno
, &sin
, &ies
)) {
7342 /* Send delayed failure */
7343 auth_fail(fr
->callno
, IAX_COMMAND_REGREJ
);
7346 if ((ast_strlen_zero(iaxs
[fr
->callno
]->secret
) && ast_strlen_zero(iaxs
[fr
->callno
]->inkeys
)) ||
7347 ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_AUTHENTICATED
| IAX_STATE_UNCHANGED
)) {
7348 if (f
.subclass
== IAX_COMMAND_REGREL
)
7349 memset(&sin
, 0, sizeof(sin
));
7350 if (update_registry(iaxs
[fr
->callno
]->peer
, &sin
, fr
->callno
, ies
.devicetype
, fd
, ies
.refresh
))
7351 ast_log(LOG_WARNING
, "Registry error\n");
7352 if (ies
.provverpres
&& ies
.serviceident
&& sin
.sin_addr
.s_addr
)
7353 check_provisioning(&sin
, fd
, ies
.serviceident
, ies
.provver
);
7356 registry_authrequest(iaxs
[fr
->callno
]->peer
, fr
->callno
);
7358 case IAX_COMMAND_REGACK
:
7359 if (iax2_ack_registry(&ies
, &sin
, fr
->callno
))
7360 ast_log(LOG_WARNING
, "Registration failure\n");
7361 /* Send ack immediately, before we destroy */
7362 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7363 iax2_destroy(fr
->callno
);
7365 case IAX_COMMAND_REGREJ
:
7366 if (iaxs
[fr
->callno
]->reg
) {
7368 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
));
7369 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>");
7371 iaxs
[fr
->callno
]->reg
->regstate
= REG_STATE_REJECTED
;
7373 /* Send ack immediately, before we destroy */
7374 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7375 iax2_destroy(fr
->callno
);
7377 case IAX_COMMAND_REGAUTH
:
7378 /* Authentication request */
7379 if (registry_rerequest(&ies
, fr
->callno
, &sin
)) {
7380 memset(&ied0
, 0, sizeof(ied0
));
7381 iax_ie_append_str(&ied0
, IAX_IE_CAUSE
, "No authority found");
7382 iax_ie_append_byte(&ied0
, IAX_IE_CAUSECODE
, AST_CAUSE_FACILITY_NOT_SUBSCRIBED
);
7383 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7386 case IAX_COMMAND_TXREJ
:
7387 iaxs
[fr
->callno
]->transferring
= 0;
7388 if (option_verbose
> 2)
7389 ast_verbose(VERBOSE_PREFIX_3
"Channel '%s' unable to transfer\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>");
7390 memset(&iaxs
[fr
->callno
]->transfer
, 0, sizeof(iaxs
[fr
->callno
]->transfer
));
7391 if (iaxs
[fr
->callno
]->bridgecallno
) {
7392 if (iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
) {
7393 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= 0;
7394 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXREJ
, 0, NULL
, 0, -1);
7398 case IAX_COMMAND_TXREADY
:
7399 if ((iaxs
[fr
->callno
]->transferring
== TRANSFER_BEGIN
) ||
7400 (iaxs
[fr
->callno
]->transferring
== TRANSFER_MBEGIN
)) {
7401 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_MBEGIN
)
7402 iaxs
[fr
->callno
]->transferring
= TRANSFER_MREADY
;
7404 iaxs
[fr
->callno
]->transferring
= TRANSFER_READY
;
7405 if (option_verbose
> 2)
7406 ast_verbose(VERBOSE_PREFIX_3
"Channel '%s' ready to transfer\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>");
7407 if (iaxs
[fr
->callno
]->bridgecallno
) {
7408 if ((iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
== TRANSFER_READY
) ||
7409 (iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
== TRANSFER_MREADY
)) {
7410 /* They're both ready, now release them. */
7411 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_MREADY
) {
7412 if (option_verbose
> 2)
7413 ast_verbose(VERBOSE_PREFIX_3
"Attempting media bridge of %s and %s\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>",
7414 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
? iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
->name
: "<Unknown>");
7416 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= TRANSFER_MEDIA
;
7417 iaxs
[fr
->callno
]->transferring
= TRANSFER_MEDIA
;
7419 memset(&ied0
, 0, sizeof(ied0
));
7420 memset(&ied1
, 0, sizeof(ied1
));
7421 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->peercallno
);
7422 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->peercallno
);
7423 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXMEDIA
, 0, ied0
.buf
, ied0
.pos
, -1);
7424 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXMEDIA
, 0, ied1
.buf
, ied1
.pos
, -1);
7426 if (option_verbose
> 2)
7427 ast_verbose(VERBOSE_PREFIX_3
"Releasing %s and %s\n", iaxs
[fr
->callno
]->owner
? iaxs
[fr
->callno
]->owner
->name
: "<Unknown>",
7428 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
? iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->owner
->name
: "<Unknown>");
7430 iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->transferring
= TRANSFER_RELEASED
;
7431 iaxs
[fr
->callno
]->transferring
= TRANSFER_RELEASED
;
7432 ast_set_flag(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], IAX_ALREADYGONE
);
7433 ast_set_flag(iaxs
[fr
->callno
], IAX_ALREADYGONE
);
7435 /* Stop doing lag & ping requests */
7436 stop_stuff(fr
->callno
);
7437 stop_stuff(iaxs
[fr
->callno
]->bridgecallno
);
7439 memset(&ied0
, 0, sizeof(ied0
));
7440 memset(&ied1
, 0, sizeof(ied1
));
7441 iax_ie_append_short(&ied0
, IAX_IE_CALLNO
, iaxs
[iaxs
[fr
->callno
]->bridgecallno
]->peercallno
);
7442 iax_ie_append_short(&ied1
, IAX_IE_CALLNO
, iaxs
[fr
->callno
]->peercallno
);
7443 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXREL
, 0, ied0
.buf
, ied0
.pos
, -1);
7444 send_command(iaxs
[iaxs
[fr
->callno
]->bridgecallno
], AST_FRAME_IAX
, IAX_COMMAND_TXREL
, 0, ied1
.buf
, ied1
.pos
, -1);
7451 case IAX_COMMAND_TXREQ
:
7452 try_transfer(iaxs
[fr
->callno
], &ies
);
7454 case IAX_COMMAND_TXCNT
:
7455 if (iaxs
[fr
->callno
]->transferring
)
7456 send_command_transfer(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_TXACC
, 0, NULL
, 0);
7458 case IAX_COMMAND_TXREL
:
7459 /* Send ack immediately, rather than waiting until we've changed addresses */
7460 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7461 complete_transfer(fr
->callno
, &ies
);
7462 stop_stuff(fr
->callno
); /* for attended transfer to work with libiax */
7464 case IAX_COMMAND_TXMEDIA
:
7465 if (iaxs
[fr
->callno
]->transferring
== TRANSFER_READY
) {
7466 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
7467 iaxs
[fr
->callno
]->transferring
= TRANSFER_MEDIAPASS
;
7470 case IAX_COMMAND_DPREP
:
7471 complete_dpreply(iaxs
[fr
->callno
], &ies
);
7473 case IAX_COMMAND_UNSUPPORT
:
7474 ast_log(LOG_NOTICE
, "Peer did not understand our iax command '%d'\n", ies
.iax_unknown
);
7476 case IAX_COMMAND_FWDOWNL
:
7477 /* Firmware download */
7478 memset(&ied0
, 0, sizeof(ied0
));
7479 res
= iax_firmware_append(&ied0
, (unsigned char *)ies
.devicetype
, ies
.fwdesc
);
7481 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_REJECT
, 0, ied0
.buf
, ied0
.pos
, -1);
7483 send_command_final(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_FWDATA
, 0, ied0
.buf
, ied0
.pos
, -1);
7485 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_FWDATA
, 0, ied0
.buf
, ied0
.pos
, -1);
7488 ast_log(LOG_DEBUG
, "Unknown IAX command %d on %d/%d\n", f
.subclass
, fr
->callno
, iaxs
[fr
->callno
]->peercallno
);
7489 memset(&ied0
, 0, sizeof(ied0
));
7490 iax_ie_append_byte(&ied0
, IAX_IE_IAX_UNKNOWN
, f
.subclass
);
7491 send_command(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_UNSUPPORT
, 0, ied0
.buf
, ied0
.pos
, -1);
7493 /* Don't actually pass these frames along */
7494 if ((f
.subclass
!= IAX_COMMAND_ACK
) &&
7495 (f
.subclass
!= IAX_COMMAND_TXCNT
) &&
7496 (f
.subclass
!= IAX_COMMAND_TXACC
) &&
7497 (f
.subclass
!= IAX_COMMAND_INVAL
) &&
7498 (f
.subclass
!= IAX_COMMAND_VNAK
)) {
7499 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->aseqno
!= iaxs
[fr
->callno
]->iseqno
)
7500 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7502 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7505 /* Unless this is an ACK or INVAL frame, ack it */
7506 if (iaxs
[fr
->callno
]->aseqno
!= iaxs
[fr
->callno
]->iseqno
)
7507 send_command_immediate(iaxs
[fr
->callno
], AST_FRAME_IAX
, IAX_COMMAND_ACK
, fr
->ts
, NULL
, 0,fr
->iseqno
);
7508 } else if (minivid
) {
7509 f
.frametype
= AST_FRAME_VIDEO
;
7510 if (iaxs
[fr
->callno
]->videoformat
> 0)
7511 f
.subclass
= iaxs
[fr
->callno
]->videoformat
| (ntohs(vh
->ts
) & 0x8000 ? 1 : 0);
7513 ast_log(LOG_WARNING
, "Received mini frame before first full video frame\n ");
7514 iax2_vnak(fr
->callno
);
7515 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7518 f
.datalen
= res
- sizeof(*vh
);
7520 f
.data
= thread
->buf
+ sizeof(*vh
);
7525 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF8000L
) | ((ntohs(vh
->ts
) + test_resync
) & 0x7fff);
7527 #endif /* IAXTESTS */
7528 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF8000L
) | (ntohs(vh
->ts
) & 0x7fff);
7531 f
.frametype
= AST_FRAME_VOICE
;
7532 if (iaxs
[fr
->callno
]->voiceformat
> 0)
7533 f
.subclass
= iaxs
[fr
->callno
]->voiceformat
;
7535 ast_log(LOG_WARNING
, "Received mini frame before first full voice frame\n ");
7536 iax2_vnak(fr
->callno
);
7537 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7540 f
.datalen
= res
- sizeof(struct ast_iax2_mini_hdr
);
7541 if (f
.datalen
< 0) {
7542 ast_log(LOG_WARNING
, "Datalen < 0?\n");
7543 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7547 f
.data
= thread
->buf
+ sizeof(*mh
);
7552 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | ((ntohs(mh
->ts
) + test_resync
) & 0xffff);
7554 #endif /* IAXTESTS */
7555 fr
->ts
= (iaxs
[fr
->callno
]->last
& 0xFFFF0000L
) | ntohs(mh
->ts
);
7556 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
7558 /* Don't pass any packets until we're started */
7559 if (!ast_test_flag(&iaxs
[fr
->callno
]->state
, IAX_STATE_STARTED
)) {
7560 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7568 if (f
.datalen
&& (f
.frametype
== AST_FRAME_VOICE
)) {
7569 f
.samples
= ast_codec_get_samples(&f
);
7570 /* We need to byteswap incoming slinear samples from network byte order */
7571 if (f
.subclass
== AST_FORMAT_SLINEAR
)
7572 ast_frame_byteswap_be(&f
);
7575 iax_frame_wrap(fr
, &f
);
7577 /* If this is our most recent packet, use it as our basis for timestamping */
7578 if (iaxs
[fr
->callno
]->last
< fr
->ts
) {
7579 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
7582 if (option_debug
&& iaxdebug
)
7583 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
);
7584 fr
->outoforder
= -1;
7586 duped_fr
= iaxfrdup2(fr
);
7588 schedule_delivery(duped_fr
, updatehistory
, 0, &fr
->ts
);
7590 if (iaxs
[fr
->callno
] && iaxs
[fr
->callno
]->last
< fr
->ts
) {
7591 iaxs
[fr
->callno
]->last
= fr
->ts
;
7593 if (option_debug
&& iaxdebug
)
7594 ast_log(LOG_DEBUG
, "For call=%d, set last=%d\n", fr
->callno
, fr
->ts
);
7598 /* Always run again */
7599 ast_mutex_unlock(&iaxsl
[fr
->callno
]);
7603 /* Function to clean up process thread if it is cancelled */
7604 static void iax2_process_thread_cleanup(void *data
)
7606 struct iax2_thread
*thread
= data
;
7607 ast_mutex_destroy(&thread
->lock
);
7608 ast_cond_destroy(&thread
->cond
);
7610 ast_atomic_dec_and_test(&iaxactivethreadcount
);
7613 static void *iax2_process_thread(void *data
)
7615 struct iax2_thread
*thread
= data
;
7618 int put_into_idle
= 0;
7620 ast_atomic_fetchadd_int(&iaxactivethreadcount
,1);
7621 pthread_cleanup_push(iax2_process_thread_cleanup
, data
);
7623 /* Wait for something to signal us to be awake */
7624 ast_mutex_lock(&thread
->lock
);
7626 /* Put into idle list if applicable */
7628 insert_idle_thread(thread
);
7630 if (thread
->type
== IAX_TYPE_DYNAMIC
) {
7631 /* Wait to be signalled or time out */
7632 tv
= ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
7633 ts
.tv_sec
= tv
.tv_sec
;
7634 ts
.tv_nsec
= tv
.tv_usec
* 1000;
7635 if (ast_cond_timedwait(&thread
->cond
, &thread
->lock
, &ts
) == ETIMEDOUT
) {
7636 ast_mutex_unlock(&thread
->lock
);
7637 AST_LIST_LOCK(&dynamic_list
);
7638 AST_LIST_REMOVE(&dynamic_list
, thread
, list
);
7639 iaxdynamicthreadcount
--;
7640 AST_LIST_UNLOCK(&dynamic_list
);
7641 break; /* exiting the main loop */
7644 ast_cond_wait(&thread
->cond
, &thread
->lock
);
7646 ast_mutex_unlock(&thread
->lock
);
7648 /* Add ourselves to the active list now */
7649 AST_LIST_LOCK(&active_list
);
7650 AST_LIST_INSERT_HEAD(&active_list
, thread
, list
);
7651 AST_LIST_UNLOCK(&active_list
);
7653 /* See what we need to do */
7654 switch(thread
->iostate
) {
7655 case IAX_IOSTATE_READY
:
7657 thread
->iostate
= IAX_IOSTATE_PROCESSING
;
7658 socket_process(thread
);
7660 case IAX_IOSTATE_SCHEDREADY
:
7662 thread
->iostate
= IAX_IOSTATE_PROCESSING
;
7663 #ifdef SCHED_MULTITHREADED
7664 thread
->schedfunc(thread
->scheddata
);
7668 time(&thread
->checktime
);
7669 thread
->iostate
= IAX_IOSTATE_IDLE
;
7670 #ifdef DEBUG_SCHED_MULTITHREAD
7671 thread
->curfunc
[0]='\0';
7674 /* Now... remove ourselves from the active list, and return to the idle list */
7675 AST_LIST_LOCK(&active_list
);
7676 AST_LIST_REMOVE(&active_list
, thread
, list
);
7677 AST_LIST_UNLOCK(&active_list
);
7679 /* Go back into our respective list */
7683 /* I am exiting here on my own volition, I need to clean up my own data structures
7684 * Assume that I am no longer in any of the lists (idle, active, or dynamic)
7686 pthread_cleanup_pop(1);
7691 static int iax2_do_register(struct iax2_registry
*reg
)
7693 struct iax_ie_data ied
;
7694 if (option_debug
&& iaxdebug
)
7695 ast_log(LOG_DEBUG
, "Sending registration request for '%s'\n", reg
->username
);
7698 ((reg
->regstate
== REG_STATE_TIMEOUT
) || !reg
->addr
.sin_addr
.s_addr
)) {
7699 /* Maybe the IP has changed, force DNS refresh */
7700 ast_dnsmgr_refresh(reg
->dnsmgr
);
7704 * if IP has Changed, free allocated call to create a new one with new IP
7705 * call has the pointer to IP and must be updated to the new one
7707 if (reg
->dnsmgr
&& ast_dnsmgr_changed(reg
->dnsmgr
) && (reg
->callno
> 0)) {
7708 ast_mutex_lock(&iaxsl
[reg
->callno
]);
7709 iax2_destroy(reg
->callno
);
7710 ast_mutex_unlock(&iaxsl
[reg
->callno
]);
7713 if (!reg
->addr
.sin_addr
.s_addr
) {
7714 if (option_debug
&& iaxdebug
)
7715 ast_log(LOG_DEBUG
, "Unable to send registration request for '%s' without IP address\n", reg
->username
);
7716 /* Setup the next registration attempt */
7717 if (reg
->expire
> -1)
7718 ast_sched_del(sched
, reg
->expire
);
7719 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
7725 ast_log(LOG_DEBUG
, "Allocate call number\n");
7726 reg
->callno
= find_callno(0, 0, ®
->addr
, NEW_FORCE
, 1, defaultsockfd
);
7727 if (reg
->callno
< 1) {
7728 ast_log(LOG_WARNING
, "Unable to create call for registration\n");
7730 } else if (option_debug
)
7731 ast_log(LOG_DEBUG
, "Registration created on call %d\n", reg
->callno
);
7732 iaxs
[reg
->callno
]->reg
= reg
;
7734 /* Schedule the next registration attempt */
7735 if (reg
->expire
> -1)
7736 ast_sched_del(sched
, reg
->expire
);
7737 /* Setup the next registration a little early */
7738 reg
->expire
= ast_sched_add(sched
, (5 * reg
->refresh
/ 6) * 1000, iax2_do_register_s
, reg
);
7739 /* Send the request */
7740 memset(&ied
, 0, sizeof(ied
));
7741 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, reg
->username
);
7742 iax_ie_append_short(&ied
, IAX_IE_REFRESH
, reg
->refresh
);
7743 send_command(iaxs
[reg
->callno
],AST_FRAME_IAX
, IAX_COMMAND_REGREQ
, 0, ied
.buf
, ied
.pos
, -1);
7744 reg
->regstate
= REG_STATE_REGSENT
;
7748 static char *iax2_prov_complete_template_3rd(const char *line
, const char *word
, int pos
, int state
)
7752 return iax_prov_complete_template(line
, word
, pos
, state
);
7755 static int iax2_provision(struct sockaddr_in
*end
, int sockfd
, char *dest
, const char *template, int force
)
7757 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
7758 is found for template */
7759 struct iax_ie_data provdata
;
7760 struct iax_ie_data ied
;
7762 struct sockaddr_in sin
;
7764 struct create_addr_info cai
;
7766 memset(&cai
, 0, sizeof(cai
));
7769 ast_log(LOG_DEBUG
, "Provisioning '%s' from template '%s'\n", dest
, template);
7771 if (iax_provision_build(&provdata
, &sig
, template, force
)) {
7772 ast_log(LOG_DEBUG
, "No provisioning found for template '%s'\n", template);
7777 memcpy(&sin
, end
, sizeof(sin
));
7778 cai
.sockfd
= sockfd
;
7779 } else if (create_addr(dest
, &sin
, &cai
))
7782 /* Build the rest of the message */
7783 memset(&ied
, 0, sizeof(ied
));
7784 iax_ie_append_raw(&ied
, IAX_IE_PROVISIONING
, provdata
.buf
, provdata
.pos
);
7786 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
7790 ast_mutex_lock(&iaxsl
[callno
]);
7792 /* Schedule autodestruct in case they don't ever give us anything back */
7793 if (iaxs
[callno
]->autoid
> -1)
7794 ast_sched_del(sched
, iaxs
[callno
]->autoid
);
7795 iaxs
[callno
]->autoid
= ast_sched_add(sched
, 15000, auto_hangup
, (void *)(long)callno
);
7796 ast_set_flag(iaxs
[callno
], IAX_PROVISION
);
7797 /* Got a call number now, so go ahead and send the provisioning information */
7798 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_PROVISION
, 0, ied
.buf
, ied
.pos
, -1);
7800 ast_mutex_unlock(&iaxsl
[callno
]);
7805 static char *papp
= "IAX2Provision";
7806 static char *psyn
= "Provision a calling IAXy with a given template";
7807 static char *pdescrip
=
7808 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
7809 "the calling entity is in fact an IAXy) with the given template or\n"
7810 "default if one is not specified. Returns -1 on error or 0 on success.\n";
7813 \ingroup applications
7815 static int iax2_prov_app(struct ast_channel
*chan
, void *data
)
7821 unsigned short callno
= PTR_TO_CALLNO(chan
->tech_pvt
);
7822 if (ast_strlen_zero(data
))
7824 sdata
= ast_strdupa(data
);
7825 opts
= strchr(sdata
, '|');
7829 if (chan
->tech
!= &iax2_tech
) {
7830 ast_log(LOG_NOTICE
, "Can't provision a non-IAX device!\n");
7833 if (!callno
|| !iaxs
[callno
] || !iaxs
[callno
]->addr
.sin_addr
.s_addr
) {
7834 ast_log(LOG_NOTICE
, "Can't provision something with no IP?\n");
7837 res
= iax2_provision(&iaxs
[callno
]->addr
, iaxs
[callno
]->sockfd
, NULL
, sdata
, force
);
7838 if (option_verbose
> 2)
7839 ast_verbose(VERBOSE_PREFIX_3
"Provisioned IAXY at '%s' with '%s'= %d\n",
7840 ast_inet_ntoa(iaxs
[callno
]->addr
.sin_addr
),
7846 static int iax2_prov_cmd(int fd
, int argc
, char *argv
[])
7851 return RESULT_SHOWUSAGE
;
7853 if (!strcasecmp(argv
[4], "forced"))
7856 return RESULT_SHOWUSAGE
;
7858 res
= iax2_provision(NULL
, -1, argv
[2], argv
[3], force
);
7860 ast_cli(fd
, "Unable to find peer/address '%s'\n", argv
[2]);
7862 ast_cli(fd
, "No template (including wildcard) matching '%s'\n", argv
[3]);
7864 ast_cli(fd
, "Provisioning '%s' with template '%s'%s\n", argv
[2], argv
[3], force
? ", forced" : "");
7865 return RESULT_SUCCESS
;
7868 static void __iax2_poke_noanswer(void *data
)
7870 struct iax2_peer
*peer
= data
;
7871 if (peer
->lastms
> -1) {
7872 ast_log(LOG_NOTICE
, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer
->name
, peer
->lastms
);
7873 manager_event(EVENT_FLAG_SYSTEM
, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer
->name
, peer
->lastms
);
7874 ast_device_state_changed("IAX2/%s", peer
->name
); /* Activate notification */
7876 if (peer
->callno
> 0) {
7877 ast_mutex_lock(&iaxsl
[peer
->callno
]);
7878 iax2_destroy(peer
->callno
);
7879 ast_mutex_unlock(&iaxsl
[peer
->callno
]);
7883 /* Try again quickly */
7884 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_peer_s
, peer
);
7887 static int iax2_poke_noanswer(void *data
)
7889 struct iax2_peer
*peer
= data
;
7890 peer
->pokeexpire
= -1;
7891 #ifdef SCHED_MULTITHREADED
7892 if (schedule_action(__iax2_poke_noanswer
, data
))
7894 __iax2_poke_noanswer(data
);
7898 static int iax2_poke_peer(struct iax2_peer
*peer
, int heldcall
)
7900 if (!peer
->maxms
|| !peer
->addr
.sin_addr
.s_addr
) {
7901 /* IF we have no IP, or this isn't to be monitored, return
7902 immediately after clearing things out */
7904 peer
->historicms
= 0;
7905 peer
->pokeexpire
= -1;
7909 if (peer
->callno
> 0) {
7910 ast_log(LOG_NOTICE
, "Still have a callno...\n");
7911 ast_mutex_lock(&iaxsl
[peer
->callno
]);
7912 iax2_destroy(peer
->callno
);
7913 ast_mutex_unlock(&iaxsl
[peer
->callno
]);
7916 ast_mutex_unlock(&iaxsl
[heldcall
]);
7917 peer
->callno
= find_callno(0, 0, &peer
->addr
, NEW_FORCE
, 0, peer
->sockfd
);
7919 ast_mutex_lock(&iaxsl
[heldcall
]);
7920 if (peer
->callno
< 1) {
7921 ast_log(LOG_WARNING
, "Unable to allocate call for poking peer '%s'\n", peer
->name
);
7925 /* Speed up retransmission times for this qualify call */
7926 iaxs
[peer
->callno
]->pingtime
= peer
->maxms
/ 4 + 1;
7927 iaxs
[peer
->callno
]->peerpoke
= peer
;
7929 /* Remove any pending pokeexpire task */
7930 if (peer
->pokeexpire
> -1)
7931 ast_sched_del(sched
, peer
->pokeexpire
);
7933 /* Queue up a new task to handle no reply */
7934 /* If the host is already unreachable then use the unreachable interval instead */
7935 if (peer
->lastms
< 0) {
7936 peer
->pokeexpire
= ast_sched_add(sched
, peer
->pokefreqnotok
, iax2_poke_noanswer
, peer
);
7938 peer
->pokeexpire
= ast_sched_add(sched
, DEFAULT_MAXMS
* 2, iax2_poke_noanswer
, peer
);
7940 /* And send the poke */
7941 send_command(iaxs
[peer
->callno
], AST_FRAME_IAX
, IAX_COMMAND_POKE
, 0, NULL
, 0, -1);
7946 static void free_context(struct iax2_context
*con
)
7948 struct iax2_context
*conl
;
7956 static struct ast_channel
*iax2_request(const char *type
, int format
, void *data
, int *cause
)
7961 struct sockaddr_in sin
;
7962 struct ast_channel
*c
;
7963 struct parsed_dial_string pds
;
7964 struct create_addr_info cai
;
7967 memset(&pds
, 0, sizeof(pds
));
7968 tmpstr
= ast_strdupa(data
);
7969 parse_dial_string(tmpstr
, &pds
);
7971 memset(&cai
, 0, sizeof(cai
));
7972 cai
.capability
= iax2_capability
;
7974 ast_copy_flags(&cai
, &globalflags
, IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
7977 ast_log(LOG_WARNING
, "No peer given\n");
7982 /* Populate our address from the given */
7983 if (create_addr(pds
.peer
, &sin
, &cai
)) {
7984 *cause
= AST_CAUSE_UNREGISTERED
;
7989 sin
.sin_port
= htons(atoi(pds
.port
));
7991 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
7993 ast_log(LOG_WARNING
, "Unable to create call\n");
7994 *cause
= AST_CAUSE_CONGESTION
;
7998 ast_mutex_lock(&iaxsl
[callno
]);
8000 /* If this is a trunk, update it now */
8001 ast_copy_flags(iaxs
[callno
], &cai
, IAX_TRUNK
| IAX_SENDANI
| IAX_NOTRANSFER
| IAX_TRANSFERMEDIA
| IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
8002 if (ast_test_flag(&cai
, IAX_TRUNK
))
8003 callno
= make_trunk(callno
, 1);
8004 iaxs
[callno
]->maxtime
= cai
.maxtime
;
8006 ast_string_field_set(iaxs
[callno
], host
, pds
.peer
);
8008 c
= ast_iax2_new(callno
, AST_STATE_DOWN
, cai
.capability
);
8010 ast_mutex_unlock(&iaxsl
[callno
]);
8013 /* Choose a format we can live with */
8014 if (c
->nativeformats
& format
)
8015 c
->nativeformats
&= format
;
8017 native
= c
->nativeformats
;
8019 res
= ast_translator_best_choice(&fmt
, &native
);
8021 ast_log(LOG_WARNING
, "Unable to create translator path for %s to %s on %s\n",
8022 ast_getformatname(c
->nativeformats
), ast_getformatname(fmt
), c
->name
);
8026 c
->nativeformats
= native
;
8028 c
->readformat
= ast_best_codec(c
->nativeformats
);
8029 c
->writeformat
= c
->readformat
;
8035 static void *sched_thread(void *ignore
)
8043 res
= ast_sched_wait(sched
);
8044 if ((res
> 1000) || (res
< 0))
8046 tv
= ast_tvadd(ast_tvnow(), ast_samp2tv(res
, 1000));
8047 ts
.tv_sec
= tv
.tv_sec
;
8048 ts
.tv_nsec
= tv
.tv_usec
* 1000;
8050 pthread_testcancel();
8051 ast_mutex_lock(&sched_lock
);
8052 ast_cond_timedwait(&sched_cond
, &sched_lock
, &ts
);
8053 ast_mutex_unlock(&sched_lock
);
8054 pthread_testcancel();
8056 count
= ast_sched_runq(sched
);
8058 ast_log(LOG_DEBUG
, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count
);
8063 static void *network_thread(void *ignore
)
8065 /* Our job is simple: Send queued messages, retrying if necessary. Read frames
8066 from the network, and queue them for delivery to the channels */
8067 int res
, count
, wakeup
;
8068 struct iax_frame
*f
;
8071 ast_io_add(io
, timingfd
, timing_read
, AST_IO_IN
| AST_IO_PRI
, NULL
);
8074 pthread_testcancel();
8076 /* Go through the queue, sending messages which have not yet been
8077 sent, and scheduling retransmissions if appropriate */
8078 AST_LIST_LOCK(&iaxq
.queue
);
8081 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq
.queue
, f
, list
) {
8085 /* Try to lock the pvt, if we can't... don't fret - defer it till later */
8086 if (ast_mutex_trylock(&iaxsl
[f
->callno
])) {
8093 if (iaxs
[f
->callno
]) {
8098 ast_mutex_unlock(&iaxsl
[f
->callno
]);
8100 if (f
->retries
< 0) {
8101 /* This is not supposed to be retransmitted */
8102 AST_LIST_REMOVE(&iaxq
.queue
, f
, list
);
8104 /* Free the iax frame */
8107 /* We need reliable delivery. Schedule a retransmission */
8109 f
->retrans
= ast_sched_add(sched
, f
->retrytime
, attempt_transmit
, f
);
8110 signal_condition(&sched_lock
, &sched_cond
);
8113 AST_LIST_TRAVERSE_SAFE_END
8114 AST_LIST_UNLOCK(&iaxq
.queue
);
8116 pthread_testcancel();
8119 ast_log(LOG_DEBUG
, "chan_iax2: Sent %d queued outbound frames all at once\n", count
);
8121 /* Now do the IO, and run scheduled tasks */
8122 res
= ast_io_wait(io
, wakeup
);
8125 ast_log(LOG_DEBUG
, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res
);
8131 static int start_network_thread(void)
8133 pthread_attr_t attr
;
8134 int threadcount
= 0;
8136 for (x
= 0; x
< iaxthreadcount
; x
++) {
8137 struct iax2_thread
*thread
= ast_calloc(1, sizeof(struct iax2_thread
));
8139 thread
->type
= IAX_TYPE_POOL
;
8140 thread
->threadnum
= ++threadcount
;
8141 ast_mutex_init(&thread
->lock
);
8142 ast_cond_init(&thread
->cond
, NULL
);
8143 pthread_attr_init(&attr
);
8144 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_DETACHED
);
8145 if (ast_pthread_create(&thread
->threadid
, &attr
, iax2_process_thread
, thread
)) {
8146 ast_log(LOG_WARNING
, "Failed to create new thread!\n");
8150 AST_LIST_LOCK(&idle_list
);
8151 AST_LIST_INSERT_TAIL(&idle_list
, thread
, list
);
8152 AST_LIST_UNLOCK(&idle_list
);
8155 ast_pthread_create_background(&schedthreadid
, NULL
, sched_thread
, NULL
);
8156 ast_pthread_create_background(&netthreadid
, NULL
, network_thread
, NULL
);
8157 if (option_verbose
> 1)
8158 ast_verbose(VERBOSE_PREFIX_2
"%d helper threaads started\n", threadcount
);
8162 static struct iax2_context
*build_context(char *context
)
8164 struct iax2_context
*con
;
8166 if ((con
= ast_calloc(1, sizeof(*con
))))
8167 ast_copy_string(con
->context
, context
, sizeof(con
->context
));
8172 static int get_auth_methods(char *value
)
8175 if (strstr(value
, "rsa"))
8176 methods
|= IAX_AUTH_RSA
;
8177 if (strstr(value
, "md5"))
8178 methods
|= IAX_AUTH_MD5
;
8179 if (strstr(value
, "plaintext"))
8180 methods
|= IAX_AUTH_PLAINTEXT
;
8185 /*! \brief Check if address can be used as packet source.
8186 \return 0 address available, 1 address unavailable, -1 error
8188 static int check_srcaddr(struct sockaddr
*sa
, socklen_t salen
)
8193 sd
= socket(AF_INET
, SOCK_DGRAM
, 0);
8195 ast_log(LOG_ERROR
, "Socket: %s\n", strerror(errno
));
8199 res
= bind(sd
, sa
, salen
);
8201 ast_log(LOG_DEBUG
, "Can't bind: %s\n", strerror(errno
));
8210 /*! \brief Parse the "sourceaddress" value,
8211 lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
8213 static int peer_set_srcaddr(struct iax2_peer
*peer
, const char *srcaddr
)
8215 struct sockaddr_in sin
;
8217 int port
= IAX_DEFAULT_PORTNO
;
8218 int sockfd
= defaultsockfd
;
8223 if (!(tmp
= ast_strdupa(srcaddr
)))
8226 addr
= strsep(&tmp
, ":");
8230 port
= atoi(portstr
);
8232 port
= IAX_DEFAULT_PORTNO
;
8235 if (!ast_get_ip(&sin
, addr
)) {
8236 struct ast_netsock
*sock
;
8240 sin
.sin_family
= AF_INET
;
8241 res
= check_srcaddr((struct sockaddr
*) &sin
, sizeof(sin
));
8243 /* ip address valid. */
8244 sin
.sin_port
= htons(port
);
8245 sock
= ast_netsock_find(netsock
, &sin
);
8247 sockfd
= ast_netsock_sockfd(sock
);
8253 peer
->sockfd
= sockfd
;
8256 ast_log(LOG_WARNING
, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
8257 srcaddr
, peer
->name
);
8260 ast_log(LOG_DEBUG
, "Using sourceaddress %s for '%s'\n", srcaddr
, peer
->name
);
8266 /*! \brief Create peer structure based on configuration */
8267 static struct iax2_peer
*build_peer(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
)
8269 struct iax2_peer
*peer
= NULL
;
8270 struct ast_ha
*oldha
= NULL
;
8275 AST_LIST_LOCK(&peers
);
8277 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
8278 if (!strcmp(peer
->name
, name
)) {
8279 if (!ast_test_flag(peer
, IAX_DELME
))
8292 AST_LIST_REMOVE(&peers
, peer
, entry
);
8293 AST_LIST_UNLOCK(&peers
);
8295 AST_LIST_UNLOCK(&peers
);
8296 if ((peer
= ast_calloc(1, sizeof(*peer
)))) {
8298 peer
->pokeexpire
= -1;
8299 peer
->sockfd
= defaultsockfd
;
8300 if (ast_string_field_init(peer
, 32)) {
8308 ast_copy_flags(peer
, &globalflags
, IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
);
8309 peer
->encmethods
= iax2_encryption
;
8311 ast_string_field_set(peer
,secret
,"");
8313 ast_string_field_set(peer
, name
, name
);
8314 peer
->addr
.sin_port
= htons(IAX_DEFAULT_PORTNO
);
8315 peer
->expiry
= min_reg_expire
;
8317 peer
->prefs
= prefs
;
8318 peer
->capability
= iax2_capability
;
8319 peer
->smoothing
= 0;
8320 peer
->pokefreqok
= DEFAULT_FREQ_OK
;
8321 peer
->pokefreqnotok
= DEFAULT_FREQ_NOTOK
;
8322 ast_string_field_set(peer
,context
,"");
8323 ast_string_field_set(peer
,peercontext
,"");
8331 if (!strcasecmp(v
->name
, "secret")) {
8332 ast_string_field_set(peer
, secret
, v
->value
);
8333 } else if (!strcasecmp(v
->name
, "mailbox")) {
8334 ast_string_field_set(peer
, mailbox
, v
->value
);
8335 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
8336 ast_string_field_set(peer
, mohinterpret
, v
->value
);
8337 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
8338 ast_string_field_set(peer
, mohsuggest
, v
->value
);
8339 } else if (!strcasecmp(v
->name
, "dbsecret")) {
8340 ast_string_field_set(peer
, dbsecret
, v
->value
);
8341 } else if (!strcasecmp(v
->name
, "trunk")) {
8342 ast_set2_flag(peer
, ast_true(v
->value
), IAX_TRUNK
);
8343 if (ast_test_flag(peer
, IAX_TRUNK
) && (timingfd
< 0)) {
8344 ast_log(LOG_WARNING
, "Unable to support trunking on peer '%s' without zaptel timing\n", peer
->name
);
8345 ast_clear_flag(peer
, IAX_TRUNK
);
8347 } else if (!strcasecmp(v
->name
, "auth")) {
8348 peer
->authmethods
= get_auth_methods(v
->value
);
8349 } else if (!strcasecmp(v
->name
, "encryption")) {
8350 peer
->encmethods
= get_encrypt_methods(v
->value
);
8351 } else if (!strcasecmp(v
->name
, "notransfer")) {
8352 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8353 ast_clear_flag(peer
, IAX_TRANSFERMEDIA
);
8354 ast_set2_flag(peer
, ast_true(v
->value
), IAX_NOTRANSFER
);
8355 } else if (!strcasecmp(v
->name
, "transfer")) {
8356 if (!strcasecmp(v
->value
, "mediaonly")) {
8357 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8358 } else if (ast_true(v
->value
)) {
8359 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8361 ast_set_flags_to(peer
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8362 } else if (!strcasecmp(v
->name
, "jitterbuffer")) {
8363 ast_set2_flag(peer
, ast_true(v
->value
), IAX_USEJITTERBUF
);
8364 } else if (!strcasecmp(v
->name
, "forcejitterbuffer")) {
8365 ast_set2_flag(peer
, ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8366 } else if (!strcasecmp(v
->name
, "host")) {
8367 if (!strcasecmp(v
->value
, "dynamic")) {
8368 /* They'll register with us */
8369 ast_set_flag(peer
, IAX_DYNAMIC
);
8371 /* Initialize stuff iff we're not found, otherwise
8372 we keep going with what we had */
8373 memset(&peer
->addr
.sin_addr
, 0, 4);
8374 if (peer
->addr
.sin_port
) {
8375 /* If we've already got a port, make it the default rather than absolute */
8376 peer
->defaddr
.sin_port
= peer
->addr
.sin_port
;
8377 peer
->addr
.sin_port
= 0;
8381 /* Non-dynamic. Make sure we become that way if we're not */
8382 if (peer
->expire
> -1)
8383 ast_sched_del(sched
, peer
->expire
);
8385 ast_clear_flag(peer
, IAX_DYNAMIC
);
8386 if (ast_dnsmgr_lookup(v
->value
, &peer
->addr
.sin_addr
, &peer
->dnsmgr
)) {
8387 ast_string_field_free_pools(peer
);
8391 if (!peer
->addr
.sin_port
)
8392 peer
->addr
.sin_port
= htons(IAX_DEFAULT_PORTNO
);
8395 inet_aton("255.255.255.255", &peer
->mask
);
8396 } else if (!strcasecmp(v
->name
, "defaultip")) {
8397 if (ast_get_ip(&peer
->defaddr
, v
->value
)) {
8398 ast_string_field_free_pools(peer
);
8402 } else if (!strcasecmp(v
->name
, "sourceaddress")) {
8403 peer_set_srcaddr(peer
, v
->value
);
8404 } else if (!strcasecmp(v
->name
, "permit") ||
8405 !strcasecmp(v
->name
, "deny")) {
8406 peer
->ha
= ast_append_ha(v
->name
, v
->value
, peer
->ha
);
8407 } else if (!strcasecmp(v
->name
, "mask")) {
8409 inet_aton(v
->value
, &peer
->mask
);
8410 } else if (!strcasecmp(v
->name
, "context")) {
8411 ast_string_field_set(peer
, context
, v
->value
);
8412 } else if (!strcasecmp(v
->name
, "regexten")) {
8413 ast_string_field_set(peer
, regexten
, v
->value
);
8414 } else if (!strcasecmp(v
->name
, "peercontext")) {
8415 ast_string_field_set(peer
, peercontext
, v
->value
);
8416 } else if (!strcasecmp(v
->name
, "port")) {
8417 if (ast_test_flag(peer
, IAX_DYNAMIC
))
8418 peer
->defaddr
.sin_port
= htons(atoi(v
->value
));
8420 peer
->addr
.sin_port
= htons(atoi(v
->value
));
8421 } else if (!strcasecmp(v
->name
, "username")) {
8422 ast_string_field_set(peer
, username
, v
->value
);
8423 } else if (!strcasecmp(v
->name
, "allow")) {
8424 ast_parse_allow_disallow(&peer
->prefs
, &peer
->capability
, v
->value
, 1);
8425 } else if (!strcasecmp(v
->name
, "disallow")) {
8426 ast_parse_allow_disallow(&peer
->prefs
, &peer
->capability
, v
->value
, 0);
8427 } else if (!strcasecmp(v
->name
, "callerid")) {
8430 ast_callerid_split(v
->value
, name2
, 80, num2
, 80);
8431 ast_string_field_set(peer
, cid_name
, name2
);
8432 ast_string_field_set(peer
, cid_num
, num2
);
8433 ast_set_flag(peer
, IAX_HASCALLERID
);
8434 } else if (!strcasecmp(v
->name
, "fullname")) {
8435 ast_string_field_set(peer
, cid_name
, v
->value
);
8436 ast_set_flag(peer
, IAX_HASCALLERID
);
8437 } else if (!strcasecmp(v
->name
, "cid_number")) {
8438 ast_string_field_set(peer
, cid_num
, v
->value
);
8439 ast_set_flag(peer
, IAX_HASCALLERID
);
8440 } else if (!strcasecmp(v
->name
, "sendani")) {
8441 ast_set2_flag(peer
, ast_true(v
->value
), IAX_SENDANI
);
8442 } else if (!strcasecmp(v
->name
, "inkeys")) {
8443 ast_string_field_set(peer
, inkeys
, v
->value
);
8444 } else if (!strcasecmp(v
->name
, "outkey")) {
8445 ast_string_field_set(peer
, outkey
, v
->value
);
8446 } else if (!strcasecmp(v
->name
, "qualify")) {
8447 if (!strcasecmp(v
->value
, "no")) {
8449 } else if (!strcasecmp(v
->value
, "yes")) {
8450 peer
->maxms
= DEFAULT_MAXMS
;
8451 } else if (sscanf(v
->value
, "%d", &peer
->maxms
) != 1) {
8452 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
);
8455 } else if (!strcasecmp(v
->name
, "qualifysmoothing")) {
8456 peer
->smoothing
= ast_true(v
->value
);
8457 } else if (!strcasecmp(v
->name
, "qualifyfreqok")) {
8458 if (sscanf(v
->value
, "%d", &peer
->pokefreqok
) != 1) {
8459 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
);
8461 } else if (!strcasecmp(v
->name
, "qualifyfreqnotok")) {
8462 if (sscanf(v
->value
, "%d", &peer
->pokefreqnotok
) != 1) {
8463 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
);
8464 } else ast_log(LOG_WARNING
, "Set peer->pokefreqnotok to %d\n", peer
->pokefreqnotok
);
8465 } else if (!strcasecmp(v
->name
, "timezone")) {
8466 ast_string_field_set(peer
, zonetag
, v
->value
);
8467 } else if (!strcasecmp(v
->name
, "adsi")) {
8468 peer
->adsi
= ast_true(v
->value
);
8469 }/* else if (strcasecmp(v->name,"type")) */
8470 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8477 if (!peer
->authmethods
)
8478 peer
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8479 ast_clear_flag(peer
, IAX_DELME
);
8480 /* Make sure these are IPv4 addresses */
8481 peer
->addr
.sin_family
= AF_INET
;
8488 /*! \brief Create in-memory user structure from configuration */
8489 static struct iax2_user
*build_user(const char *name
, struct ast_variable
*v
, struct ast_variable
*alt
, int temponly
)
8491 struct iax2_user
*user
= NULL
;
8492 struct iax2_context
*con
, *conl
= NULL
;
8493 struct ast_ha
*oldha
= NULL
;
8494 struct iax2_context
*oldcon
= NULL
;
8497 int oldcurauthreq
= 0;
8498 char *varname
= NULL
, *varval
= NULL
;
8499 struct ast_variable
*tmpvar
= NULL
;
8501 AST_LIST_LOCK(&users
);
8503 AST_LIST_TRAVERSE(&users
, user
, entry
) {
8504 if (!strcmp(user
->name
, name
)) {
8505 if (!ast_test_flag(user
, IAX_DELME
))
8515 oldcurauthreq
= user
->curauthreq
;
8517 oldcon
= user
->contexts
;
8519 user
->contexts
= NULL
;
8521 /* Already in the list, remove it and it will be added back (or FREE'd) */
8522 AST_LIST_REMOVE(&users
, user
, entry
);
8523 AST_LIST_UNLOCK(&users
);
8525 AST_LIST_UNLOCK(&users
);
8526 /* This is going to memset'd to 0 in the next block */
8527 user
= ast_calloc(sizeof(*user
),1);
8532 ast_string_field_free_pools(user
);
8533 memset(user
, 0, sizeof(struct iax2_user
));
8534 if (ast_string_field_init(user
, 32)) {
8538 user
->maxauthreq
= maxauthreq
;
8539 user
->curauthreq
= oldcurauthreq
;
8540 user
->prefs
= prefs
;
8541 user
->capability
= iax2_capability
;
8542 user
->encmethods
= iax2_encryption
;
8544 ast_string_field_set(user
, name
, name
);
8545 ast_string_field_set(user
, language
, language
);
8546 ast_copy_flags(user
, &globalflags
, IAX_USEJITTERBUF
| IAX_FORCEJITTERBUF
| IAX_CODEC_USER_FIRST
| IAX_CODEC_NOPREFS
| IAX_CODEC_NOCAP
);
8553 if (!strcasecmp(v
->name
, "context")) {
8554 con
= build_context(v
->value
);
8559 user
->contexts
= con
;
8562 } else if (!strcasecmp(v
->name
, "permit") ||
8563 !strcasecmp(v
->name
, "deny")) {
8564 user
->ha
= ast_append_ha(v
->name
, v
->value
, user
->ha
);
8565 } else if (!strcasecmp(v
->name
, "setvar")) {
8566 varname
= ast_strdupa(v
->value
);
8567 if (varname
&& (varval
= strchr(varname
,'='))) {
8570 if((tmpvar
= ast_variable_new(varname
, varval
))) {
8571 tmpvar
->next
= user
->vars
;
8572 user
->vars
= tmpvar
;
8575 } else if (!strcasecmp(v
->name
, "allow")) {
8576 ast_parse_allow_disallow(&user
->prefs
, &user
->capability
, v
->value
, 1);
8577 } else if (!strcasecmp(v
->name
, "disallow")) {
8578 ast_parse_allow_disallow(&user
->prefs
, &user
->capability
,v
->value
, 0);
8579 } else if (!strcasecmp(v
->name
, "trunk")) {
8580 ast_set2_flag(user
, ast_true(v
->value
), IAX_TRUNK
);
8581 if (ast_test_flag(user
, IAX_TRUNK
) && (timingfd
< 0)) {
8582 ast_log(LOG_WARNING
, "Unable to support trunking on user '%s' without zaptel timing\n", user
->name
);
8583 ast_clear_flag(user
, IAX_TRUNK
);
8585 } else if (!strcasecmp(v
->name
, "auth")) {
8586 user
->authmethods
= get_auth_methods(v
->value
);
8587 } else if (!strcasecmp(v
->name
, "encryption")) {
8588 user
->encmethods
= get_encrypt_methods(v
->value
);
8589 } else if (!strcasecmp(v
->name
, "notransfer")) {
8590 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8591 ast_clear_flag(user
, IAX_TRANSFERMEDIA
);
8592 ast_set2_flag(user
, ast_true(v
->value
), IAX_NOTRANSFER
);
8593 } else if (!strcasecmp(v
->name
, "transfer")) {
8594 if (!strcasecmp(v
->value
, "mediaonly")) {
8595 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8596 } else if (ast_true(v
->value
)) {
8597 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8599 ast_set_flags_to(user
, IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8600 } else if (!strcasecmp(v
->name
, "codecpriority")) {
8601 if(!strcasecmp(v
->value
, "caller"))
8602 ast_set_flag(user
, IAX_CODEC_USER_FIRST
);
8603 else if(!strcasecmp(v
->value
, "disabled"))
8604 ast_set_flag(user
, IAX_CODEC_NOPREFS
);
8605 else if(!strcasecmp(v
->value
, "reqonly")) {
8606 ast_set_flag(user
, IAX_CODEC_NOCAP
);
8607 ast_set_flag(user
, IAX_CODEC_NOPREFS
);
8609 } else if (!strcasecmp(v
->name
, "jitterbuffer")) {
8610 ast_set2_flag(user
, ast_true(v
->value
), IAX_USEJITTERBUF
);
8611 } else if (!strcasecmp(v
->name
, "forcejitterbuffer")) {
8612 ast_set2_flag(user
, ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8613 } else if (!strcasecmp(v
->name
, "dbsecret")) {
8614 ast_string_field_set(user
, dbsecret
, v
->value
);
8615 } else if (!strcasecmp(v
->name
, "secret")) {
8616 if (!ast_strlen_zero(user
->secret
)) {
8617 char *old
= ast_strdupa(user
->secret
);
8619 ast_string_field_build(user
, secret
, "%s;%s", old
, v
->value
);
8621 ast_string_field_set(user
, secret
, v
->value
);
8622 } else if (!strcasecmp(v
->name
, "callerid")) {
8625 ast_callerid_split(v
->value
, name2
, 80, num2
, 80);
8626 ast_string_field_set(user
, cid_name
, name2
);
8627 ast_string_field_set(user
, cid_num
, num2
);
8628 ast_set_flag(user
, IAX_HASCALLERID
);
8629 } else if (!strcasecmp(v
->name
, "fullname")) {
8630 ast_string_field_set(user
, cid_name
, v
->value
);
8631 ast_set_flag(user
, IAX_HASCALLERID
);
8632 } else if (!strcasecmp(v
->name
, "cid_number")) {
8633 ast_string_field_set(user
, cid_num
, v
->value
);
8634 ast_set_flag(user
, IAX_HASCALLERID
);
8635 } else if (!strcasecmp(v
->name
, "accountcode")) {
8636 ast_string_field_set(user
, accountcode
, v
->value
);
8637 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
8638 ast_string_field_set(user
, mohinterpret
, v
->value
);
8639 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
8640 ast_string_field_set(user
, mohsuggest
, v
->value
);
8641 } else if (!strcasecmp(v
->name
, "language")) {
8642 ast_string_field_set(user
, language
, v
->value
);
8643 } else if (!strcasecmp(v
->name
, "amaflags")) {
8644 format
= ast_cdr_amaflags2int(v
->value
);
8646 ast_log(LOG_WARNING
, "Invalid AMA Flags: %s at line %d\n", v
->value
, v
->lineno
);
8648 user
->amaflags
= format
;
8650 } else if (!strcasecmp(v
->name
, "inkeys")) {
8651 ast_string_field_set(user
, inkeys
, v
->value
);
8652 } else if (!strcasecmp(v
->name
, "maxauthreq")) {
8653 user
->maxauthreq
= atoi(v
->value
);
8654 if (user
->maxauthreq
< 0)
8655 user
->maxauthreq
= 0;
8656 } else if (!strcasecmp(v
->name
, "adsi")) {
8657 user
->adsi
= ast_true(v
->value
);
8658 }/* else if (strcasecmp(v->name,"type")) */
8659 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8666 if (!user
->authmethods
) {
8667 if (!ast_strlen_zero(user
->secret
)) {
8668 user
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8669 if (!ast_strlen_zero(user
->inkeys
))
8670 user
->authmethods
|= IAX_AUTH_RSA
;
8671 } else if (!ast_strlen_zero(user
->inkeys
)) {
8672 user
->authmethods
= IAX_AUTH_RSA
;
8674 user
->authmethods
= IAX_AUTH_MD5
| IAX_AUTH_PLAINTEXT
;
8677 ast_clear_flag(user
, IAX_DELME
);
8682 free_context(oldcon
);
8686 static void delete_users(void)
8688 struct iax2_user
*user
;
8689 struct iax2_peer
*peer
;
8690 struct iax2_registry
*reg
;
8692 AST_LIST_LOCK(&users
);
8693 AST_LIST_TRAVERSE(&users
, user
, entry
)
8694 ast_set_flag(user
, IAX_DELME
);
8695 AST_LIST_UNLOCK(&users
);
8697 AST_LIST_LOCK(®istrations
);
8698 while ((reg
= AST_LIST_REMOVE_HEAD(®istrations
, entry
))) {
8699 if (reg
->expire
> -1)
8700 ast_sched_del(sched
, reg
->expire
);
8702 ast_mutex_lock(&iaxsl
[reg
->callno
]);
8703 if (iaxs
[reg
->callno
]) {
8704 iaxs
[reg
->callno
]->reg
= NULL
;
8705 iax2_destroy(reg
->callno
);
8707 ast_mutex_unlock(&iaxsl
[reg
->callno
]);
8710 ast_dnsmgr_release(reg
->dnsmgr
);
8713 AST_LIST_UNLOCK(®istrations
);
8715 AST_LIST_LOCK(&peers
);
8716 AST_LIST_TRAVERSE(&peers
, peer
, entry
)
8717 ast_set_flag(peer
, IAX_DELME
);
8718 AST_LIST_UNLOCK(&peers
);
8721 static void destroy_user(struct iax2_user
*user
)
8723 ast_free_ha(user
->ha
);
8724 free_context(user
->contexts
);
8726 ast_variables_destroy(user
->vars
);
8729 ast_string_field_free_pools(user
);
8733 static void prune_users(void)
8735 struct iax2_user
*user
= NULL
;
8737 AST_LIST_LOCK(&users
);
8738 AST_LIST_TRAVERSE_SAFE_BEGIN(&users
, user
, entry
) {
8739 if (ast_test_flag(user
, IAX_DELME
)) {
8741 AST_LIST_REMOVE_CURRENT(&users
, entry
);
8744 AST_LIST_TRAVERSE_SAFE_END
8745 AST_LIST_UNLOCK(&users
);
8749 static void destroy_peer(struct iax2_peer
*peer
)
8751 ast_free_ha(peer
->ha
);
8753 /* Delete it, it needs to disappear */
8754 if (peer
->expire
> -1)
8755 ast_sched_del(sched
, peer
->expire
);
8756 if (peer
->pokeexpire
> -1)
8757 ast_sched_del(sched
, peer
->pokeexpire
);
8758 if (peer
->callno
> 0) {
8759 ast_mutex_lock(&iaxsl
[peer
->callno
]);
8760 iax2_destroy(peer
->callno
);
8761 ast_mutex_unlock(&iaxsl
[peer
->callno
]);
8764 register_peer_exten(peer
, 0);
8767 ast_dnsmgr_release(peer
->dnsmgr
);
8769 ast_string_field_free_pools(peer
);
8774 static void prune_peers(void){
8775 /* Prune peers who still are supposed to be deleted */
8776 struct iax2_peer
*peer
= NULL
;
8778 AST_LIST_LOCK(&peers
);
8779 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers
, peer
, entry
) {
8780 if (ast_test_flag(peer
, IAX_DELME
)) {
8782 AST_LIST_REMOVE_CURRENT(&peers
, entry
);
8785 AST_LIST_TRAVERSE_SAFE_END
8786 AST_LIST_UNLOCK(&peers
);
8789 static void set_timing(void)
8792 int bs
= trunkfreq
* 8;
8793 if (timingfd
> -1) {
8796 ioctl(timingfd
, ZT_TIMERCONFIG
, &bs
) &&
8798 ioctl(timingfd
, ZT_SET_BLOCKSIZE
, &bs
))
8799 ast_log(LOG_WARNING
, "Unable to set blocksize on timing source\n");
8805 /*! \brief Load configuration */
8806 static int set_config(char *config_file
, int reload
)
8808 struct ast_config
*cfg
, *ucfg
;
8809 int capability
=iax2_capability
;
8810 struct ast_variable
*v
;
8815 int portno
= IAX_DEFAULT_PORTNO
;
8817 struct iax2_user
*user
;
8818 struct iax2_peer
*peer
;
8819 struct ast_netsock
*ns
;
8821 static unsigned short int last_port
=0;
8824 cfg
= ast_config_load(config_file
);
8827 ast_log(LOG_ERROR
, "Unable to load config %s\n", config_file
);
8831 /* Reset global codec prefs */
8832 memset(&prefs
, 0 , sizeof(struct ast_codec_pref
));
8834 /* Reset Global Flags */
8835 memset(&globalflags
, 0, sizeof(globalflags
));
8836 ast_set_flag(&globalflags
, IAX_RTUPDATE
);
8842 min_reg_expire
= IAX_DEFAULT_REG_EXPIRE
;
8843 max_reg_expire
= IAX_DEFAULT_REG_EXPIRE
;
8847 v
= ast_variable_browse(cfg
, "general");
8849 /* Seed initial tos value */
8850 tosval
= ast_variable_retrieve(cfg
, "general", "tos");
8852 if (ast_str2tos(tosval
, &tos
))
8853 ast_log(LOG_WARNING
, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
8856 if (!strcasecmp(v
->name
, "bindport")){
8858 ast_log(LOG_NOTICE
, "Ignoring bindport on reload\n");
8860 portno
= atoi(v
->value
);
8861 } else if (!strcasecmp(v
->name
, "pingtime"))
8862 ping_time
= atoi(v
->value
);
8863 else if (!strcasecmp(v
->name
, "iaxthreadcount")) {
8865 if (atoi(v
->value
) != iaxthreadcount
)
8866 ast_log(LOG_NOTICE
, "Ignoring any changes to iaxthreadcount during reload\n");
8868 iaxthreadcount
= atoi(v
->value
);
8869 if (iaxthreadcount
< 1) {
8870 ast_log(LOG_NOTICE
, "iaxthreadcount must be at least 1.\n");
8872 } else if (iaxthreadcount
> 256) {
8873 ast_log(LOG_NOTICE
, "limiting iaxthreadcount to 256\n");
8874 iaxthreadcount
= 256;
8877 } else if (!strcasecmp(v
->name
, "iaxmaxthreadcount")) {
8879 AST_LIST_LOCK(&dynamic_list
);
8880 iaxmaxthreadcount
= atoi(v
->value
);
8881 AST_LIST_UNLOCK(&dynamic_list
);
8883 iaxmaxthreadcount
= atoi(v
->value
);
8884 if (iaxmaxthreadcount
< 0) {
8885 ast_log(LOG_NOTICE
, "iaxmaxthreadcount must be at least 0.\n");
8886 iaxmaxthreadcount
= 0;
8887 } else if (iaxmaxthreadcount
> 256) {
8888 ast_log(LOG_NOTICE
, "Limiting iaxmaxthreadcount to 256\n");
8889 iaxmaxthreadcount
= 256;
8892 } else if (!strcasecmp(v
->name
, "nochecksums")) {
8894 if (ast_true(v
->value
))
8899 if (ast_true(v
->value
))
8900 ast_log(LOG_WARNING
, "Disabling RTP checksums is not supported on this operating system!\n");
8903 else if (!strcasecmp(v
->name
, "maxjitterbuffer"))
8904 maxjitterbuffer
= atoi(v
->value
);
8905 else if (!strcasecmp(v
->name
, "resyncthreshold"))
8906 resyncthreshold
= atoi(v
->value
);
8907 else if (!strcasecmp(v
->name
, "maxjitterinterps"))
8908 maxjitterinterps
= atoi(v
->value
);
8909 else if (!strcasecmp(v
->name
, "lagrqtime"))
8910 lagrq_time
= atoi(v
->value
);
8911 else if (!strcasecmp(v
->name
, "maxregexpire"))
8912 max_reg_expire
= atoi(v
->value
);
8913 else if (!strcasecmp(v
->name
, "minregexpire"))
8914 min_reg_expire
= atoi(v
->value
);
8915 else if (!strcasecmp(v
->name
, "bindaddr")) {
8917 ast_log(LOG_NOTICE
, "Ignoring bindaddr on reload\n");
8919 if (!(ns
= ast_netsock_bind(netsock
, io
, v
->value
, portno
, tos
, socket_read
, NULL
))) {
8920 ast_log(LOG_WARNING
, "Unable apply binding to '%s' at line %d\n", v
->value
, v
->lineno
);
8922 if (option_verbose
> 1) {
8923 if (strchr(v
->value
, ':'))
8924 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to '%s'\n", v
->value
);
8926 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to '%s:%d'\n", v
->value
, portno
);
8928 if (defaultsockfd
< 0)
8929 defaultsockfd
= ast_netsock_sockfd(ns
);
8930 ast_netsock_unref(ns
);
8933 } else if (!strcasecmp(v
->name
, "authdebug"))
8934 authdebug
= ast_true(v
->value
);
8935 else if (!strcasecmp(v
->name
, "encryption"))
8936 iax2_encryption
= get_encrypt_methods(v
->value
);
8937 else if (!strcasecmp(v
->name
, "notransfer")) {
8938 ast_log(LOG_NOTICE
, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8939 ast_clear_flag((&globalflags
), IAX_TRANSFERMEDIA
);
8940 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_NOTRANSFER
);
8941 } else if (!strcasecmp(v
->name
, "transfer")) {
8942 if (!strcasecmp(v
->value
, "mediaonly")) {
8943 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_TRANSFERMEDIA
);
8944 } else if (ast_true(v
->value
)) {
8945 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, 0);
8947 ast_set_flags_to((&globalflags
), IAX_NOTRANSFER
|IAX_TRANSFERMEDIA
, IAX_NOTRANSFER
);
8948 } else if (!strcasecmp(v
->name
, "codecpriority")) {
8949 if(!strcasecmp(v
->value
, "caller"))
8950 ast_set_flag((&globalflags
), IAX_CODEC_USER_FIRST
);
8951 else if(!strcasecmp(v
->value
, "disabled"))
8952 ast_set_flag((&globalflags
), IAX_CODEC_NOPREFS
);
8953 else if(!strcasecmp(v
->value
, "reqonly")) {
8954 ast_set_flag((&globalflags
), IAX_CODEC_NOCAP
);
8955 ast_set_flag((&globalflags
), IAX_CODEC_NOPREFS
);
8957 } else if (!strcasecmp(v
->name
, "jitterbuffer"))
8958 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_USEJITTERBUF
);
8959 else if (!strcasecmp(v
->name
, "forcejitterbuffer"))
8960 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_FORCEJITTERBUF
);
8961 else if (!strcasecmp(v
->name
, "delayreject"))
8962 delayreject
= ast_true(v
->value
);
8963 else if (!strcasecmp(v
->name
, "rtcachefriends"))
8964 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTCACHEFRIENDS
);
8965 else if (!strcasecmp(v
->name
, "rtignoreregexpire"))
8966 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTIGNOREREGEXPIRE
);
8967 else if (!strcasecmp(v
->name
, "rtupdate"))
8968 ast_set2_flag((&globalflags
), ast_true(v
->value
), IAX_RTUPDATE
);
8969 else if (!strcasecmp(v
->name
, "trunktimestamps"))
8970 ast_set2_flag(&globalflags
, ast_true(v
->value
), IAX_TRUNKTIMESTAMPS
);
8971 else if (!strcasecmp(v
->name
, "rtautoclear")) {
8972 int i
= atoi(v
->value
);
8974 global_rtautoclear
= i
;
8977 ast_set2_flag((&globalflags
), i
|| ast_true(v
->value
), IAX_RTAUTOCLEAR
);
8978 } else if (!strcasecmp(v
->name
, "trunkfreq")) {
8979 trunkfreq
= atoi(v
->value
);
8982 } else if (!strcasecmp(v
->name
, "autokill")) {
8983 if (sscanf(v
->value
, "%d", &x
) == 1) {
8987 ast_log(LOG_NOTICE
, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v
->lineno
);
8988 } else if (ast_true(v
->value
)) {
8989 autokill
= DEFAULT_MAXMS
;
8993 } else if (!strcasecmp(v
->name
, "bandwidth")) {
8994 if (!strcasecmp(v
->value
, "low")) {
8995 capability
= IAX_CAPABILITY_LOWBANDWIDTH
;
8996 } else if (!strcasecmp(v
->value
, "medium")) {
8997 capability
= IAX_CAPABILITY_MEDBANDWIDTH
;
8998 } else if (!strcasecmp(v
->value
, "high")) {
8999 capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
9001 ast_log(LOG_WARNING
, "bandwidth must be either low, medium, or high\n");
9002 } else if (!strcasecmp(v
->name
, "allow")) {
9003 ast_parse_allow_disallow(&prefs
, &capability
, v
->value
, 1);
9004 } else if (!strcasecmp(v
->name
, "disallow")) {
9005 ast_parse_allow_disallow(&prefs
, &capability
, v
->value
, 0);
9006 } else if (!strcasecmp(v
->name
, "register")) {
9007 iax2_register(v
->value
, v
->lineno
);
9008 } else if (!strcasecmp(v
->name
, "iaxcompat")) {
9009 iaxcompat
= ast_true(v
->value
);
9010 } else if (!strcasecmp(v
->name
, "regcontext")) {
9011 ast_copy_string(regcontext
, v
->value
, sizeof(regcontext
));
9012 /* Create context if it doesn't exist already */
9013 if (!ast_context_find(regcontext
))
9014 ast_context_create(NULL
, regcontext
, "IAX2");
9015 } else if (!strcasecmp(v
->name
, "tos")) {
9016 if (ast_str2tos(v
->value
, &tos
))
9017 ast_log(LOG_WARNING
, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v
->lineno
);
9018 } else if (!strcasecmp(v
->name
, "accountcode")) {
9019 ast_copy_string(accountcode
, v
->value
, sizeof(accountcode
));
9020 } else if (!strcasecmp(v
->name
, "mohinterpret")) {
9021 ast_copy_string(mohinterpret
, v
->value
, sizeof(user
->mohinterpret
));
9022 } else if (!strcasecmp(v
->name
, "mohsuggest")) {
9023 ast_copy_string(mohsuggest
, v
->value
, sizeof(user
->mohsuggest
));
9024 } else if (!strcasecmp(v
->name
, "amaflags")) {
9025 format
= ast_cdr_amaflags2int(v
->value
);
9027 ast_log(LOG_WARNING
, "Invalid AMA Flags: %s at line %d\n", v
->value
, v
->lineno
);
9031 } else if (!strcasecmp(v
->name
, "language")) {
9032 ast_copy_string(language
, v
->value
, sizeof(language
));
9033 } else if (!strcasecmp(v
->name
, "maxauthreq")) {
9034 maxauthreq
= atoi(v
->value
);
9037 } else if (!strcasecmp(v
->name
, "adsi")) {
9038 adsi
= ast_true(v
->value
);
9039 } /*else if (strcasecmp(v->name,"type")) */
9040 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
9044 if (defaultsockfd
< 0) {
9045 if (!(ns
= ast_netsock_bind(netsock
, io
, "0.0.0.0", portno
, tos
, socket_read
, NULL
))) {
9046 ast_log(LOG_ERROR
, "Unable to create network socket: %s\n", strerror(errno
));
9048 if (option_verbose
> 1)
9049 ast_verbose(VERBOSE_PREFIX_2
"Binding IAX2 to default address 0.0.0.0:%d\n", portno
);
9050 defaultsockfd
= ast_netsock_sockfd(ns
);
9051 ast_netsock_unref(ns
);
9055 if (min_reg_expire
> max_reg_expire
) {
9056 ast_log(LOG_WARNING
, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
9057 min_reg_expire
, max_reg_expire
, max_reg_expire
);
9058 min_reg_expire
= max_reg_expire
;
9060 iax2_capability
= capability
;
9062 ucfg
= ast_config_load("users.conf");
9064 struct ast_variable
*gen
;
9067 const char *hasiax
, *registeriax
;
9069 genhasiax
= ast_true(ast_variable_retrieve(ucfg
, "general", "hasiax"));
9070 genregisteriax
= ast_true(ast_variable_retrieve(ucfg
, "general", "registeriax"));
9071 gen
= ast_variable_browse(ucfg
, "general");
9072 cat
= ast_category_browse(ucfg
, NULL
);
9074 if (strcasecmp(cat
, "general")) {
9075 hasiax
= ast_variable_retrieve(ucfg
, cat
, "hasiax");
9076 registeriax
= ast_variable_retrieve(ucfg
, cat
, "registeriax");
9077 if (ast_true(hasiax
) || (!hasiax
&& genhasiax
)) {
9078 /* Start with general parameters, then specific parameters, user and peer */
9079 user
= build_user(cat
, gen
, ast_variable_browse(ucfg
, cat
), 0);
9081 AST_LIST_LOCK(&users
);
9082 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
9083 AST_LIST_UNLOCK(&users
);
9085 peer
= build_peer(cat
, gen
, ast_variable_browse(ucfg
, cat
), 0);
9087 AST_LIST_LOCK(&peers
);
9088 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
9089 AST_LIST_UNLOCK(&peers
);
9090 if (ast_test_flag(peer
, IAX_DYNAMIC
))
9091 reg_source_db(peer
);
9094 if (ast_true(registeriax
) || (!registeriax
&& genregisteriax
)) {
9096 const char *host
= ast_variable_retrieve(ucfg
, cat
, "host");
9097 const char *username
= ast_variable_retrieve(ucfg
, cat
, "username");
9098 const char *secret
= ast_variable_retrieve(ucfg
, cat
, "secret");
9100 host
= ast_variable_retrieve(ucfg
, "general", "host");
9102 username
= ast_variable_retrieve(ucfg
, "general", "username");
9104 secret
= ast_variable_retrieve(ucfg
, "general", "secret");
9105 if (!ast_strlen_zero(username
) && !ast_strlen_zero(host
)) {
9106 if (!ast_strlen_zero(secret
))
9107 snprintf(tmp
, sizeof(tmp
), "%s:%s@%s", username
, secret
, host
);
9109 snprintf(tmp
, sizeof(tmp
), "%s@%s", username
, host
);
9110 iax2_register(tmp
, 0);
9114 cat
= ast_category_browse(ucfg
, cat
);
9116 ast_config_destroy(ucfg
);
9119 cat
= ast_category_browse(cfg
, NULL
);
9121 if (strcasecmp(cat
, "general")) {
9122 utype
= ast_variable_retrieve(cfg
, cat
, "type");
9124 if (!strcasecmp(utype
, "user") || !strcasecmp(utype
, "friend")) {
9125 user
= build_user(cat
, ast_variable_browse(cfg
, cat
), NULL
, 0);
9127 AST_LIST_LOCK(&users
);
9128 AST_LIST_INSERT_HEAD(&users
, user
, entry
);
9129 AST_LIST_UNLOCK(&users
);
9132 if (!strcasecmp(utype
, "peer") || !strcasecmp(utype
, "friend")) {
9133 peer
= build_peer(cat
, ast_variable_browse(cfg
, cat
), NULL
, 0);
9135 AST_LIST_LOCK(&peers
);
9136 AST_LIST_INSERT_HEAD(&peers
, peer
, entry
);
9137 AST_LIST_UNLOCK(&peers
);
9138 if (ast_test_flag(peer
, IAX_DYNAMIC
))
9139 reg_source_db(peer
);
9141 } else if (strcasecmp(utype
, "user")) {
9142 ast_log(LOG_WARNING
, "Unknown type '%s' for '%s' in %s\n", utype
, cat
, config_file
);
9145 ast_log(LOG_WARNING
, "Section '%s' lacks type\n", cat
);
9147 cat
= ast_category_browse(cfg
, cat
);
9149 ast_config_destroy(cfg
);
9154 static int reload_config(void)
9156 char *config
= "iax.conf";
9157 struct iax2_registry
*reg
;
9158 struct iax2_peer
*peer
;
9160 strcpy(accountcode
, "");
9161 strcpy(language
, "");
9162 strcpy(mohinterpret
, "default");
9163 strcpy(mohsuggest
, "");
9166 ast_clear_flag((&globalflags
), IAX_NOTRANSFER
);
9167 ast_clear_flag((&globalflags
), IAX_TRANSFERMEDIA
);
9168 ast_clear_flag((&globalflags
), IAX_USEJITTERBUF
);
9169 ast_clear_flag((&globalflags
), IAX_FORCEJITTERBUF
);
9171 set_config(config
, 1);
9174 AST_LIST_LOCK(®istrations
);
9175 AST_LIST_TRAVERSE(®istrations
, reg
, entry
)
9176 iax2_do_register(reg
);
9177 AST_LIST_UNLOCK(®istrations
);
9178 /* Qualify hosts, too */
9179 AST_LIST_LOCK(&peers
);
9180 AST_LIST_TRAVERSE(&peers
, peer
, entry
)
9181 iax2_poke_peer(peer
, 0);
9182 AST_LIST_UNLOCK(&peers
);
9184 iax_provision_reload();
9189 static int iax2_reload(int fd
, int argc
, char *argv
[])
9191 return reload_config();
9194 static int reload(void)
9196 return reload_config();
9199 static int cache_get_callno_locked(const char *data
)
9201 struct sockaddr_in sin
;
9204 struct iax_ie_data ied
;
9205 struct create_addr_info cai
;
9206 struct parsed_dial_string pds
;
9209 for (x
=0; x
<IAX_MAX_CALLS
; x
++) {
9210 /* Look for an *exact match* call. Once a call is negotiated, it can only
9211 look up entries for a single context */
9212 if (!ast_mutex_trylock(&iaxsl
[x
])) {
9213 if (iaxs
[x
] && !strcasecmp(data
, iaxs
[x
]->dproot
))
9215 ast_mutex_unlock(&iaxsl
[x
]);
9219 /* No match found, we need to create a new one */
9221 memset(&cai
, 0, sizeof(cai
));
9222 memset(&ied
, 0, sizeof(ied
));
9223 memset(&pds
, 0, sizeof(pds
));
9225 tmpstr
= ast_strdupa(data
);
9226 parse_dial_string(tmpstr
, &pds
);
9228 /* Populate our address from the given */
9229 if (create_addr(pds
.peer
, &sin
, &cai
))
9232 ast_log(LOG_DEBUG
, "peer: %s, username: %s, password: %s, context: %s\n",
9233 pds
.peer
, pds
.username
, pds
.password
, pds
.context
);
9235 callno
= find_callno(0, 0, &sin
, NEW_FORCE
, 1, cai
.sockfd
);
9237 ast_log(LOG_WARNING
, "Unable to create call\n");
9241 ast_mutex_lock(&iaxsl
[callno
]);
9242 ast_string_field_set(iaxs
[callno
], dproot
, data
);
9243 iaxs
[callno
]->capability
= IAX_CAPABILITY_FULLBANDWIDTH
;
9245 iax_ie_append_short(&ied
, IAX_IE_VERSION
, IAX_PROTO_VERSION
);
9246 iax_ie_append_str(&ied
, IAX_IE_CALLED_NUMBER
, "TBD");
9247 /* the string format is slightly different from a standard dial string,
9248 because the context appears in the 'exten' position
9251 iax_ie_append_str(&ied
, IAX_IE_CALLED_CONTEXT
, pds
.exten
);
9253 iax_ie_append_str(&ied
, IAX_IE_USERNAME
, pds
.username
);
9254 iax_ie_append_int(&ied
, IAX_IE_FORMAT
, IAX_CAPABILITY_FULLBANDWIDTH
);
9255 iax_ie_append_int(&ied
, IAX_IE_CAPABILITY
, IAX_CAPABILITY_FULLBANDWIDTH
);
9256 /* Keep password handy */
9258 ast_string_field_set(iaxs
[callno
], secret
, pds
.password
);
9260 ast_string_field_set(iaxs
[callno
], outkey
, pds
.key
);
9261 /* Start the call going */
9262 send_command(iaxs
[callno
], AST_FRAME_IAX
, IAX_COMMAND_NEW
, 0, ied
.buf
, ied
.pos
, -1);
9267 static struct iax2_dpcache
*find_cache(struct ast_channel
*chan
, const char *data
, const char *context
, const char *exten
, int priority
)
9269 struct iax2_dpcache
*dp
, *prev
= NULL
, *next
;
9278 struct ast_channel
*c
;
9279 struct ast_frame
*f
;
9280 gettimeofday(&tv
, NULL
);
9284 /* Expire old caches */
9285 if (ast_tvcmp(tv
, dp
->expiry
) > 0) {
9286 /* It's expired, let it disappear */
9288 prev
->next
= dp
->next
;
9291 if (!dp
->peer
&& !(dp
->flags
& CACHE_FLAG_PENDING
) && !dp
->callno
) {
9292 /* Free memory and go again */
9295 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
);
9300 /* We found an entry that matches us! */
9301 if (!strcmp(dp
->peercontext
, data
) && !strcmp(dp
->exten
, exten
))
9307 /* No matching entry. Create a new one. */
9308 /* First, can we make a callno? */
9309 callno
= cache_get_callno_locked(data
);
9311 ast_log(LOG_WARNING
, "Unable to generate call for '%s'\n", data
);
9314 if (!(dp
= ast_calloc(1, sizeof(*dp
)))) {
9315 ast_mutex_unlock(&iaxsl
[callno
]);
9318 ast_copy_string(dp
->peercontext
, data
, sizeof(dp
->peercontext
));
9319 ast_copy_string(dp
->exten
, exten
, sizeof(dp
->exten
));
9320 gettimeofday(&dp
->expiry
, NULL
);
9321 dp
->orig
= dp
->expiry
;
9322 /* Expires in 30 mins by default */
9323 dp
->expiry
.tv_sec
+= iaxdefaultdpcache
;
9325 dp
->flags
= CACHE_FLAG_PENDING
;
9326 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
9327 dp
->waiters
[x
] = -1;
9329 dp
->peer
= iaxs
[callno
]->dpentries
;
9330 iaxs
[callno
]->dpentries
= dp
;
9331 /* Send the request if we're already up */
9332 if (ast_test_flag(&iaxs
[callno
]->state
, IAX_STATE_STARTED
))
9333 iax2_dprequest(dp
, callno
);
9334 ast_mutex_unlock(&iaxsl
[callno
]);
9336 /* By here we must have a dp */
9337 if (dp
->flags
& CACHE_FLAG_PENDING
) {
9338 /* Okay, here it starts to get nasty. We need a pipe now to wait
9339 for a reply to come back so long as it's pending */
9340 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++) {
9341 /* Find an empty slot */
9342 if (dp
->waiters
[x
] < 0)
9345 if (x
>= sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0])) {
9346 ast_log(LOG_WARNING
, "No more waiter positions available\n");
9350 ast_log(LOG_WARNING
, "Unable to create pipe for comm\n");
9353 dp
->waiters
[x
] = com
[1];
9354 /* Okay, now we wait */
9355 timeout
= iaxdefaulttimeout
* 1000;
9356 /* Temporarily unlock */
9357 ast_mutex_unlock(&dpcache_lock
);
9358 /* Defer any dtmf */
9360 old
= ast_channel_defer_dtmf(chan
);
9363 c
= ast_waitfor_nandfds(&chan
, chan
? 1 : 0, &com
[0], 1, NULL
, &outfd
, &timeout
);
9372 /* Got hung up on, abort! */
9379 ast_log(LOG_WARNING
, "Timeout waiting for %s exten %s\n", data
, exten
);
9381 ast_mutex_lock(&dpcache_lock
);
9382 dp
->waiters
[x
] = -1;
9386 /* Don't interpret anything, just abort. Not sure what th epoint
9387 of undeferring dtmf on a hung up channel is but hey whatever */
9389 ast_channel_undefer_dtmf(chan
);
9392 if (!(dp
->flags
& CACHE_FLAG_TIMEOUT
)) {
9393 /* Now to do non-independent analysis the results of our wait */
9394 if (dp
->flags
& CACHE_FLAG_PENDING
) {
9395 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
9396 pending. Don't let it take as long to timeout. */
9397 dp
->flags
&= ~CACHE_FLAG_PENDING
;
9398 dp
->flags
|= CACHE_FLAG_TIMEOUT
;
9399 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
9400 systems without leaving it unavailable once the server comes back online */
9401 dp
->expiry
.tv_sec
= dp
->orig
.tv_sec
+ 60;
9402 for (x
=0;x
<sizeof(dp
->waiters
) / sizeof(dp
->waiters
[0]); x
++)
9403 if (dp
->waiters
[x
] > -1)
9404 write(dp
->waiters
[x
], "asdf", 4);
9407 /* Our caller will obtain the rest */
9409 ast_channel_undefer_dtmf(chan
);
9414 /*! \brief Part of the IAX2 switch interface */
9415 static int iax2_exists(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9417 struct iax2_dpcache
*dp
;
9420 ast_log(LOG_NOTICE
, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9422 if ((priority
!= 1) && (priority
!= 2))
9424 ast_mutex_lock(&dpcache_lock
);
9425 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9427 if (dp
->flags
& CACHE_FLAG_EXISTS
)
9430 ast_mutex_unlock(&dpcache_lock
);
9432 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9437 /*! \brief part of the IAX2 dial plan switch interface */
9438 static int iax2_canmatch(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9441 struct iax2_dpcache
*dp
;
9443 ast_log(LOG_NOTICE
, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9445 if ((priority
!= 1) && (priority
!= 2))
9447 ast_mutex_lock(&dpcache_lock
);
9448 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9450 if (dp
->flags
& CACHE_FLAG_CANEXIST
)
9453 ast_mutex_unlock(&dpcache_lock
);
9455 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9460 /*! \brief Part of the IAX2 Switch interface */
9461 static int iax2_matchmore(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9464 struct iax2_dpcache
*dp
;
9466 ast_log(LOG_NOTICE
, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context
, exten
, priority
, callerid
? callerid
: "<unknown>", data
);
9468 if ((priority
!= 1) && (priority
!= 2))
9470 ast_mutex_lock(&dpcache_lock
);
9471 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9473 if (dp
->flags
& CACHE_FLAG_MATCHMORE
)
9476 ast_mutex_unlock(&dpcache_lock
);
9478 ast_log(LOG_WARNING
, "Unable to make DP cache\n");
9483 /*! \brief Execute IAX2 dialplan switch */
9484 static int iax2_exec(struct ast_channel
*chan
, const char *context
, const char *exten
, int priority
, const char *callerid
, const char *data
)
9489 struct iax2_dpcache
*dp
;
9490 struct ast_app
*dial
;
9492 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
);
9494 if (priority
== 2) {
9495 /* Indicate status, can be overridden in dialplan */
9496 const char *dialstatus
= pbx_builtin_getvar_helper(chan
, "DIALSTATUS");
9498 dial
= pbx_findapp(dialstatus
);
9500 pbx_exec(chan
, dial
, "");
9503 } else if (priority
!= 1)
9505 ast_mutex_lock(&dpcache_lock
);
9506 dp
= find_cache(chan
, data
, context
, exten
, priority
);
9508 if (dp
->flags
& CACHE_FLAG_EXISTS
) {
9509 ast_copy_string(odata
, data
, sizeof(odata
));
9510 ncontext
= strchr(odata
, '/');
9514 snprintf(req
, sizeof(req
), "IAX2/%s/%s@%s", odata
, exten
, ncontext
);
9516 snprintf(req
, sizeof(req
), "IAX2/%s/%s", odata
, exten
);
9518 if (option_verbose
> 2)
9519 ast_verbose(VERBOSE_PREFIX_3
"Executing Dial('%s')\n", req
);
9521 ast_mutex_unlock(&dpcache_lock
);
9522 ast_log(LOG_WARNING
, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten
, context
, data
);
9526 ast_mutex_unlock(&dpcache_lock
);
9527 dial
= pbx_findapp("Dial");
9529 return pbx_exec(chan
, dial
, req
);
9531 ast_log(LOG_WARNING
, "No dial application registered\n");
9536 static int function_iaxpeer(struct ast_channel
*chan
, char *cmd
, char *data
, char *buf
, size_t len
)
9538 struct iax2_peer
*peer
;
9539 char *peername
, *colname
;
9541 peername
= ast_strdupa(data
);
9543 /* if our channel, return the IP address of the endpoint of current channel */
9544 if (!strcmp(peername
,"CURRENTCHANNEL")) {
9545 unsigned short callno
;
9546 if (chan
->tech
!= &iax2_tech
)
9548 callno
= PTR_TO_CALLNO(chan
->tech_pvt
);
9549 ast_copy_string(buf
, iaxs
[callno
]->addr
.sin_addr
.s_addr
? ast_inet_ntoa(iaxs
[callno
]->addr
.sin_addr
) : "", len
);
9553 if ((colname
= strchr(peername
, ':'))) /*! \todo : will be removed after the 1.4 relese */
9555 else if ((colname
= strchr(peername
, '|')))
9560 if (!(peer
= find_peer(peername
, 1)))
9563 if (!strcasecmp(colname
, "ip")) {
9564 ast_copy_string(buf
, peer
->addr
.sin_addr
.s_addr
? ast_inet_ntoa(peer
->addr
.sin_addr
) : "", len
);
9565 } else if (!strcasecmp(colname
, "status")) {
9566 peer_status(peer
, buf
, len
);
9567 } else if (!strcasecmp(colname
, "mailbox")) {
9568 ast_copy_string(buf
, peer
->mailbox
, len
);
9569 } else if (!strcasecmp(colname
, "context")) {
9570 ast_copy_string(buf
, peer
->context
, len
);
9571 } else if (!strcasecmp(colname
, "expire")) {
9572 snprintf(buf
, len
, "%d", peer
->expire
);
9573 } else if (!strcasecmp(colname
, "dynamic")) {
9574 ast_copy_string(buf
, (ast_test_flag(peer
, IAX_DYNAMIC
) ? "yes" : "no"), len
);
9575 } else if (!strcasecmp(colname
, "callerid_name")) {
9576 ast_copy_string(buf
, peer
->cid_name
, len
);
9577 } else if (!strcasecmp(colname
, "callerid_num")) {
9578 ast_copy_string(buf
, peer
->cid_num
, len
);
9579 } else if (!strcasecmp(colname
, "codecs")) {
9580 ast_getformatname_multiple(buf
, len
-1, peer
->capability
);
9581 } else if (!strncasecmp(colname
, "codec[", 6)) {
9582 char *codecnum
, *ptr
;
9583 int index
= 0, codec
= 0;
9585 codecnum
= strchr(colname
, '[');
9588 if ((ptr
= strchr(codecnum
, ']'))) {
9591 index
= atoi(codecnum
);
9592 if((codec
= ast_codec_pref_index(&peer
->prefs
, index
))) {
9593 ast_copy_string(buf
, ast_getformatname(codec
), len
);
9600 struct ast_custom_function iaxpeer_function
= {
9602 .synopsis
= "Gets IAX peer information",
9603 .syntax
= "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
9604 .read
= function_iaxpeer
,
9605 .desc
= "If peername specified, valid items are:\n"
9606 "- ip (default) The IP address.\n"
9607 "- status The peer's status (if qualify=yes)\n"
9608 "- mailbox The configured mailbox.\n"
9609 "- context The configured context.\n"
9610 "- expire The epoch time of the next expire.\n"
9611 "- dynamic Is it dynamic? (yes/no).\n"
9612 "- callerid_name The configured Caller ID name.\n"
9613 "- callerid_num The configured Caller ID number.\n"
9614 "- codecs The configured codecs.\n"
9615 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
9617 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
9622 /*! \brief Part of the device state notification system ---*/
9623 static int iax2_devicestate(void *data
)
9625 struct parsed_dial_string pds
;
9626 char *tmp
= ast_strdupa(data
);
9627 struct iax2_peer
*p
;
9628 int res
= AST_DEVICE_INVALID
;
9630 memset(&pds
, 0, sizeof(pds
));
9631 parse_dial_string(tmp
, &pds
);
9632 if (ast_strlen_zero(pds
.peer
))
9635 if (option_debug
> 2)
9636 ast_log(LOG_DEBUG
, "Checking device state for device %s\n", pds
.peer
);
9638 /* SLD: FIXME: second call to find_peer during registration */
9639 if (!(p
= find_peer(pds
.peer
, 1)))
9642 res
= AST_DEVICE_UNAVAILABLE
;
9643 if (option_debug
> 2)
9644 ast_log(LOG_DEBUG
, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
9645 pds
.peer
, p
->addr
.sin_addr
.s_addr
, p
->defaddr
.sin_addr
.s_addr
, p
->maxms
, p
->lastms
);
9647 if ((p
->addr
.sin_addr
.s_addr
|| p
->defaddr
.sin_addr
.s_addr
) &&
9648 (!p
->maxms
|| ((p
->lastms
> -1) && (p
->historicms
<= p
->maxms
)))) {
9649 /* Peer is registered, or have default IP address
9650 and a valid registration */
9651 if (p
->historicms
== 0 || p
->historicms
<= p
->maxms
)
9652 /* let the core figure out whether it is in use or not */
9653 res
= AST_DEVICE_UNKNOWN
;
9656 if (ast_test_flag(p
, IAX_TEMPONLY
))
9662 static struct ast_switch iax2_switch
=
9665 description
: "IAX Remote Dialplan Switch",
9666 exists
: iax2_exists
,
9667 canmatch
: iax2_canmatch
,
9669 matchmore
: iax2_matchmore
,
9672 static char show_stats_usage
[] =
9673 "Usage: iax2 show stats\n"
9674 " Display statistics on IAX channel driver.\n";
9676 static char show_cache_usage
[] =
9677 "Usage: iax2 show cache\n"
9678 " Display currently cached IAX Dialplan results.\n";
9680 static char show_peer_usage
[] =
9681 "Usage: iax2 show peer <name>\n"
9682 " Display details on specific IAX peer\n";
9684 static char prune_realtime_usage
[] =
9685 "Usage: iax2 prune realtime [<peername>|all]\n"
9686 " Prunes object(s) from the cache\n";
9688 static char iax2_reload_usage
[] =
9689 "Usage: iax2 reload\n"
9690 " Reloads IAX configuration from iax.conf\n";
9692 static char show_prov_usage
[] =
9693 "Usage: iax2 provision <host> <template> [forced]\n"
9694 " Provisions the given peer or IP address using a template\n"
9695 " matching either 'template' or '*' if the template is not\n"
9696 " found. If 'forced' is specified, even empty provisioning\n"
9697 " fields will be provisioned as empty fields.\n";
9699 static char show_users_usage
[] =
9700 "Usage: iax2 show users [like <pattern>]\n"
9701 " Lists all known IAX2 users.\n"
9702 " Optional regular expression pattern is used to filter the user list.\n";
9704 static char show_channels_usage
[] =
9705 "Usage: iax2 show channels\n"
9706 " Lists all currently active IAX channels.\n";
9708 static char show_netstats_usage
[] =
9709 "Usage: iax2 show netstats\n"
9710 " Lists network status for all currently active IAX channels.\n";
9712 static char show_threads_usage
[] =
9713 "Usage: iax2 show threads\n"
9714 " Lists status of IAX helper threads\n";
9716 static char show_peers_usage
[] =
9717 "Usage: iax2 show peers [registered] [like <pattern>]\n"
9718 " Lists all known IAX2 peers.\n"
9719 " Optional 'registered' argument lists only peers with known addresses.\n"
9720 " Optional regular expression pattern is used to filter the peer list.\n";
9722 static char show_firmware_usage
[] =
9723 "Usage: iax2 show firmware\n"
9724 " Lists all known IAX firmware images.\n";
9726 static char show_reg_usage
[] =
9727 "Usage: iax2 show registry\n"
9728 " Lists all registration requests and status.\n";
9730 static char debug_usage
[] =
9731 "Usage: iax2 set debug\n"
9732 " Enables dumping of IAX packets for debugging purposes\n";
9734 static char no_debug_usage
[] =
9735 "Usage: iax2 set debug off\n"
9736 " Disables dumping of IAX packets for debugging purposes\n";
9738 static char debug_trunk_usage
[] =
9739 "Usage: iax2 set debug trunk\n"
9740 " Requests current status of IAX trunking\n";
9742 static char no_debug_trunk_usage
[] =
9743 "Usage: iax2 set debug trunk off\n"
9744 " Requests current status of IAX trunking\n";
9746 static char debug_jb_usage
[] =
9747 "Usage: iax2 set debug jb\n"
9748 " Enables jitterbuffer debugging information\n";
9750 static char no_debug_jb_usage
[] =
9751 "Usage: iax2 set debug jb off\n"
9752 " Disables jitterbuffer debugging information\n";
9754 static char iax2_test_losspct_usage
[] =
9755 "Usage: iax2 test losspct <percentage>\n"
9756 " For testing, throws away <percentage> percent of incoming packets\n";
9759 static char iax2_test_late_usage
[] =
9760 "Usage: iax2 test late <ms>\n"
9761 " For testing, count the next frame as <ms> ms late\n";
9763 static char iax2_test_resync_usage
[] =
9764 "Usage: iax2 test resync <ms>\n"
9765 " For testing, adjust all future frames by <ms> ms\n";
9767 static char iax2_test_jitter_usage
[] =
9768 "Usage: iax2 test jitter <ms> <pct>\n"
9769 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
9770 #endif /* IAXTESTS */
9772 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated
= {
9773 { "iax2", "trunk", "debug", NULL
},
9774 iax2_do_trunk_debug
, NULL
,
9777 static struct ast_cli_entry cli_iax2_jb_debug_deprecated
= {
9778 { "iax2", "jb", "debug", NULL
},
9779 iax2_do_jb_debug
, NULL
,
9782 static struct ast_cli_entry cli_iax2_no_debug_deprecated
= {
9783 { "iax2", "no", "debug", NULL
},
9784 iax2_no_debug
, NULL
,
9787 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated
= {
9788 { "iax2", "no", "trunk", "debug", NULL
},
9789 iax2_no_trunk_debug
, NULL
,
9792 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated
= {
9793 { "iax2", "no", "jb", "debug", NULL
},
9794 iax2_no_jb_debug
, NULL
,
9797 static struct ast_cli_entry cli_iax2
[] = {
9798 { { "iax2", "show", "cache", NULL
},
9799 iax2_show_cache
, "Display IAX cached dialplan",
9800 show_cache_usage
, NULL
, },
9802 { { "iax2", "show", "channels", NULL
},
9803 iax2_show_channels
, "List active IAX channels",
9804 show_channels_usage
, NULL
, },
9806 { { "iax2", "show", "firmware", NULL
},
9807 iax2_show_firmware
, "List available IAX firmwares",
9808 show_firmware_usage
, NULL
, },
9810 { { "iax2", "show", "netstats", NULL
},
9811 iax2_show_netstats
, "List active IAX channel netstats",
9812 show_netstats_usage
, NULL
, },
9814 { { "iax2", "show", "peers", NULL
},
9815 iax2_show_peers
, "List defined IAX peers",
9816 show_peers_usage
, NULL
, },
9818 { { "iax2", "show", "registry", NULL
},
9819 iax2_show_registry
, "Display IAX registration status",
9820 show_reg_usage
, NULL
, },
9822 { { "iax2", "show", "stats", NULL
},
9823 iax2_show_stats
, "Display IAX statistics",
9824 show_stats_usage
, NULL
, },
9826 { { "iax2", "show", "threads", NULL
},
9827 iax2_show_threads
, "Display IAX helper thread info",
9828 show_threads_usage
, NULL
, },
9830 { { "iax2", "show", "users", NULL
},
9831 iax2_show_users
, "List defined IAX users",
9832 show_users_usage
, NULL
, },
9834 { { "iax2", "prune", "realtime", NULL
},
9835 iax2_prune_realtime
, "Prune a cached realtime lookup",
9836 prune_realtime_usage
, complete_iax2_show_peer
},
9838 { { "iax2", "reload", NULL
},
9839 iax2_reload
, "Reload IAX configuration",
9840 iax2_reload_usage
},
9842 { { "iax2", "show", "peer", NULL
},
9843 iax2_show_peer
, "Show details on specific IAX peer",
9844 show_peer_usage
, complete_iax2_show_peer
},
9846 { { "iax2", "set", "debug", NULL
},
9847 iax2_do_debug
, "Enable IAX debugging",
9850 { { "iax2", "set", "debug", "trunk", NULL
},
9851 iax2_do_trunk_debug
, "Enable IAX trunk debugging",
9852 debug_trunk_usage
, NULL
, &cli_iax2_trunk_debug_deprecated
},
9854 { { "iax2", "set", "debug", "jb", NULL
},
9855 iax2_do_jb_debug
, "Enable IAX jitterbuffer debugging",
9856 debug_jb_usage
, NULL
, &cli_iax2_jb_debug_deprecated
},
9858 { { "iax2", "set", "debug", "off", NULL
},
9859 iax2_no_debug
, "Disable IAX debugging",
9860 no_debug_usage
, NULL
, &cli_iax2_no_debug_deprecated
},
9862 { { "iax2", "set", "debug", "trunk", "off", NULL
},
9863 iax2_no_trunk_debug
, "Disable IAX trunk debugging",
9864 no_debug_trunk_usage
, NULL
, &cli_iax2_no_trunk_debug_deprecated
},
9866 { { "iax2", "set", "debug", "jb", "off", NULL
},
9867 iax2_no_jb_debug
, "Disable IAX jitterbuffer debugging",
9868 no_debug_jb_usage
, NULL
, &cli_iax2_no_jb_debug_deprecated
},
9870 { { "iax2", "test", "losspct", NULL
},
9871 iax2_test_losspct
, "Set IAX2 incoming frame loss percentage",
9872 iax2_test_losspct_usage
},
9874 { { "iax2", "provision", NULL
},
9875 iax2_prov_cmd
, "Provision an IAX device",
9876 show_prov_usage
, iax2_prov_complete_template_3rd
},
9879 { { "iax2", "test", "late", NULL
},
9880 iax2_test_late
, "Test the receipt of a late frame",
9881 iax2_test_late_usage
},
9883 { { "iax2", "test", "resync", NULL
},
9884 iax2_test_resync
, "Test a resync in received timestamps",
9885 iax2_test_resync_usage
},
9887 { { "iax2", "test", "jitter", NULL
},
9888 iax2_test_jitter
, "Simulates jitter for testing",
9889 iax2_test_jitter_usage
},
9890 #endif /* IAXTESTS */
9893 static int __unload_module(void)
9895 struct iax2_thread
*thread
= NULL
;
9898 /* Make sure threads do not hold shared resources when they are canceled */
9900 /* Grab the sched lock resource to keep it away from threads about to die */
9901 /* Cancel the network thread, close the net socket */
9902 if (netthreadid
!= AST_PTHREADT_NULL
) {
9903 AST_LIST_LOCK(&iaxq
.queue
);
9904 ast_mutex_lock(&sched_lock
);
9905 pthread_cancel(netthreadid
);
9906 ast_cond_signal(&sched_cond
);
9907 ast_mutex_unlock(&sched_lock
); /* Release the schedule lock resource */
9908 AST_LIST_UNLOCK(&iaxq
.queue
);
9909 pthread_join(netthreadid
, NULL
);
9911 if (schedthreadid
!= AST_PTHREADT_NULL
) {
9912 ast_mutex_lock(&sched_lock
);
9913 pthread_cancel(schedthreadid
);
9914 ast_cond_signal(&sched_cond
);
9915 ast_mutex_unlock(&sched_lock
);
9916 pthread_join(schedthreadid
, NULL
);
9919 /* Call for all threads to halt */
9920 AST_LIST_LOCK(&idle_list
);
9921 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list
, thread
, list
) {
9922 AST_LIST_REMOVE_CURRENT(&idle_list
, list
);
9923 pthread_cancel(thread
->threadid
);
9925 AST_LIST_TRAVERSE_SAFE_END
9926 AST_LIST_UNLOCK(&idle_list
);
9928 AST_LIST_LOCK(&active_list
);
9929 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list
, thread
, list
) {
9930 AST_LIST_REMOVE_CURRENT(&active_list
, list
);
9931 pthread_cancel(thread
->threadid
);
9933 AST_LIST_TRAVERSE_SAFE_END
9934 AST_LIST_UNLOCK(&active_list
);
9936 AST_LIST_LOCK(&dynamic_list
);
9937 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list
, thread
, list
) {
9938 AST_LIST_REMOVE_CURRENT(&dynamic_list
, list
);
9939 pthread_cancel(thread
->threadid
);
9941 AST_LIST_TRAVERSE_SAFE_END
9942 AST_LIST_UNLOCK(&dynamic_list
);
9944 AST_LIST_HEAD_DESTROY(&iaxq
.queue
);
9946 /* Wait for threads to exit */
9947 while(0 < iaxactivethreadcount
)
9950 ast_netsock_release(netsock
);
9951 for (x
=0;x
<IAX_MAX_CALLS
;x
++)
9954 ast_manager_unregister( "IAXpeers" );
9955 ast_manager_unregister( "IAXnetstats" );
9956 ast_unregister_application(papp
);
9957 ast_cli_unregister_multiple(cli_iax2
, sizeof(cli_iax2
) / sizeof(struct ast_cli_entry
));
9958 ast_unregister_switch(&iax2_switch
);
9959 ast_channel_unregister(&iax2_tech
);
9961 iax_provision_unload();
9962 sched_context_destroy(sched
);
9964 ast_mutex_destroy(&waresl
.lock
);
9966 for (x
= 0; x
< IAX_MAX_CALLS
; x
++)
9967 ast_mutex_destroy(&iaxsl
[x
]);
9972 static int unload_module(void)
9974 ast_custom_function_unregister(&iaxpeer_function
);
9975 return __unload_module();
9979 /*! \brief Load IAX2 module, load configuraiton ---*/
9980 static int load_module(void)
9982 char *config
= "iax.conf";
9985 struct iax2_registry
*reg
= NULL
;
9986 struct iax2_peer
*peer
= NULL
;
9988 ast_custom_function_register(&iaxpeer_function
);
9990 iax_set_output(iax_debug_output
);
9991 iax_set_error(iax_error_output
);
9992 jb_setoutput(jb_error_output
, jb_warning_output
, NULL
);
9996 timingfd
= open("/dev/zap/timer", O_RDWR
);
9999 timingfd
= open("/dev/zap/pseudo", O_RDWR
);
10001 ast_log(LOG_WARNING
, "Unable to open IAX timing interface: %s\n", strerror(errno
));
10004 memset(iaxs
, 0, sizeof(iaxs
));
10006 for (x
=0;x
<IAX_MAX_CALLS
;x
++)
10007 ast_mutex_init(&iaxsl
[x
]);
10009 ast_cond_init(&sched_cond
, NULL
);
10011 io
= io_context_create();
10012 sched
= sched_context_create();
10014 if (!io
|| !sched
) {
10015 ast_log(LOG_ERROR
, "Out of memory\n");
10019 netsock
= ast_netsock_list_alloc();
10021 ast_log(LOG_ERROR
, "Could not allocate netsock list.\n");
10024 ast_netsock_init(netsock
);
10026 ast_mutex_init(&waresl
.lock
);
10028 AST_LIST_HEAD_INIT(&iaxq
.queue
);
10030 ast_cli_register_multiple(cli_iax2
, sizeof(cli_iax2
) / sizeof(struct ast_cli_entry
));
10032 ast_register_application(papp
, iax2_prov_app
, psyn
, pdescrip
);
10034 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers
, "List IAX Peers" );
10035 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats
, "Show IAX Netstats" );
10037 if(set_config(config
, 0) == -1)
10038 return AST_MODULE_LOAD_DECLINE
;
10040 if (ast_channel_register(&iax2_tech
)) {
10041 ast_log(LOG_ERROR
, "Unable to register channel class %s\n", "IAX2");
10046 if (ast_register_switch(&iax2_switch
))
10047 ast_log(LOG_ERROR
, "Unable to register IAX switch\n");
10049 res
= start_network_thread();
10051 if (option_verbose
> 1)
10052 ast_verbose(VERBOSE_PREFIX_2
"IAX Ready and Listening\n");
10054 ast_log(LOG_ERROR
, "Unable to start network thread\n");
10055 ast_netsock_release(netsock
);
10058 AST_LIST_LOCK(®istrations
);
10059 AST_LIST_TRAVERSE(®istrations
, reg
, entry
)
10060 iax2_do_register(reg
);
10061 AST_LIST_UNLOCK(®istrations
);
10063 AST_LIST_LOCK(&peers
);
10064 AST_LIST_TRAVERSE(&peers
, peer
, entry
) {
10065 if (peer
->sockfd
< 0)
10066 peer
->sockfd
= defaultsockfd
;
10067 iax2_poke_peer(peer
, 0);
10069 AST_LIST_UNLOCK(&peers
);
10071 iax_provision_reload();
10075 AST_MODULE_INFO(ASTERISK_GPL_KEY
, AST_MODFLAG_DEFAULT
, "Inter Asterisk eXchange (Ver 2)",
10076 .load
= load_module
,
10077 .unload
= unload_module
,