move ADSI functionality into ast_ namespace
[asterisk-bristuff.git] / channels / chan_iax2.c
blob1fa4c87848d28727c9c2d232dd2aa3e658dcfeda
1 /*
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.
19 /*! \file
21 * \brief Implementation of Inter-Asterisk eXchange Version 2
23 * \author Mark Spencer <markster@digium.com>
25 * \par See also
26 * \arg \ref Config_iax
28 * \ingroup channel_drivers
31 /*** MODULEINFO
32 <use>zaptel</use>
33 ***/
35 #include "asterisk.h"
37 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <sys/types.h>
42 #include <sys/mman.h>
43 #include <dirent.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>
49 #include <sys/time.h>
50 #include <sys/signal.h>
51 #include <signal.h>
52 #include <string.h>
53 #include <strings.h>
54 #include <errno.h>
55 #include <unistd.h>
56 #include <netdb.h>
57 #include <fcntl.h>
58 #include <sys/stat.h>
59 #include <regex.h>
61 #ifdef HAVE_ZAPTEL
62 #include <sys/ioctl.h>
63 #include <zaptel/zaptel.h>
64 #endif
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"
98 #include "iax2.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
113 #endif
115 #ifdef SO_NO_CHECK
116 static int nochecksums = 0;
117 #endif
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 */
137 #define GAMMA (0.01)
139 static struct ast_codec_pref prefs;
141 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
143 static char context[80] = "default";
145 static char language[MAX_LANGUAGE] = "";
146 static char regcontext[AST_MAX_CONTEXT] = "";
148 static int maxauthreq = 3;
149 static int max_retries = 4;
150 static int ping_time = 20;
151 static int lagrq_time = 10;
152 static int maxtrunkcall = TRUNK_CALL_START;
153 static int maxnontrunkcall = 1;
154 static int maxjitterbuffer=1000;
155 static int resyncthreshold=1000;
156 static int maxjitterinterps=10;
157 static int trunkfreq = 20;
158 static int authdebug = 1;
159 static int autokill = 0;
160 static int iaxcompat = 0;
162 static int iaxdefaultdpcache=10 * 60; /* Cache dialplan entries for 10 minutes by default */
164 static int iaxdefaulttimeout = 5; /* Default to wait no more than 5 seconds for a reply to come back */
166 static unsigned int tos = 0;
168 static int min_reg_expire;
169 static int max_reg_expire;
171 static int timingfd = -1; /* Timing file descriptor */
173 static struct ast_netsock_list *netsock;
174 static int defaultsockfd = -1;
176 static int usecnt = 0;
178 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
180 /* Ethernet, etc */
181 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
182 /* T1, maybe ISDN */
183 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
184 ~AST_FORMAT_SLINEAR & \
185 ~AST_FORMAT_ULAW & \
186 ~AST_FORMAT_ALAW)
187 /* A modem */
188 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
189 ~AST_FORMAT_G726 & \
190 ~AST_FORMAT_G726_AAL2 & \
191 ~AST_FORMAT_ADPCM)
193 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
194 ~AST_FORMAT_G723_1)
197 #define DEFAULT_MAXMS 2000 /* Must be faster than 2 seconds by default */
198 #define DEFAULT_FREQ_OK 60 * 1000 /* How often to check for the host to be up */
199 #define DEFAULT_FREQ_NOTOK 10 * 1000 /* How often to check, if the host is down... */
201 static struct io_context *io;
202 static struct sched_context *sched;
204 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
206 static int iaxdebug = 0;
208 static int iaxtrunkdebug = 0;
210 static int test_losspct = 0;
211 #ifdef IAXTESTS
212 static int test_late = 0;
213 static int test_resync = 0;
214 static int test_jit = 0;
215 static int test_jitpct = 0;
216 #endif /* IAXTESTS */
218 static char accountcode[AST_MAX_ACCOUNT_CODE];
219 static char mohinterpret[MAX_MUSICCLASS];
220 static char mohsuggest[MAX_MUSICCLASS];
221 static int amaflags = 0;
222 static int adsi = 0;
223 static int delayreject = 0;
224 static int iax2_encryption = 0;
226 static struct ast_flags globalflags = { 0 };
228 static pthread_t netthreadid = AST_PTHREADT_NULL;
229 static pthread_t schedthreadid = AST_PTHREADT_NULL;
230 AST_MUTEX_DEFINE_STATIC(sched_lock);
231 static int sched_halt = 0;
232 static ast_cond_t sched_cond;
234 enum {
235 IAX_STATE_STARTED = (1 << 0),
236 IAX_STATE_AUTHENTICATED = (1 << 1),
237 IAX_STATE_TBD = (1 << 2),
238 IAX_STATE_UNCHANGED = (1 << 3),
239 } iax2_state;
241 struct iax2_context {
242 char context[AST_MAX_CONTEXT];
243 struct iax2_context *next;
246 enum {
247 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */
248 IAX_DELME = (1 << 1), /*!< Needs to be deleted */
249 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */
250 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */
251 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */
252 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */
253 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */
254 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */
255 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
256 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */
257 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */
258 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */
259 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */
260 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */
261 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */
262 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */
263 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/
264 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */
265 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */
266 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */
267 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */
268 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */
269 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */
270 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */
271 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */
272 } iax2_flags;
274 static int global_rtautoclear = 120;
276 static int reload_config(void);
277 static int iax2_reload(int fd, int argc, char *argv[]);
280 struct iax2_user {
281 AST_DECLARE_STRING_FIELDS(
282 AST_STRING_FIELD(name);
283 AST_STRING_FIELD(secret);
284 AST_STRING_FIELD(dbsecret);
285 AST_STRING_FIELD(accountcode);
286 AST_STRING_FIELD(mohinterpret);
287 AST_STRING_FIELD(mohsuggest);
288 AST_STRING_FIELD(inkeys); /*!< Key(s) this user can use to authenticate to us */
289 AST_STRING_FIELD(language);
290 AST_STRING_FIELD(cid_num);
291 AST_STRING_FIELD(cid_name);
294 int authmethods;
295 int encmethods;
296 int amaflags;
297 int adsi;
298 unsigned int flags;
299 int capability;
300 int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
301 int curauthreq; /*!< Current number of outstanding AUTHREQs */
302 struct ast_codec_pref prefs;
303 struct ast_ha *ha;
304 struct iax2_context *contexts;
305 struct ast_variable *vars;
306 AST_LIST_ENTRY(iax2_user) entry;
309 struct iax2_peer {
310 AST_DECLARE_STRING_FIELDS(
311 AST_STRING_FIELD(name);
312 AST_STRING_FIELD(username);
313 AST_STRING_FIELD(secret);
314 AST_STRING_FIELD(dbsecret);
315 AST_STRING_FIELD(outkey); /*!< What key we use to talk to this peer */
317 AST_STRING_FIELD(regexten); /*!< Extension to register (if regcontext is used) */
318 AST_STRING_FIELD(context); /*!< For transfers only */
319 AST_STRING_FIELD(peercontext); /*!< Context to pass to peer */
320 AST_STRING_FIELD(mailbox); /*!< Mailbox */
321 AST_STRING_FIELD(mohinterpret);
322 AST_STRING_FIELD(mohsuggest);
323 AST_STRING_FIELD(inkeys); /*!< Key(s) this peer can use to authenticate to us */
324 /* Suggested caller id if registering */
325 AST_STRING_FIELD(cid_num); /*!< Default context (for transfer really) */
326 AST_STRING_FIELD(cid_name); /*!< Default context (for transfer really) */
327 AST_STRING_FIELD(zonetag); /*!< Time Zone */
329 struct ast_codec_pref prefs;
330 struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
331 struct sockaddr_in addr;
332 int formats;
333 int sockfd; /*!< Socket to use for transmission */
334 struct in_addr mask;
335 int adsi;
336 unsigned int flags;
338 /* Dynamic Registration fields */
339 struct sockaddr_in defaddr; /*!< Default address if there is one */
340 int authmethods; /*!< Authentication methods (IAX_AUTH_*) */
341 int encmethods; /*!< Encryption methods (IAX_ENCRYPT_*) */
343 int expire; /*!< Schedule entry for expiry */
344 int expiry; /*!< How soon to expire */
345 int capability; /*!< Capability */
347 /* Qualification */
348 int callno; /*!< Call number of POKE request */
349 int pokeexpire; /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
350 int lastms; /*!< How long last response took (in ms), or -1 for no response */
351 int maxms; /*!< Max ms we will accept for the host to be up, 0 to not monitor */
353 int pokefreqok; /*!< How often to check if the host is up */
354 int pokefreqnotok; /*!< How often to check when the host has been determined to be down */
355 int historicms; /*!< How long recent average responses took */
356 int smoothing; /*!< Sample over how many units to determine historic ms */
358 struct ast_ha *ha;
359 AST_LIST_ENTRY(iax2_peer) entry;
362 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
364 static struct iax2_trunk_peer {
365 ast_mutex_t lock;
366 int sockfd;
367 struct sockaddr_in addr;
368 struct timeval txtrunktime; /*!< Transmit trunktime */
369 struct timeval rxtrunktime; /*!< Receive trunktime */
370 struct timeval lasttxtime; /*!< Last transmitted trunktime */
371 struct timeval trunkact; /*!< Last trunk activity */
372 unsigned int lastsent; /*!< Last sent time */
373 /* Trunk data and length */
374 unsigned char *trunkdata;
375 unsigned int trunkdatalen;
376 unsigned int trunkdataalloc;
377 struct iax2_trunk_peer *next;
378 int trunkerror;
379 int calls;
380 } *tpeers = NULL;
382 AST_MUTEX_DEFINE_STATIC(tpeerlock);
384 struct iax_firmware {
385 struct iax_firmware *next;
386 int fd;
387 int mmaplen;
388 int dead;
389 struct ast_iax2_firmware_header *fwh;
390 unsigned char *buf;
393 enum iax_reg_state {
394 REG_STATE_UNREGISTERED = 0,
395 REG_STATE_REGSENT,
396 REG_STATE_AUTHSENT,
397 REG_STATE_REGISTERED,
398 REG_STATE_REJECTED,
399 REG_STATE_TIMEOUT,
400 REG_STATE_NOAUTH
403 enum iax_transfer_state {
404 TRANSFER_NONE = 0,
405 TRANSFER_BEGIN,
406 TRANSFER_READY,
407 TRANSFER_RELEASED,
408 TRANSFER_PASSTHROUGH,
409 TRANSFER_MBEGIN,
410 TRANSFER_MREADY,
411 TRANSFER_MRELEASED,
412 TRANSFER_MPASSTHROUGH,
413 TRANSFER_MEDIA,
414 TRANSFER_MEDIAPASS
417 struct iax2_registry {
418 struct sockaddr_in addr; /*!< Who we connect to for registration purposes */
419 char username[80];
420 char secret[80]; /*!< Password or key name in []'s */
421 char random[80];
422 int expire; /*!< Sched ID of expiration */
423 int refresh; /*!< How often to refresh */
424 enum iax_reg_state regstate;
425 int messages; /*!< Message count, low 8 bits = new, high 8 bits = old */
426 int callno; /*!< Associated call number if applicable */
427 struct sockaddr_in us; /*!< Who the server thinks we are */
428 struct iax2_registry *next;
429 struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
432 static struct iax2_registry *registrations;
434 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
435 #define MIN_RETRY_TIME 100
436 #define MAX_RETRY_TIME 10000
438 #define MAX_JITTER_BUFFER 50
439 #define MIN_JITTER_BUFFER 10
441 #define DEFAULT_TRUNKDATA 640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
442 #define MAX_TRUNKDATA 640 * 200 /*!< 40ms, uncompressed linear * 200 channels */
444 #define MAX_TIMESTAMP_SKEW 160 /*!< maximum difference between actual and predicted ts for sending */
446 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
447 #define TS_GAP_FOR_JB_RESYNC 5000
449 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
450 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
451 static int iaxdynamicthreadcount = 0;
453 struct iax_rr {
454 int jitter;
455 int losspct;
456 int losscnt;
457 int packets;
458 int delay;
459 int dropped;
460 int ooo;
463 struct chan_iax2_pvt {
464 /*! Socket to send/receive on for this call */
465 int sockfd;
466 /*! Last received voice format */
467 int voiceformat;
468 /*! Last received video format */
469 int videoformat;
470 /*! Last sent voice format */
471 int svoiceformat;
472 /*! Last sent video format */
473 int svideoformat;
474 /*! What we are capable of sending */
475 int capability;
476 /*! Last received timestamp */
477 unsigned int last;
478 /*! Last sent timestamp - never send the same timestamp twice in a single call */
479 unsigned int lastsent;
480 /*! Next outgoing timestamp if everything is good */
481 unsigned int nextpred;
482 /*! True if the last voice we transmitted was not silence/CNG */
483 int notsilenttx;
484 /*! Ping time */
485 unsigned int pingtime;
486 /*! Max time for initial response */
487 int maxtime;
488 /*! Peer Address */
489 struct sockaddr_in addr;
490 /*! Actual used codec preferences */
491 struct ast_codec_pref prefs;
492 /*! Requested codec preferences */
493 struct ast_codec_pref rprefs;
494 /*! Our call number */
495 unsigned short callno;
496 /*! Peer callno */
497 unsigned short peercallno;
498 /*! Peer selected format */
499 int peerformat;
500 /*! Peer capability */
501 int peercapability;
502 /*! timeval that we base our transmission on */
503 struct timeval offset;
504 /*! timeval that we base our delivery on */
505 struct timeval rxcore;
506 /*! The jitterbuffer */
507 jitterbuf *jb;
508 /*! active jb read scheduler id */
509 int jbid;
510 /*! LAG */
511 int lag;
512 /*! Error, as discovered by the manager */
513 int error;
514 /*! Owner if we have one */
515 struct ast_channel *owner;
516 /*! What's our state? */
517 struct ast_flags state;
518 /*! Expiry (optional) */
519 int expiry;
520 /*! Next outgoing sequence number */
521 unsigned char oseqno;
522 /*! Next sequence number they have not yet acknowledged */
523 unsigned char rseqno;
524 /*! Next incoming sequence number */
525 unsigned char iseqno;
526 /*! Last incoming sequence number we have acknowledged */
527 unsigned char aseqno;
529 AST_DECLARE_STRING_FIELDS(
530 /*! Peer name */
531 AST_STRING_FIELD(peer);
532 /*! Default Context */
533 AST_STRING_FIELD(context);
534 /*! Caller ID if available */
535 AST_STRING_FIELD(cid_num);
536 AST_STRING_FIELD(cid_name);
537 /*! Hidden Caller ID (i.e. ANI) if appropriate */
538 AST_STRING_FIELD(ani);
539 /*! DNID */
540 AST_STRING_FIELD(dnid);
541 /*! RDNIS */
542 AST_STRING_FIELD(rdnis);
543 /*! Requested Extension */
544 AST_STRING_FIELD(exten);
545 /*! Expected Username */
546 AST_STRING_FIELD(username);
547 /*! Expected Secret */
548 AST_STRING_FIELD(secret);
549 /*! MD5 challenge */
550 AST_STRING_FIELD(challenge);
551 /*! Public keys permitted keys for incoming authentication */
552 AST_STRING_FIELD(inkeys);
553 /*! Private key for outgoing authentication */
554 AST_STRING_FIELD(outkey);
555 /*! Preferred language */
556 AST_STRING_FIELD(language);
557 /*! Hostname/peername for naming purposes */
558 AST_STRING_FIELD(host);
560 AST_STRING_FIELD(dproot);
561 AST_STRING_FIELD(accountcode);
562 AST_STRING_FIELD(mohinterpret);
563 AST_STRING_FIELD(mohsuggest);
566 /*! permitted authentication methods */
567 int authmethods;
568 /*! permitted encryption methods */
569 int encmethods;
570 /*! Encryption AES-128 Key */
571 aes_encrypt_ctx ecx;
572 /*! Decryption AES-128 Key */
573 aes_decrypt_ctx dcx;
574 /*! 32 bytes of semi-random data */
575 unsigned char semirand[32];
576 /*! Associated registry */
577 struct iax2_registry *reg;
578 /*! Associated peer for poking */
579 struct iax2_peer *peerpoke;
580 /*! IAX_ flags */
581 unsigned int flags;
582 int adsi;
584 /*! Transferring status */
585 enum iax_transfer_state transferring;
586 /*! Transfer identifier */
587 int transferid;
588 /*! Who we are IAX transfering to */
589 struct sockaddr_in transfer;
590 /*! What's the new call number for the transfer */
591 unsigned short transfercallno;
592 /*! Transfer decrypt AES-128 Key */
593 aes_encrypt_ctx tdcx;
595 /*! Status of knowledge of peer ADSI capability */
596 int peeradsicpe;
598 /*! Who we are bridged to */
599 unsigned short bridgecallno;
601 int pingid; /*!< Transmit PING request */
602 int lagid; /*!< Retransmit lag request */
603 int autoid; /*!< Auto hangup for Dialplan requestor */
604 int authid; /*!< Authentication rejection ID */
605 int authfail; /*!< Reason to report failure */
606 int initid; /*!< Initial peer auto-congest ID (based on qualified peers) */
607 int calling_ton;
608 int calling_tns;
609 int calling_pres;
610 int amaflags;
611 struct iax2_dpcache *dpentries;
612 struct ast_variable *vars;
613 /*! last received remote rr */
614 struct iax_rr remote_rr;
615 /*! Current base time: (just for stats) */
616 int min;
617 /*! Dropped frame count: (just for stats) */
618 int frames_dropped;
619 /*! received frame count: (just for stats) */
620 int frames_received;
623 static struct ast_iax2_queue {
624 AST_LIST_HEAD(, iax_frame) queue;
625 int count;
626 } iaxq = {
627 .queue = AST_LIST_HEAD_INIT_VALUE
630 static AST_LIST_HEAD_STATIC(users, iax2_user);
632 static AST_LIST_HEAD_STATIC(peers, iax2_peer);
634 static struct ast_firmware_list {
635 struct iax_firmware *wares;
636 ast_mutex_t lock;
637 } waresl;
639 /*! Extension exists */
640 #define CACHE_FLAG_EXISTS (1 << 0)
641 /*! Extension is nonexistent */
642 #define CACHE_FLAG_NONEXISTENT (1 << 1)
643 /*! Extension can exist */
644 #define CACHE_FLAG_CANEXIST (1 << 2)
645 /*! Waiting to hear back response */
646 #define CACHE_FLAG_PENDING (1 << 3)
647 /*! Timed out */
648 #define CACHE_FLAG_TIMEOUT (1 << 4)
649 /*! Request transmitted */
650 #define CACHE_FLAG_TRANSMITTED (1 << 5)
651 /*! Timeout */
652 #define CACHE_FLAG_UNKNOWN (1 << 6)
653 /*! Matchmore */
654 #define CACHE_FLAG_MATCHMORE (1 << 7)
656 static struct iax2_dpcache {
657 char peercontext[AST_MAX_CONTEXT];
658 char exten[AST_MAX_EXTENSION];
659 struct timeval orig;
660 struct timeval expiry;
661 int flags;
662 unsigned short callno;
663 int waiters[256];
664 struct iax2_dpcache *next;
665 struct iax2_dpcache *peer; /*!< For linking in peers */
666 } *dpcache;
668 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
670 static void reg_source_db(struct iax2_peer *p);
671 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
673 static void destroy_peer(struct iax2_peer *peer);
674 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
676 #define IAX_IOSTATE_IDLE 0
677 #define IAX_IOSTATE_READY 1
678 #define IAX_IOSTATE_PROCESSING 2
679 #define IAX_IOSTATE_SCHEDREADY 3
681 #define IAX_TYPE_POOL 1
682 #define IAX_TYPE_DYNAMIC 2
684 struct iax2_thread {
685 AST_LIST_ENTRY(iax2_thread) list;
686 int type;
687 int iostate;
688 #ifdef SCHED_MULTITHREADED
689 void (*schedfunc)(void *);
690 void *scheddata;
691 #endif
692 #ifdef DEBUG_SCHED_MULTITHREAD
693 char curfunc[80];
694 #endif
695 int actions;
696 int halt;
697 pthread_t threadid;
698 int threadnum;
699 struct sockaddr_in iosin;
700 unsigned char buf[4096];
701 int iores;
702 int iofd;
703 time_t checktime;
704 ast_mutex_t lock;
705 ast_cond_t cond;
708 /* Thread lists */
709 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
710 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
711 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
713 static void *iax2_process_thread(void *data);
715 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
717 ast_mutex_lock(lock);
718 ast_cond_signal(cond);
719 ast_mutex_unlock(lock);
722 static void iax_debug_output(const char *data)
724 if (iaxdebug)
725 ast_verbose("%s", data);
728 static void iax_error_output(const char *data)
730 ast_log(LOG_WARNING, "%s", data);
733 static void jb_error_output(const char *fmt, ...)
735 va_list args;
736 char buf[1024];
738 va_start(args, fmt);
739 vsnprintf(buf, 1024, fmt, args);
740 va_end(args);
742 ast_log(LOG_ERROR, buf);
745 static void jb_warning_output(const char *fmt, ...)
747 va_list args;
748 char buf[1024];
750 va_start(args, fmt);
751 vsnprintf(buf, 1024, fmt, args);
752 va_end(args);
754 ast_log(LOG_WARNING, buf);
757 static void jb_debug_output(const char *fmt, ...)
759 va_list args;
760 char buf[1024];
762 va_start(args, fmt);
763 vsnprintf(buf, 1024, fmt, args);
764 va_end(args);
766 ast_verbose(buf);
769 /* XXX We probably should use a mutex when working with this XXX */
770 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
771 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
772 static struct timeval lastused[IAX_MAX_CALLS];
774 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
775 static int expire_registry(void *data);
776 static int iax2_answer(struct ast_channel *c);
777 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
778 static int iax2_devicestate(void *data);
779 static int iax2_digit_begin(struct ast_channel *c, char digit);
780 static int iax2_digit_end(struct ast_channel *c, char digit);
781 static int iax2_do_register(struct iax2_registry *reg);
782 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
783 static int iax2_hangup(struct ast_channel *c);
784 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
785 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
786 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
787 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
788 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
789 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
790 static int iax2_sendtext(struct ast_channel *c, const char *text);
791 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
792 static int iax2_transfer(struct ast_channel *c, const char *dest);
793 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
794 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
795 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
796 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
797 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
798 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
799 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
800 static struct ast_frame *iax2_read(struct ast_channel *c);
801 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
802 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
803 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
804 static void destroy_user(struct iax2_user *user);
805 static void prune_peers(void);
807 static const struct ast_channel_tech iax2_tech = {
808 .type = "IAX2",
809 .description = tdesc,
810 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
811 .properties = AST_CHAN_TP_WANTSJITTER,
812 .requester = iax2_request,
813 .devicestate = iax2_devicestate,
814 .send_digit_begin = iax2_digit_begin,
815 .send_digit_end = iax2_digit_end,
816 .send_text = iax2_sendtext,
817 .send_image = iax2_sendimage,
818 .send_html = iax2_sendhtml,
819 .call = iax2_call,
820 .hangup = iax2_hangup,
821 .answer = iax2_answer,
822 .read = iax2_read,
823 .write = iax2_write,
824 .write_video = iax2_write,
825 .indicate = iax2_indicate,
826 .setoption = iax2_setoption,
827 .bridge = iax2_bridge,
828 .transfer = iax2_transfer,
829 .fixup = iax2_fixup,
832 static struct iax2_thread *find_idle_thread(void)
834 struct iax2_thread *thread = NULL;
836 /* Pop the head of the list off */
837 AST_LIST_LOCK(&idle_list);
838 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
839 AST_LIST_UNLOCK(&idle_list);
841 /* If no idle thread is available from the regular list, try dynamic */
842 if (thread == NULL) {
843 AST_LIST_LOCK(&dynamic_list);
844 thread = AST_LIST_FIRST(&dynamic_list);
845 if (thread != NULL) {
846 AST_LIST_REMOVE(&dynamic_list, thread, list);
848 /* Make sure we absolutely have a thread... if not, try to make one if allowed */
849 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
850 /* We need to MAKE a thread! */
851 thread = ast_calloc(1, sizeof(*thread));
852 if (thread != NULL) {
853 thread->threadnum = iaxdynamicthreadcount;
854 thread->type = IAX_TYPE_DYNAMIC;
855 ast_mutex_init(&thread->lock);
856 ast_cond_init(&thread->cond, NULL);
857 if (ast_pthread_create(&thread->threadid, NULL, iax2_process_thread, thread)) {
858 free(thread);
859 thread = NULL;
860 } else {
861 /* All went well and the thread is up, so increment our count */
862 iaxdynamicthreadcount++;
866 AST_LIST_UNLOCK(&dynamic_list);
869 return thread;
872 #ifdef SCHED_MULTITHREADED
873 static int __schedule_action(void (*func)(void *data), void *data, const char *funcname)
875 struct iax2_thread *thread = NULL;
876 static time_t lasterror;
877 static time_t t;
879 thread = find_idle_thread();
881 if (thread != NULL) {
882 thread->schedfunc = func;
883 thread->scheddata = data;
884 thread->iostate = IAX_IOSTATE_SCHEDREADY;
885 #ifdef DEBUG_SCHED_MULTITHREAD
886 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
887 #endif
888 signal_condition(&thread->lock, &thread->cond);
889 return 0;
891 time(&t);
892 if (t != lasterror)
893 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for scheduling!\n");
894 lasterror = t;
896 return -1;
898 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
899 #endif
901 static void __send_ping(void *data)
903 int callno = (long)data;
904 send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
907 static int send_ping(void *data)
909 int callno = (long)data;
910 if (iaxs[callno]) {
911 #ifdef SCHED_MULTITHREADED
912 if (schedule_action(__send_ping, data))
913 #endif
914 __send_ping(data);
915 return 1;
916 } else
917 return 0;
918 return 0;
921 static int get_encrypt_methods(const char *s)
923 int e;
924 if (!strcasecmp(s, "aes128"))
925 e = IAX_ENCRYPT_AES128;
926 else if (ast_true(s))
927 e = IAX_ENCRYPT_AES128;
928 else
929 e = 0;
930 return e;
933 static void __send_lagrq(void *data)
935 int callno = (long)data;
936 /* Ping only if it's real not if it's bridged */
937 send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
940 static int send_lagrq(void *data)
942 int callno = (long)data;
943 if (iaxs[callno]) {
944 #ifdef SCHED_MULTITHREADED
945 if (schedule_action(__send_lagrq, data))
946 #endif
947 __send_lagrq(data);
948 return 1;
949 } else
950 return 0;
951 return 0;
954 static unsigned char compress_subclass(int subclass)
956 int x;
957 int power=-1;
958 /* If it's 128 or smaller, just return it */
959 if (subclass < IAX_FLAG_SC_LOG)
960 return subclass;
961 /* Otherwise find its power */
962 for (x = 0; x < IAX_MAX_SHIFT; x++) {
963 if (subclass & (1 << x)) {
964 if (power > -1) {
965 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
966 return 0;
967 } else
968 power = x;
971 return power | IAX_FLAG_SC_LOG;
974 static int uncompress_subclass(unsigned char csub)
976 /* If the SC_LOG flag is set, return 2^csub otherwise csub */
977 if (csub & IAX_FLAG_SC_LOG) {
978 /* special case for 'compressed' -1 */
979 if (csub == 0xff)
980 return -1;
981 else
982 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
984 else
985 return csub;
988 static struct iax2_peer *find_peer(const char *name, int realtime)
990 struct iax2_peer *peer = NULL;
992 /* Grab peer from linked list */
993 AST_LIST_LOCK(&peers);
994 AST_LIST_TRAVERSE(&peers, peer, entry) {
995 if (!strcasecmp(peer->name, name)) {
996 break;
999 AST_LIST_UNLOCK(&peers);
1001 /* Now go for realtime if applicable */
1002 if(!peer && realtime)
1003 peer = realtime_peer(name, NULL);
1004 return peer;
1007 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len, int lockpeer)
1009 struct iax2_peer *peer = NULL;
1010 int res = 0;
1012 if (lockpeer)
1013 AST_LIST_LOCK(&peers);
1014 AST_LIST_TRAVERSE(&peers, peer, entry) {
1015 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
1016 (peer->addr.sin_port == sin.sin_port)) {
1017 ast_copy_string(host, peer->name, len);
1018 res = 1;
1019 break;
1022 if (lockpeer)
1023 AST_LIST_UNLOCK(&peers);
1024 if (!peer) {
1025 peer = realtime_peer(NULL, &sin);
1026 if (peer) {
1027 ast_copy_string(host, peer->name, len);
1028 if (ast_test_flag(peer, IAX_TEMPONLY))
1029 destroy_peer(peer);
1030 res = 1;
1034 return res;
1037 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, int lockpeer, const char *host)
1039 struct chan_iax2_pvt *tmp;
1040 jb_conf jbconf;
1042 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1043 return NULL;
1045 if (ast_string_field_init(tmp, 32)) {
1046 free(tmp);
1047 tmp = NULL;
1048 return NULL;
1051 tmp->prefs = prefs;
1052 tmp->callno = 0;
1053 tmp->peercallno = 0;
1054 tmp->transfercallno = 0;
1055 tmp->bridgecallno = 0;
1056 tmp->pingid = -1;
1057 tmp->lagid = -1;
1058 tmp->autoid = -1;
1059 tmp->authid = -1;
1060 tmp->initid = -1;
1062 ast_string_field_set(tmp,exten, "s");
1063 ast_string_field_set(tmp,host, host);
1065 tmp->jb = jb_new();
1066 tmp->jbid = -1;
1067 jbconf.max_jitterbuf = maxjitterbuffer;
1068 jbconf.resync_threshold = resyncthreshold;
1069 jbconf.max_contig_interp = maxjitterinterps;
1070 jb_setconf(tmp->jb,&jbconf);
1072 return tmp;
1075 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
1077 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen);
1078 if (new) {
1079 size_t mallocd_datalen = new->mallocd_datalen;
1080 memcpy(new, fr, sizeof(*new));
1081 iax_frame_wrap(new, &fr->af);
1082 new->mallocd_datalen = mallocd_datalen;
1083 new->data = NULL;
1084 new->datalen = 0;
1085 new->direction = DIRECTION_INGRESS;
1086 new->retrans = -1;
1088 return new;
1091 #define NEW_PREVENT 0
1092 #define NEW_ALLOW 1
1093 #define NEW_FORCE 2
1095 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
1097 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
1098 (cur->addr.sin_port == sin->sin_port)) {
1099 /* This is the main host */
1100 if ((cur->peercallno == callno) ||
1101 ((dcallno == cur->callno) && !cur->peercallno)) {
1102 /* That's us. Be sure we keep track of the peer call number */
1103 return 1;
1106 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
1107 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
1108 /* We're transferring */
1109 if (dcallno == cur->callno)
1110 return 1;
1112 return 0;
1115 static void update_max_trunk(void)
1117 int max = TRUNK_CALL_START;
1118 int x;
1119 /* XXX Prolly don't need locks here XXX */
1120 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
1121 if (iaxs[x])
1122 max = x + 1;
1124 maxtrunkcall = max;
1125 if (option_debug && iaxdebug)
1126 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
1129 static void update_max_nontrunk(void)
1131 int max = 1;
1132 int x;
1133 /* XXX Prolly don't need locks here XXX */
1134 for (x=1;x<TRUNK_CALL_START - 1; x++) {
1135 if (iaxs[x])
1136 max = x + 1;
1138 maxnontrunkcall = max;
1139 if (option_debug && iaxdebug)
1140 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
1143 static int make_trunk(unsigned short callno, int locked)
1145 int x;
1146 int res= 0;
1147 struct timeval now;
1148 if (iaxs[callno]->oseqno) {
1149 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
1150 return -1;
1152 if (callno & TRUNK_CALL_START) {
1153 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
1154 return -1;
1156 gettimeofday(&now, NULL);
1157 for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
1158 ast_mutex_lock(&iaxsl[x]);
1159 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
1160 iaxs[x] = iaxs[callno];
1161 iaxs[x]->callno = x;
1162 iaxs[callno] = NULL;
1163 /* Update the two timers that should have been started */
1164 if (iaxs[x]->pingid > -1)
1165 ast_sched_del(sched, iaxs[x]->pingid);
1166 if (iaxs[x]->lagid > -1)
1167 ast_sched_del(sched, iaxs[x]->lagid);
1168 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
1169 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
1170 if (locked)
1171 ast_mutex_unlock(&iaxsl[callno]);
1172 res = x;
1173 if (!locked)
1174 ast_mutex_unlock(&iaxsl[x]);
1175 break;
1177 ast_mutex_unlock(&iaxsl[x]);
1179 if (x >= IAX_MAX_CALLS - 1) {
1180 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
1181 return -1;
1183 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
1184 /* We move this call from a non-trunked to a trunked call */
1185 update_max_trunk();
1186 update_max_nontrunk();
1187 return res;
1190 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd)
1192 int res = 0;
1193 int x;
1194 struct timeval now;
1195 char host[80];
1196 if (new <= NEW_ALLOW) {
1197 /* Look for an existing connection first */
1198 for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
1199 ast_mutex_lock(&iaxsl[x]);
1200 if (iaxs[x]) {
1201 /* Look for an exact match */
1202 if (match(sin, callno, dcallno, iaxs[x])) {
1203 res = x;
1206 ast_mutex_unlock(&iaxsl[x]);
1208 for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
1209 ast_mutex_lock(&iaxsl[x]);
1210 if (iaxs[x]) {
1211 /* Look for an exact match */
1212 if (match(sin, callno, dcallno, iaxs[x])) {
1213 res = x;
1216 ast_mutex_unlock(&iaxsl[x]);
1219 if ((res < 1) && (new >= NEW_ALLOW)) {
1220 if (!iax2_getpeername(*sin, host, sizeof(host), lockpeer))
1221 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
1222 gettimeofday(&now, NULL);
1223 for (x=1;x<TRUNK_CALL_START;x++) {
1224 /* Find first unused call number that hasn't been used in a while */
1225 ast_mutex_lock(&iaxsl[x]);
1226 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
1227 ast_mutex_unlock(&iaxsl[x]);
1229 /* We've still got lock held if we found a spot */
1230 if (x >= TRUNK_CALL_START) {
1231 ast_log(LOG_WARNING, "No more space\n");
1232 return 0;
1234 iaxs[x] = new_iax(sin, lockpeer, host);
1235 update_max_nontrunk();
1236 if (iaxs[x]) {
1237 if (option_debug && iaxdebug)
1238 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
1239 iaxs[x]->sockfd = sockfd;
1240 iaxs[x]->addr.sin_port = sin->sin_port;
1241 iaxs[x]->addr.sin_family = sin->sin_family;
1242 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
1243 iaxs[x]->peercallno = callno;
1244 iaxs[x]->callno = x;
1245 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
1246 iaxs[x]->expiry = min_reg_expire;
1247 iaxs[x]->pingid = ast_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
1248 iaxs[x]->lagid = ast_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
1249 iaxs[x]->amaflags = amaflags;
1250 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
1252 ast_string_field_set(iaxs[x], accountcode, accountcode);
1253 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
1254 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
1255 } else {
1256 ast_log(LOG_WARNING, "Out of resources\n");
1257 ast_mutex_unlock(&iaxsl[x]);
1258 return 0;
1260 ast_mutex_unlock(&iaxsl[x]);
1261 res = x;
1263 return res;
1266 static void iax2_frame_free(struct iax_frame *fr)
1268 if (fr->retrans > -1)
1269 ast_sched_del(sched, fr->retrans);
1270 iax_frame_free(fr);
1273 static int iax2_queue_frame(int callno, struct ast_frame *f)
1275 /* Assumes lock for callno is already held... */
1276 for (;;) {
1277 if (iaxs[callno] && iaxs[callno]->owner) {
1278 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
1279 /* Avoid deadlock by pausing and trying again */
1280 ast_mutex_unlock(&iaxsl[callno]);
1281 usleep(1);
1282 ast_mutex_lock(&iaxsl[callno]);
1283 } else {
1284 ast_queue_frame(iaxs[callno]->owner, f);
1285 ast_mutex_unlock(&iaxs[callno]->owner->lock);
1286 break;
1288 } else
1289 break;
1291 return 0;
1294 static void destroy_firmware(struct iax_firmware *cur)
1296 /* Close firmware */
1297 if (cur->fwh) {
1298 munmap(cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
1300 close(cur->fd);
1301 free(cur);
1304 static int try_firmware(char *s)
1306 struct stat stbuf;
1307 struct iax_firmware *cur;
1308 int ifd;
1309 int fd;
1310 int res;
1312 struct ast_iax2_firmware_header *fwh, fwh2;
1313 struct MD5Context md5;
1314 unsigned char sum[16];
1315 unsigned char buf[1024];
1316 int len, chunk;
1317 char *s2;
1318 char *last;
1319 s2 = alloca(strlen(s) + 100);
1320 if (!s2) {
1321 ast_log(LOG_WARNING, "Alloca failed!\n");
1322 return -1;
1324 last = strrchr(s, '/');
1325 if (last)
1326 last++;
1327 else
1328 last = s;
1329 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
1330 res = stat(s, &stbuf);
1331 if (res < 0) {
1332 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
1333 return -1;
1335 /* Make sure it's not a directory */
1336 if (S_ISDIR(stbuf.st_mode))
1337 return -1;
1338 ifd = open(s, O_RDONLY);
1339 if (ifd < 0) {
1340 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
1341 return -1;
1343 fd = open(s2, O_RDWR | O_CREAT | O_EXCL);
1344 if (fd < 0) {
1345 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
1346 close(ifd);
1347 return -1;
1349 /* Unlink our newly created file */
1350 unlink(s2);
1352 /* Now copy the firmware into it */
1353 len = stbuf.st_size;
1354 while(len) {
1355 chunk = len;
1356 if (chunk > sizeof(buf))
1357 chunk = sizeof(buf);
1358 res = read(ifd, buf, chunk);
1359 if (res != chunk) {
1360 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
1361 close(ifd);
1362 close(fd);
1363 return -1;
1365 res = write(fd, buf, chunk);
1366 if (res != chunk) {
1367 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
1368 close(ifd);
1369 close(fd);
1370 return -1;
1372 len -= chunk;
1374 close(ifd);
1375 /* Return to the beginning */
1376 lseek(fd, 0, SEEK_SET);
1377 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
1378 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
1379 close(fd);
1380 return -1;
1382 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
1383 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
1384 close(fd);
1385 return -1;
1387 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
1388 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
1389 close(fd);
1390 return -1;
1392 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
1393 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
1394 close(fd);
1395 return -1;
1397 fwh = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
1398 if (!fwh) {
1399 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
1400 close(fd);
1401 return -1;
1403 MD5Init(&md5);
1404 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
1405 MD5Final(sum, &md5);
1406 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
1407 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
1408 munmap(fwh, stbuf.st_size);
1409 close(fd);
1410 return -1;
1412 cur = waresl.wares;
1413 while(cur) {
1414 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
1415 /* Found a candidate */
1416 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
1417 /* The version we have on loaded is older, load this one instead */
1418 break;
1419 /* This version is no newer than what we have. Don't worry about it.
1420 We'll consider it a proper load anyhow though */
1421 munmap(fwh, stbuf.st_size);
1422 close(fd);
1423 return 0;
1425 cur = cur->next;
1427 if (!cur) {
1428 /* Allocate a new one and link it */
1429 if ((cur = ast_calloc(1, sizeof(*cur)))) {
1430 cur->fd = -1;
1431 cur->next = waresl.wares;
1432 waresl.wares = cur;
1435 if (cur) {
1436 if (cur->fwh) {
1437 munmap(cur->fwh, cur->mmaplen);
1439 if (cur->fd > -1)
1440 close(cur->fd);
1441 cur->fwh = fwh;
1442 cur->fd = fd;
1443 cur->mmaplen = stbuf.st_size;
1444 cur->dead = 0;
1446 return 0;
1449 static int iax_check_version(char *dev)
1451 int res = 0;
1452 struct iax_firmware *cur;
1453 if (!ast_strlen_zero(dev)) {
1454 ast_mutex_lock(&waresl.lock);
1455 cur = waresl.wares;
1456 while(cur) {
1457 if (!strcmp(dev, (char *)cur->fwh->devname)) {
1458 res = ntohs(cur->fwh->version);
1459 break;
1461 cur = cur->next;
1463 ast_mutex_unlock(&waresl.lock);
1465 return res;
1468 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
1470 int res = -1;
1471 unsigned int bs = desc & 0xff;
1472 unsigned int start = (desc >> 8) & 0xffffff;
1473 unsigned int bytes;
1474 struct iax_firmware *cur;
1475 if (!ast_strlen_zero((char *)dev) && bs) {
1476 start *= bs;
1477 ast_mutex_lock(&waresl.lock);
1478 cur = waresl.wares;
1479 while(cur) {
1480 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
1481 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
1482 if (start < ntohl(cur->fwh->datalen)) {
1483 bytes = ntohl(cur->fwh->datalen) - start;
1484 if (bytes > bs)
1485 bytes = bs;
1486 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
1487 } else {
1488 bytes = 0;
1489 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
1491 if (bytes == bs)
1492 res = 0;
1493 else
1494 res = 1;
1495 break;
1497 cur = cur->next;
1499 ast_mutex_unlock(&waresl.lock);
1501 return res;
1505 static void reload_firmware(void)
1507 struct iax_firmware *cur, *curl, *curp;
1508 DIR *fwd;
1509 struct dirent *de;
1510 char dir[256];
1511 char fn[256];
1512 /* Mark all as dead */
1513 ast_mutex_lock(&waresl.lock);
1514 cur = waresl.wares;
1515 while(cur) {
1516 cur->dead = 1;
1517 cur = cur->next;
1519 /* Now that we've freed them, load the new ones */
1520 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
1521 fwd = opendir(dir);
1522 if (fwd) {
1523 while((de = readdir(fwd))) {
1524 if (de->d_name[0] != '.') {
1525 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
1526 if (!try_firmware(fn)) {
1527 if (option_verbose > 1)
1528 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
1532 closedir(fwd);
1533 } else
1534 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
1536 /* Clean up leftovers */
1537 cur = waresl.wares;
1538 curp = NULL;
1539 while(cur) {
1540 curl = cur;
1541 cur = cur->next;
1542 if (curl->dead) {
1543 if (curp) {
1544 curp->next = cur;
1545 } else {
1546 waresl.wares = cur;
1548 destroy_firmware(curl);
1549 } else {
1550 curp = cur;
1553 ast_mutex_unlock(&waresl.lock);
1556 static int __do_deliver(void *data)
1558 /* Just deliver the packet by using queueing. This is called by
1559 the IAX thread with the iaxsl lock held. */
1560 struct iax_frame *fr = data;
1561 fr->retrans = -1;
1562 fr->af.has_timing_info = 0;
1563 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
1564 iax2_queue_frame(fr->callno, &fr->af);
1565 /* Free our iax frame */
1566 iax2_frame_free(fr);
1567 /* And don't run again */
1568 return 0;
1571 static int handle_error(void)
1573 /* XXX Ideally we should figure out why an error occured and then abort those
1574 rather than continuing to try. Unfortunately, the published interface does
1575 not seem to work XXX */
1576 #if 0
1577 struct sockaddr_in *sin;
1578 int res;
1579 struct msghdr m;
1580 struct sock_extended_err e;
1581 m.msg_name = NULL;
1582 m.msg_namelen = 0;
1583 m.msg_iov = NULL;
1584 m.msg_control = &e;
1585 m.msg_controllen = sizeof(e);
1586 m.msg_flags = 0;
1587 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
1588 if (res < 0)
1589 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
1590 else {
1591 if (m.msg_controllen) {
1592 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
1593 if (sin)
1594 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
1595 else
1596 ast_log(LOG_WARNING, "No address detected??\n");
1597 } else {
1598 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
1601 #endif
1602 return 0;
1605 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
1607 int res;
1608 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
1609 sizeof(*sin));
1610 if (res < 0) {
1611 if (option_debug)
1612 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
1613 handle_error();
1614 } else
1615 res = 0;
1616 return res;
1619 static int send_packet(struct iax_frame *f)
1621 int res;
1622 int callno = f->callno;
1624 /* Don't send if there was an error, but return error instead */
1625 if (!callno || !iaxs[callno] || iaxs[callno]->error)
1626 return -1;
1628 /* Called with iaxsl held */
1629 if (option_debug > 2 && iaxdebug)
1630 ast_log(LOG_DEBUG, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
1631 if (f->transfer) {
1632 if (iaxdebug)
1633 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
1634 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
1635 sizeof(iaxs[callno]->transfer));
1636 } else {
1637 if (iaxdebug)
1638 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
1639 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
1640 sizeof(iaxs[callno]->addr));
1642 if (res < 0) {
1643 if (option_debug && iaxdebug)
1644 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
1645 handle_error();
1646 } else
1647 res = 0;
1648 return res;
1651 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
1653 struct iax2_user *user = NULL;
1655 /* Decrement AUTHREQ count if needed */
1656 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
1657 AST_LIST_LOCK(&users);
1658 AST_LIST_TRAVERSE(&users, user, entry) {
1659 if (!strcmp(user->name, pvt->username)) {
1660 user->curauthreq--;
1661 break;
1664 AST_LIST_UNLOCK(&users);
1665 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
1667 /* No more pings or lagrq's */
1668 if (pvt->pingid > -1)
1669 ast_sched_del(sched, pvt->pingid);
1670 pvt->pingid = -1;
1671 if (pvt->lagid > -1)
1672 ast_sched_del(sched, pvt->lagid);
1673 pvt->lagid = -1;
1674 if (pvt->autoid > -1)
1675 ast_sched_del(sched, pvt->autoid);
1676 pvt->autoid = -1;
1677 if (pvt->authid > -1)
1678 ast_sched_del(sched, pvt->authid);
1679 pvt->authid = -1;
1680 if (pvt->initid > -1)
1681 ast_sched_del(sched, pvt->initid);
1682 pvt->initid = -1;
1683 if (pvt->jbid > -1)
1684 ast_sched_del(sched, pvt->jbid);
1685 pvt->jbid = -1;
1688 static int iax2_predestroy(int callno)
1690 struct ast_channel *c;
1691 struct chan_iax2_pvt *pvt;
1692 ast_mutex_lock(&iaxsl[callno]);
1693 pvt = iaxs[callno];
1694 if (!pvt) {
1695 ast_mutex_unlock(&iaxsl[callno]);
1696 return -1;
1698 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
1699 iax2_destroy_helper(pvt);
1700 ast_set_flag(pvt, IAX_ALREADYGONE);
1702 c = pvt->owner;
1703 if (c) {
1704 c->_softhangup |= AST_SOFTHANGUP_DEV;
1705 c->tech_pvt = NULL;
1706 ast_queue_hangup(c);
1707 pvt->owner = NULL;
1708 ast_atomic_fetchadd_int(&usecnt, -1);
1709 ast_update_use_count();
1711 ast_mutex_unlock(&iaxsl[callno]);
1712 return 0;
1715 static int iax2_predestroy_nolock(int callno)
1717 int res;
1718 ast_mutex_unlock(&iaxsl[callno]);
1719 res = iax2_predestroy(callno);
1720 ast_mutex_lock(&iaxsl[callno]);
1721 return res;
1724 static void iax2_destroy(int callno)
1726 struct chan_iax2_pvt *pvt;
1727 struct iax_frame *cur;
1728 struct ast_channel *owner;
1730 retry:
1731 ast_mutex_lock(&iaxsl[callno]);
1732 pvt = iaxs[callno];
1733 gettimeofday(&lastused[callno], NULL);
1735 owner = pvt ? pvt->owner : NULL;
1737 if (owner) {
1738 if (ast_mutex_trylock(&owner->lock)) {
1739 ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
1740 ast_mutex_unlock(&iaxsl[callno]);
1741 usleep(1);
1742 goto retry;
1745 if (!owner)
1746 iaxs[callno] = NULL;
1747 if (pvt) {
1748 if (!owner)
1749 pvt->owner = NULL;
1750 iax2_destroy_helper(pvt);
1752 /* Already gone */
1753 ast_set_flag(pvt, IAX_ALREADYGONE);
1755 if (owner) {
1756 /* If there's an owner, prod it to give up */
1757 owner->_softhangup |= AST_SOFTHANGUP_DEV;
1758 ast_queue_hangup(owner);
1761 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
1762 /* Cancel any pending transmissions */
1763 if (cur->callno == pvt->callno)
1764 cur->retries = -1;
1766 if (pvt->reg)
1767 pvt->reg->callno = 0;
1768 if (!owner) {
1769 jb_frame frame;
1770 if (pvt->vars) {
1771 ast_variables_destroy(pvt->vars);
1772 pvt->vars = NULL;
1775 while (jb_getall(pvt->jb, &frame) == JB_OK)
1776 iax2_frame_free(frame.data);
1777 jb_destroy(pvt->jb);
1778 /* gotta free up the stringfields */
1779 ast_string_field_free_all(pvt);
1780 free(pvt);
1783 if (owner) {
1784 ast_mutex_unlock(&owner->lock);
1786 ast_mutex_unlock(&iaxsl[callno]);
1787 if (callno & 0x4000)
1788 update_max_trunk();
1790 static void iax2_destroy_nolock(int callno)
1792 /* Actually it's easier to unlock, kill it, and relock */
1793 ast_mutex_unlock(&iaxsl[callno]);
1794 iax2_destroy(callno);
1795 ast_mutex_lock(&iaxsl[callno]);
1798 static int update_packet(struct iax_frame *f)
1800 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
1801 struct ast_iax2_full_hdr *fh = f->data;
1802 /* Mark this as a retransmission */
1803 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
1804 /* Update iseqno */
1805 f->iseqno = iaxs[f->callno]->iseqno;
1806 fh->iseqno = f->iseqno;
1807 return 0;
1810 static int attempt_transmit(void *data);
1811 static void __attempt_transmit(void *data)
1813 /* Attempt to transmit the frame to the remote peer...
1814 Called without iaxsl held. */
1815 struct iax_frame *f = data;
1816 int freeme=0;
1817 int callno = f->callno;
1818 /* Make sure this call is still active */
1819 if (callno)
1820 ast_mutex_lock(&iaxsl[callno]);
1821 if (callno && iaxs[callno]) {
1822 if ((f->retries < 0) /* Already ACK'd */ ||
1823 (f->retries >= max_retries) /* Too many attempts */) {
1824 /* Record an error if we've transmitted too many times */
1825 if (f->retries >= max_retries) {
1826 if (f->transfer) {
1827 /* Transfer timeout */
1828 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
1829 } else if (f->final) {
1830 if (f->final)
1831 iax2_destroy_nolock(callno);
1832 } else {
1833 if (iaxs[callno]->owner)
1834 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
1835 iaxs[callno]->error = ETIMEDOUT;
1836 if (iaxs[callno]->owner) {
1837 struct ast_frame fr = { 0, };
1838 /* Hangup the fd */
1839 fr.frametype = AST_FRAME_CONTROL;
1840 fr.subclass = AST_CONTROL_HANGUP;
1841 iax2_queue_frame(callno, &fr);
1842 /* Remember, owner could disappear */
1843 if (iaxs[callno]->owner)
1844 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
1845 } else {
1846 if (iaxs[callno]->reg) {
1847 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
1848 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
1849 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
1851 iax2_destroy_nolock(callno);
1856 freeme++;
1857 } else {
1858 /* Update it if it needs it */
1859 update_packet(f);
1860 /* Attempt transmission */
1861 send_packet(f);
1862 f->retries++;
1863 /* Try again later after 10 times as long */
1864 f->retrytime *= 10;
1865 if (f->retrytime > MAX_RETRY_TIME)
1866 f->retrytime = MAX_RETRY_TIME;
1867 /* Transfer messages max out at one second */
1868 if (f->transfer && (f->retrytime > 1000))
1869 f->retrytime = 1000;
1870 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
1872 } else {
1873 /* Make sure it gets freed */
1874 f->retries = -1;
1875 freeme++;
1877 if (callno)
1878 ast_mutex_unlock(&iaxsl[callno]);
1879 /* Do not try again */
1880 if (freeme) {
1881 /* Don't attempt delivery, just remove it from the queue */
1882 AST_LIST_LOCK(&iaxq.queue);
1883 AST_LIST_REMOVE(&iaxq.queue, f, list);
1884 iaxq.count--;
1885 AST_LIST_UNLOCK(&iaxq.queue);
1886 f->retrans = -1;
1887 /* Free the IAX frame */
1888 iax2_frame_free(f);
1892 static int attempt_transmit(void *data)
1894 #ifdef SCHED_MULTITHREADED
1895 if (schedule_action(__attempt_transmit, data))
1896 #endif
1897 __attempt_transmit(data);
1898 return 0;
1901 static int iax2_prune_realtime(int fd, int argc, char *argv[])
1903 struct iax2_peer *peer;
1905 if (argc != 4)
1906 return RESULT_SHOWUSAGE;
1907 if (!strcmp(argv[3],"all")) {
1908 reload_config();
1909 ast_cli(fd, "OK cache is flushed.\n");
1910 } else if ((peer = find_peer(argv[3], 0))) {
1911 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
1912 ast_set_flag(peer, IAX_RTAUTOCLEAR);
1913 expire_registry((void*)peer->name);
1914 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
1915 } else {
1916 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
1918 } else {
1919 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
1922 return RESULT_SUCCESS;
1925 static int iax2_test_losspct(int fd, int argc, char *argv[])
1927 if (argc != 4)
1928 return RESULT_SHOWUSAGE;
1930 test_losspct = atoi(argv[3]);
1932 return RESULT_SUCCESS;
1935 #ifdef IAXTESTS
1936 static int iax2_test_late(int fd, int argc, char *argv[])
1938 if (argc != 4)
1939 return RESULT_SHOWUSAGE;
1941 test_late = atoi(argv[3]);
1943 return RESULT_SUCCESS;
1946 static int iax2_test_resync(int fd, int argc, char *argv[])
1948 if (argc != 4)
1949 return RESULT_SHOWUSAGE;
1951 test_resync = atoi(argv[3]);
1953 return RESULT_SUCCESS;
1956 static int iax2_test_jitter(int fd, int argc, char *argv[])
1958 if (argc < 4 || argc > 5)
1959 return RESULT_SHOWUSAGE;
1961 test_jit = atoi(argv[3]);
1962 if (argc == 5)
1963 test_jitpct = atoi(argv[4]);
1965 return RESULT_SUCCESS;
1967 #endif /* IAXTESTS */
1969 /*! \brief peer_status: Report Peer status in character string */
1970 /* returns 1 if peer is online, -1 if unmonitored */
1971 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
1973 int res = 0;
1974 if (peer->maxms) {
1975 if (peer->lastms < 0) {
1976 ast_copy_string(status, "UNREACHABLE", statuslen);
1977 } else if (peer->lastms > peer->maxms) {
1978 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
1979 res = 1;
1980 } else if (peer->lastms) {
1981 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
1982 res = 1;
1983 } else {
1984 ast_copy_string(status, "UNKNOWN", statuslen);
1986 } else {
1987 ast_copy_string(status, "Unmonitored", statuslen);
1988 res = -1;
1990 return res;
1993 /*! \brief Show one peer in detail */
1994 static int iax2_show_peer(int fd, int argc, char *argv[])
1996 char status[30];
1997 char cbuf[256];
1998 struct iax2_peer *peer;
1999 char codec_buf[512];
2000 int x = 0, codec = 0, load_realtime = 0;
2002 if (argc < 4)
2003 return RESULT_SHOWUSAGE;
2005 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
2007 peer = find_peer(argv[3], load_realtime);
2008 if (peer) {
2009 ast_cli(fd,"\n\n");
2010 ast_cli(fd, " * Name : %s\n", peer->name);
2011 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
2012 ast_cli(fd, " Context : %s\n", peer->context);
2013 ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
2014 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
2015 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
2016 ast_cli(fd, " Expire : %d\n", peer->expire);
2017 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
2018 ast_cli(fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
2019 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
2020 ast_cli(fd, " Username : %s\n", peer->username);
2021 ast_cli(fd, " Codecs : ");
2022 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
2023 ast_cli(fd, "%s\n", codec_buf);
2025 ast_cli(fd, " Codec Order : (");
2026 for(x = 0; x < 32 ; x++) {
2027 codec = ast_codec_pref_index(&peer->prefs,x);
2028 if(!codec)
2029 break;
2030 ast_cli(fd, "%s", ast_getformatname(codec));
2031 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
2032 ast_cli(fd, "|");
2035 if (!x)
2036 ast_cli(fd, "none");
2037 ast_cli(fd, ")\n");
2039 ast_cli(fd, " Status : ");
2040 peer_status(peer, status, sizeof(status));
2041 ast_cli(fd, "%s\n",status);
2042 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
2043 ast_cli(fd,"\n");
2044 if (ast_test_flag(peer, IAX_TEMPONLY))
2045 destroy_peer(peer);
2046 } else {
2047 ast_cli(fd,"Peer %s not found.\n", argv[3]);
2048 ast_cli(fd,"\n");
2051 return RESULT_SUCCESS;
2054 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
2056 int which = 0;
2057 struct iax2_peer *p = NULL;
2058 char *res = NULL;
2059 int wordlen = strlen(word);
2061 /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
2062 if (pos == 3) {
2063 AST_LIST_LOCK(&peers);
2064 AST_LIST_TRAVERSE(&peers, p, entry) {
2065 if (!strncasecmp(p->name, word, wordlen) && ++which > state) {
2066 res = ast_strdup(p->name);
2067 break;
2070 AST_LIST_UNLOCK(&peers);
2073 return res;
2076 static int iax2_show_stats(int fd, int argc, char *argv[])
2078 struct iax_frame *cur;
2079 int cnt = 0, dead=0, final=0;
2080 if (argc != 3)
2081 return RESULT_SHOWUSAGE;
2082 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
2083 if (cur->retries < 0)
2084 dead++;
2085 if (cur->final)
2086 final++;
2087 cnt++;
2089 ast_cli(fd, " IAX Statistics\n");
2090 ast_cli(fd, "---------------------\n");
2091 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
2092 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
2094 return RESULT_SUCCESS;
2097 static int iax2_show_cache(int fd, int argc, char *argv[])
2099 struct iax2_dpcache *dp;
2100 char tmp[1024], *pc;
2101 int s;
2102 int x,y;
2103 struct timeval tv;
2104 gettimeofday(&tv, NULL);
2105 ast_mutex_lock(&dpcache_lock);
2106 dp = dpcache;
2107 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
2108 while(dp) {
2109 s = dp->expiry.tv_sec - tv.tv_sec;
2110 tmp[0] = '\0';
2111 if (dp->flags & CACHE_FLAG_EXISTS)
2112 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
2113 if (dp->flags & CACHE_FLAG_NONEXISTENT)
2114 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
2115 if (dp->flags & CACHE_FLAG_CANEXIST)
2116 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
2117 if (dp->flags & CACHE_FLAG_PENDING)
2118 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
2119 if (dp->flags & CACHE_FLAG_TIMEOUT)
2120 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
2121 if (dp->flags & CACHE_FLAG_TRANSMITTED)
2122 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
2123 if (dp->flags & CACHE_FLAG_MATCHMORE)
2124 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
2125 if (dp->flags & CACHE_FLAG_UNKNOWN)
2126 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
2127 /* Trim trailing pipe */
2128 if (!ast_strlen_zero(tmp))
2129 tmp[strlen(tmp) - 1] = '\0';
2130 else
2131 ast_copy_string(tmp, "(none)", sizeof(tmp));
2132 y=0;
2133 pc = strchr(dp->peercontext, '@');
2134 if (!pc)
2135 pc = dp->peercontext;
2136 else
2137 pc++;
2138 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
2139 if (dp->waiters[x] > -1)
2140 y++;
2141 if (s > 0)
2142 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
2143 else
2144 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
2145 dp = dp->next;
2147 ast_mutex_unlock(&dpcache_lock);
2148 return RESULT_SUCCESS;
2151 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
2153 static void unwrap_timestamp(struct iax_frame *fr)
2155 int x;
2157 if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
2158 x = fr->ts - iaxs[fr->callno]->last;
2159 if (x < -50000) {
2160 /* Sudden big jump backwards in timestamp:
2161 What likely happened here is that miniframe timestamp has circled but we haven't
2162 gotten the update from the main packet. We'll just pretend that we did, and
2163 update the timestamp appropriately. */
2164 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
2165 if (option_debug && iaxdebug)
2166 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
2168 if (x > 50000) {
2169 /* Sudden apparent big jump forwards in timestamp:
2170 What's likely happened is this is an old miniframe belonging to the previous
2171 top-16-bit timestamp that has turned up out of order.
2172 Adjust the timestamp appropriately. */
2173 fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
2174 if (option_debug && iaxdebug)
2175 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
2180 static int get_from_jb(void *p);
2182 static void update_jbsched(struct chan_iax2_pvt *pvt)
2184 int when;
2186 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
2188 when = jb_next(pvt->jb) - when;
2190 if(pvt->jbid > -1) ast_sched_del(sched, pvt->jbid);
2192 if(when <= 0) {
2193 /* XXX should really just empty until when > 0.. */
2194 when = 1;
2197 pvt->jbid = ast_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
2199 /* Signal scheduler thread */
2200 signal_condition(&sched_lock, &sched_cond);
2203 static void __get_from_jb(void *p)
2205 int callno = PTR_TO_CALLNO(p);
2206 struct chan_iax2_pvt *pvt = NULL;
2207 struct iax_frame *fr;
2208 jb_frame frame;
2209 int ret;
2210 long now;
2211 long next;
2212 struct timeval tv;
2214 /* Make sure we have a valid private structure before going on */
2215 ast_mutex_lock(&iaxsl[callno]);
2216 pvt = iaxs[callno];
2217 if (!pvt) {
2218 /* No go! */
2219 ast_mutex_unlock(&iaxsl[callno]);
2220 return;
2223 pvt->jbid = -1;
2225 gettimeofday(&tv,NULL);
2226 /* round up a millisecond since ast_sched_runq does; */
2227 /* prevents us from spinning while waiting for our now */
2228 /* to catch up with runq's now */
2229 tv.tv_usec += 1000;
2231 now = ast_tvdiff_ms(tv, pvt->rxcore);
2233 if(now >= (next = jb_next(pvt->jb))) {
2234 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
2235 switch(ret) {
2236 case JB_OK:
2237 fr = frame.data;
2238 __do_deliver(fr);
2239 break;
2240 case JB_INTERP:
2242 struct ast_frame af;
2244 /* create an interpolation frame */
2245 af.frametype = AST_FRAME_VOICE;
2246 af.subclass = pvt->voiceformat;
2247 af.datalen = 0;
2248 af.samples = frame.ms * 8;
2249 af.mallocd = 0;
2250 af.src = "IAX2 JB interpolation";
2251 af.data = NULL;
2252 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
2253 af.offset=AST_FRIENDLY_OFFSET;
2255 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
2256 * which we'd need to malloc, and then it would free it. That seems like a drag */
2257 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
2258 iax2_queue_frame(callno, &af);
2260 break;
2261 case JB_DROP:
2262 iax2_frame_free(frame.data);
2263 break;
2264 case JB_NOFRAME:
2265 case JB_EMPTY:
2266 /* do nothing */
2267 break;
2268 default:
2269 /* shouldn't happen */
2270 break;
2273 update_jbsched(pvt);
2274 ast_mutex_unlock(&iaxsl[callno]);
2277 static int get_from_jb(void *data)
2279 #ifdef SCHED_MULTITHREADED
2280 if (schedule_action(__get_from_jb, data))
2281 #endif
2282 __get_from_jb(data);
2283 return 0;
2286 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
2288 int type, len;
2289 int ret;
2290 int needfree = 0;
2292 /* Attempt to recover wrapped timestamps */
2293 unwrap_timestamp(fr);
2296 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
2297 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
2298 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
2299 else {
2300 #if 0
2301 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
2302 #endif
2303 fr->af.delivery = ast_tv(0,0);
2306 type = JB_TYPE_CONTROL;
2307 len = 0;
2309 if(fr->af.frametype == AST_FRAME_VOICE) {
2310 type = JB_TYPE_VOICE;
2311 len = ast_codec_get_samples(&fr->af) / 8;
2312 } else if(fr->af.frametype == AST_FRAME_CNG) {
2313 type = JB_TYPE_SILENCE;
2316 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
2317 if (tsout)
2318 *tsout = fr->ts;
2319 __do_deliver(fr);
2320 return -1;
2323 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
2324 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
2325 if( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) &&
2326 iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) &&
2327 (ast_bridged_channel(iaxs[fr->callno]->owner)->tech->properties & AST_CHAN_TP_WANTSJITTER)) {
2328 jb_frame frame;
2330 /* deliver any frames in the jb */
2331 while(jb_getall(iaxs[fr->callno]->jb,&frame) == JB_OK)
2332 __do_deliver(frame.data);
2334 jb_reset(iaxs[fr->callno]->jb);
2336 if (iaxs[fr->callno]->jbid > -1)
2337 ast_sched_del(sched, iaxs[fr->callno]->jbid);
2339 iaxs[fr->callno]->jbid = -1;
2341 /* deliver this frame now */
2342 if (tsout)
2343 *tsout = fr->ts;
2344 __do_deliver(fr);
2345 return -1;
2348 /* insert into jitterbuffer */
2349 /* TODO: Perhaps we could act immediately if it's not droppable and late */
2350 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
2351 calc_rxstamp(iaxs[fr->callno],fr->ts));
2352 if (ret == JB_DROP) {
2353 needfree++;
2354 } else if (ret == JB_SCHED) {
2355 update_jbsched(iaxs[fr->callno]);
2357 if (tsout)
2358 *tsout = fr->ts;
2359 if (needfree) {
2360 /* Free our iax frame */
2361 iax2_frame_free(fr);
2362 return -1;
2364 return 0;
2367 static int iax2_transmit(struct iax_frame *fr)
2369 /* Lock the queue and place this packet at the end */
2370 /* By setting this to 0, the network thread will send it for us, and
2371 queue retransmission if necessary */
2372 fr->sentyet = 0;
2373 AST_LIST_LOCK(&iaxq.queue);
2374 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
2375 iaxq.count++;
2376 AST_LIST_UNLOCK(&iaxq.queue);
2377 /* Wake up the network and scheduler thread */
2378 pthread_kill(netthreadid, SIGURG);
2379 signal_condition(&sched_lock, &sched_cond);
2380 return 0;
2385 static int iax2_digit_begin(struct ast_channel *c, char digit)
2387 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
2390 static int iax2_digit_end(struct ast_channel *c, char digit)
2392 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
2395 static int iax2_sendtext(struct ast_channel *c, const char *text)
2398 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
2399 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
2402 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
2404 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
2407 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
2409 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
2412 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
2414 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
2415 ast_mutex_lock(&iaxsl[callno]);
2416 if (iaxs[callno])
2417 iaxs[callno]->owner = newchan;
2418 else
2419 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
2420 ast_mutex_unlock(&iaxsl[callno]);
2421 return 0;
2424 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
2426 struct ast_variable *var;
2427 struct ast_variable *tmp;
2428 struct iax2_peer *peer=NULL;
2429 time_t regseconds = 0, nowtime;
2430 int dynamic=0;
2432 if (peername)
2433 var = ast_load_realtime("iaxpeers", "name", peername, NULL);
2434 else {
2435 char porta[25];
2436 sprintf(porta, "%d", ntohs(sin->sin_port));
2437 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
2438 if (var) {
2439 /* We'll need the peer name in order to build the structure! */
2440 for (tmp = var; tmp; tmp = tmp->next) {
2441 if (!strcasecmp(tmp->name, "name"))
2442 peername = tmp->value;
2446 if (!var)
2447 return NULL;
2449 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
2451 if (!peer)
2452 return NULL;
2454 for (tmp = var; tmp; tmp = tmp->next) {
2455 /* Make sure it's not a user only... */
2456 if (!strcasecmp(tmp->name, "type")) {
2457 if (strcasecmp(tmp->value, "friend") &&
2458 strcasecmp(tmp->value, "peer")) {
2459 /* Whoops, we weren't supposed to exist! */
2460 destroy_peer(peer);
2461 peer = NULL;
2462 break;
2464 } else if (!strcasecmp(tmp->name, "regseconds")) {
2465 ast_get_time_t(tmp->value, &regseconds, 0, NULL);
2466 } else if (!strcasecmp(tmp->name, "ipaddr")) {
2467 inet_aton(tmp->value, &(peer->addr.sin_addr));
2468 } else if (!strcasecmp(tmp->name, "port")) {
2469 peer->addr.sin_port = htons(atoi(tmp->value));
2470 } else if (!strcasecmp(tmp->name, "host")) {
2471 if (!strcasecmp(tmp->value, "dynamic"))
2472 dynamic = 1;
2475 if (!peer)
2476 return NULL;
2478 ast_variables_destroy(var);
2480 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
2481 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
2482 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
2483 if (peer->expire > -1)
2484 ast_sched_del(sched, peer->expire);
2485 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
2487 AST_LIST_LOCK(&peers);
2488 AST_LIST_INSERT_HEAD(&peers, peer, entry);
2489 AST_LIST_UNLOCK(&peers);
2490 if (ast_test_flag(peer, IAX_DYNAMIC))
2491 reg_source_db(peer);
2492 } else {
2493 ast_set_flag(peer, IAX_TEMPONLY);
2496 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
2497 time(&nowtime);
2498 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
2499 memset(&peer->addr, 0, sizeof(peer->addr));
2500 realtime_update_peer(peer->name, &peer->addr, 0);
2501 if (option_debug)
2502 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
2503 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
2505 else {
2506 if (option_debug)
2507 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
2508 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
2512 return peer;
2515 static struct iax2_user *realtime_user(const char *username)
2517 struct ast_variable *var;
2518 struct ast_variable *tmp;
2519 struct iax2_user *user=NULL;
2521 var = ast_load_realtime("iaxusers", "name", username, NULL);
2522 if (!var)
2523 return NULL;
2525 tmp = var;
2526 while(tmp) {
2527 /* Make sure it's not a peer only... */
2528 if (!strcasecmp(tmp->name, "type")) {
2529 if (strcasecmp(tmp->value, "friend") &&
2530 strcasecmp(tmp->value, "user")) {
2531 return NULL;
2534 tmp = tmp->next;
2537 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
2538 if (!user)
2539 return NULL;
2541 ast_variables_destroy(var);
2543 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
2544 ast_set_flag(user, IAX_RTCACHEFRIENDS);
2545 AST_LIST_LOCK(&users);
2546 AST_LIST_INSERT_HEAD(&users, user, entry);
2547 AST_LIST_UNLOCK(&users);
2548 } else {
2549 ast_set_flag(user, IAX_TEMPONLY);
2552 return user;
2555 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
2557 char port[10];
2558 char regseconds[20];
2560 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
2561 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
2562 ast_update_realtime("iaxpeers", "name", peername,
2563 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
2564 "regseconds", regseconds, NULL);
2567 struct create_addr_info {
2568 int capability;
2569 unsigned int flags;
2570 int maxtime;
2571 int encmethods;
2572 int found;
2573 int sockfd;
2574 int adsi;
2575 char username[80];
2576 char secret[80];
2577 char outkey[80];
2578 char timezone[80];
2579 char prefs[32];
2580 char context[AST_MAX_CONTEXT];
2581 char peercontext[AST_MAX_CONTEXT];
2582 char mohinterpret[MAX_MUSICCLASS];
2583 char mohsuggest[MAX_MUSICCLASS];
2586 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
2588 struct ast_hostent ahp;
2589 struct hostent *hp;
2590 struct iax2_peer *peer;
2592 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
2593 cai->sockfd = defaultsockfd;
2594 cai->maxtime = 0;
2595 sin->sin_family = AF_INET;
2597 if (!(peer = find_peer(peername, 1))) {
2598 cai->found = 0;
2600 hp = ast_gethostbyname(peername, &ahp);
2601 if (hp) {
2602 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
2603 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
2604 /* use global iax prefs for unknown peer/user */
2605 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
2606 return 0;
2607 } else {
2608 ast_log(LOG_WARNING, "No such host: %s\n", peername);
2609 return -1;
2613 cai->found = 1;
2615 /* if the peer has no address (current or default), return failure */
2616 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
2617 if (ast_test_flag(peer, IAX_TEMPONLY))
2618 destroy_peer(peer);
2619 return -1;
2622 /* if the peer is being monitored and is currently unreachable, return failure */
2623 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
2624 if (ast_test_flag(peer, IAX_TEMPONLY))
2625 destroy_peer(peer);
2626 return -1;
2629 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
2630 cai->maxtime = peer->maxms;
2631 cai->capability = peer->capability;
2632 cai->encmethods = peer->encmethods;
2633 cai->sockfd = peer->sockfd;
2634 cai->adsi = peer->adsi;
2635 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
2636 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
2637 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
2638 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
2639 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
2640 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
2641 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
2642 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
2643 if (ast_strlen_zero(peer->dbsecret)) {
2644 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
2645 } else {
2646 char *family;
2647 char *key = NULL;
2649 family = ast_strdupa(peer->dbsecret);
2650 key = strchr(family, '/');
2651 if (key)
2652 *key++ = '\0';
2653 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
2654 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
2655 if (ast_test_flag(peer, IAX_TEMPONLY))
2656 destroy_peer(peer);
2657 return -1;
2661 if (peer->addr.sin_addr.s_addr) {
2662 sin->sin_addr = peer->addr.sin_addr;
2663 sin->sin_port = peer->addr.sin_port;
2664 } else {
2665 sin->sin_addr = peer->defaddr.sin_addr;
2666 sin->sin_port = peer->defaddr.sin_port;
2669 if (ast_test_flag(peer, IAX_TEMPONLY))
2670 destroy_peer(peer);
2672 return 0;
2675 static void __auto_congest(void *nothing)
2677 int callno = PTR_TO_CALLNO(nothing);
2678 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
2679 ast_mutex_lock(&iaxsl[callno]);
2680 if (iaxs[callno]) {
2681 iaxs[callno]->initid = -1;
2682 iax2_queue_frame(callno, &f);
2683 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
2685 ast_mutex_unlock(&iaxsl[callno]);
2688 static int auto_congest(void *data)
2690 #ifdef SCHED_MULTITHREADED
2691 if (schedule_action(__auto_congest, data))
2692 #endif
2693 __auto_congest(data);
2694 return 0;
2697 static unsigned int iax2_datetime(const char *tz)
2699 time_t t;
2700 struct tm tm;
2701 unsigned int tmp;
2702 time(&t);
2703 localtime_r(&t, &tm);
2704 if (!ast_strlen_zero(tz))
2705 ast_localtime(&t, &tm, tz);
2706 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */
2707 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */
2708 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */
2709 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */
2710 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */
2711 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
2712 return tmp;
2715 struct parsed_dial_string {
2716 char *username;
2717 char *password;
2718 char *key;
2719 char *peer;
2720 char *port;
2721 char *exten;
2722 char *context;
2723 char *options;
2727 * \brief Parses an IAX dial string into its component parts.
2728 * \param data the string to be parsed
2729 * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
2730 * \return nothing
2732 * This function parses the string and fills the structure
2733 * with pointers to its component parts. The input string
2734 * will be modified.
2736 * \note This function supports both plaintext passwords and RSA
2737 * key names; if the password string is formatted as '[keyname]',
2738 * then the keyname will be placed into the key field, and the
2739 * password field will be set to NULL.
2741 * \note The dial string format is:
2742 * [username[:password]@]peer[:port][/exten[@@context]][/options]
2744 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
2746 if (ast_strlen_zero(data))
2747 return;
2749 pds->peer = strsep(&data, "/");
2750 pds->exten = strsep(&data, "/");
2751 pds->options = data;
2753 if (pds->exten) {
2754 data = pds->exten;
2755 pds->exten = strsep(&data, "@");
2756 pds->context = data;
2759 if (strchr(pds->peer, '@')) {
2760 data = pds->peer;
2761 pds->username = strsep(&data, "@");
2762 pds->peer = data;
2765 if (pds->username) {
2766 data = pds->username;
2767 pds->username = strsep(&data, ":");
2768 pds->password = data;
2771 data = pds->peer;
2772 pds->peer = strsep(&data, ":");
2773 pds->port = data;
2775 /* check for a key name wrapped in [] in the secret position, if found,
2776 move it to the key field instead
2778 if (pds->password && (pds->password[0] == '[')) {
2779 pds->key = ast_strip_quoted(pds->password, "[", "]");
2780 pds->password = NULL;
2784 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
2786 struct sockaddr_in sin;
2787 char *l=NULL, *n=NULL, *tmpstr;
2788 struct iax_ie_data ied;
2789 char *defaultrdest = "s";
2790 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
2791 struct parsed_dial_string pds;
2792 struct create_addr_info cai;
2794 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
2795 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
2796 return -1;
2799 memset(&cai, 0, sizeof(cai));
2800 cai.encmethods = iax2_encryption;
2802 memset(&pds, 0, sizeof(pds));
2803 tmpstr = ast_strdupa(dest);
2804 parse_dial_string(tmpstr, &pds);
2806 if (!pds.exten)
2807 pds.exten = defaultrdest;
2809 if (create_addr(pds.peer, &sin, &cai)) {
2810 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
2811 return -1;
2814 if (!pds.username && !ast_strlen_zero(cai.username))
2815 pds.username = cai.username;
2816 if (!pds.password && !ast_strlen_zero(cai.secret))
2817 pds.password = cai.secret;
2818 if (!pds.key && !ast_strlen_zero(cai.outkey))
2819 pds.key = cai.outkey;
2820 if (!pds.context && !ast_strlen_zero(cai.peercontext))
2821 pds.context = cai.peercontext;
2823 /* Keep track of the context for outgoing calls too */
2824 ast_copy_string(c->context, cai.context, sizeof(c->context));
2826 if (pds.port)
2827 sin.sin_port = htons(atoi(pds.port));
2829 l = c->cid.cid_num;
2830 n = c->cid.cid_name;
2832 /* Now build request */
2833 memset(&ied, 0, sizeof(ied));
2835 /* On new call, first IE MUST be IAX version of caller */
2836 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
2837 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
2838 if (pds.options && strchr(pds.options, 'a')) {
2839 /* Request auto answer */
2840 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
2843 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
2845 if (l) {
2846 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
2847 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
2848 } else {
2849 if (n)
2850 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
2851 else
2852 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
2855 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
2856 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
2858 if (n)
2859 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
2860 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
2861 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
2863 if (!ast_strlen_zero(c->language))
2864 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
2865 if (!ast_strlen_zero(c->cid.cid_dnid))
2866 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
2867 if (!ast_strlen_zero(c->cid.cid_rdnis))
2868 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
2870 if (pds.context)
2871 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
2873 if (pds.username)
2874 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
2876 if (cai.encmethods)
2877 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
2879 ast_mutex_lock(&iaxsl[callno]);
2881 if (!ast_strlen_zero(c->context))
2882 ast_string_field_set(iaxs[callno], context, c->context);
2884 if (pds.username)
2885 ast_string_field_set(iaxs[callno], username, pds.username);
2887 iaxs[callno]->encmethods = cai.encmethods;
2889 iaxs[callno]->adsi = cai.adsi;
2891 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
2892 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
2894 if (pds.key)
2895 ast_string_field_set(iaxs[callno], outkey, pds.key);
2896 if (pds.password)
2897 ast_string_field_set(iaxs[callno], secret, pds.password);
2899 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
2900 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
2901 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
2902 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
2904 if (iaxs[callno]->maxtime) {
2905 /* Initialize pingtime and auto-congest time */
2906 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
2907 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
2908 } else if (autokill) {
2909 iaxs[callno]->pingtime = autokill / 2;
2910 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
2913 /* Transmit the string in a "NEW" request */
2914 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
2916 ast_mutex_unlock(&iaxsl[callno]);
2917 ast_setstate(c, AST_STATE_RINGING);
2919 return 0;
2922 static int iax2_hangup(struct ast_channel *c)
2924 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
2925 int alreadygone;
2926 struct iax_ie_data ied;
2927 memset(&ied, 0, sizeof(ied));
2928 ast_mutex_lock(&iaxsl[callno]);
2929 if (callno && iaxs[callno]) {
2930 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
2931 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
2932 /* Send the hangup unless we have had a transmission error or are already gone */
2933 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
2934 if (!iaxs[callno]->error && !alreadygone)
2935 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
2936 /* Explicitly predestroy it */
2937 iax2_predestroy_nolock(callno);
2938 /* If we were already gone to begin with, destroy us now */
2939 if (alreadygone) {
2940 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
2941 iax2_destroy_nolock(callno);
2944 ast_mutex_unlock(&iaxsl[callno]);
2945 if (option_verbose > 2)
2946 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
2947 return 0;
2950 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
2952 struct ast_option_header *h;
2953 int res;
2955 switch (option) {
2956 case AST_OPTION_TXGAIN:
2957 case AST_OPTION_RXGAIN:
2958 /* these two cannot be sent, because they require a result */
2959 errno = ENOSYS;
2960 return -1;
2961 default:
2962 if (!(h = ast_malloc(datalen + sizeof(*h))))
2963 return -1;
2965 h->flag = AST_OPTION_FLAG_REQUEST;
2966 h->option = htons(option);
2967 memcpy(h->data, data, datalen);
2968 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
2969 AST_CONTROL_OPTION, 0, (unsigned char *) h,
2970 datalen + sizeof(*h), -1);
2971 free(h);
2972 return res;
2976 static struct ast_frame *iax2_read(struct ast_channel *c)
2978 ast_log(LOG_NOTICE, "I should never be called!\n");
2979 return &ast_null_frame;
2982 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
2984 int res;
2985 struct iax_ie_data ied0;
2986 struct iax_ie_data ied1;
2987 unsigned int transferid = (unsigned int)ast_random();
2988 memset(&ied0, 0, sizeof(ied0));
2989 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
2990 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
2991 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
2993 memset(&ied1, 0, sizeof(ied1));
2994 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
2995 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
2996 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
2998 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
2999 if (res)
3000 return -1;
3001 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
3002 if (res)
3003 return -1;
3004 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
3005 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
3006 return 0;
3009 static void lock_both(unsigned short callno0, unsigned short callno1)
3011 ast_mutex_lock(&iaxsl[callno0]);
3012 while (ast_mutex_trylock(&iaxsl[callno1])) {
3013 ast_mutex_unlock(&iaxsl[callno0]);
3014 usleep(10);
3015 ast_mutex_lock(&iaxsl[callno0]);
3019 static void unlock_both(unsigned short callno0, unsigned short callno1)
3021 ast_mutex_unlock(&iaxsl[callno1]);
3022 ast_mutex_unlock(&iaxsl[callno0]);
3025 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
3027 struct ast_channel *cs[3];
3028 struct ast_channel *who, *other;
3029 int to = -1;
3030 int res = -1;
3031 int transferstarted=0;
3032 struct ast_frame *f;
3033 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
3034 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
3035 struct timeval waittimer = {0, 0}, tv;
3037 lock_both(callno0, callno1);
3038 /* Put them in native bridge mode */
3039 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
3040 iaxs[callno0]->bridgecallno = callno1;
3041 iaxs[callno1]->bridgecallno = callno0;
3043 unlock_both(callno0, callno1);
3045 /* If not, try to bridge until we can execute a transfer, if we can */
3046 cs[0] = c0;
3047 cs[1] = c1;
3048 for (/* ever */;;) {
3049 /* Check in case we got masqueraded into */
3050 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
3051 if (option_verbose > 2)
3052 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
3053 /* Remove from native mode */
3054 if (c0->tech == &iax2_tech) {
3055 ast_mutex_lock(&iaxsl[callno0]);
3056 iaxs[callno0]->bridgecallno = 0;
3057 ast_mutex_unlock(&iaxsl[callno0]);
3059 if (c1->tech == &iax2_tech) {
3060 ast_mutex_lock(&iaxsl[callno1]);
3061 iaxs[callno1]->bridgecallno = 0;
3062 ast_mutex_unlock(&iaxsl[callno1]);
3064 return AST_BRIDGE_FAILED_NOWARN;
3066 if (c0->nativeformats != c1->nativeformats) {
3067 if (option_verbose > 2) {
3068 char buf0[255];
3069 char buf1[255];
3070 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
3071 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
3072 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
3074 /* Remove from native mode */
3075 lock_both(callno0, callno1);
3076 iaxs[callno0]->bridgecallno = 0;
3077 iaxs[callno1]->bridgecallno = 0;
3078 unlock_both(callno0, callno1);
3079 return AST_BRIDGE_FAILED_NOWARN;
3081 /* check if transfered and if we really want native bridging */
3082 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
3083 /* Try the transfer */
3084 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
3085 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
3086 ast_log(LOG_WARNING, "Unable to start the transfer\n");
3087 transferstarted = 1;
3089 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
3090 /* Call has been transferred. We're no longer involved */
3091 gettimeofday(&tv, NULL);
3092 if (ast_tvzero(waittimer)) {
3093 waittimer = tv;
3094 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
3095 c0->_softhangup |= AST_SOFTHANGUP_DEV;
3096 c1->_softhangup |= AST_SOFTHANGUP_DEV;
3097 *fo = NULL;
3098 *rc = c0;
3099 res = AST_BRIDGE_COMPLETE;
3100 break;
3103 to = 1000;
3104 who = ast_waitfor_n(cs, 2, &to);
3105 if (timeoutms > -1) {
3106 timeoutms -= (1000 - to);
3107 if (timeoutms < 0)
3108 timeoutms = 0;
3110 if (!who) {
3111 if (!timeoutms) {
3112 res = AST_BRIDGE_RETRY;
3113 break;
3115 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
3116 res = AST_BRIDGE_FAILED;
3117 break;
3119 continue;
3121 f = ast_read(who);
3122 if (!f) {
3123 *fo = NULL;
3124 *rc = who;
3125 res = AST_BRIDGE_COMPLETE;
3126 break;
3128 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
3129 *fo = f;
3130 *rc = who;
3131 res = AST_BRIDGE_COMPLETE;
3132 break;
3134 other = (who == c0) ? c1 : c0; /* the 'other' channel */
3135 if ((f->frametype == AST_FRAME_VOICE) ||
3136 (f->frametype == AST_FRAME_TEXT) ||
3137 (f->frametype == AST_FRAME_VIDEO) ||
3138 (f->frametype == AST_FRAME_IMAGE) ||
3139 (f->frametype == AST_FRAME_DTMF)) {
3140 /* monitored dtmf take out of the bridge.
3141 * check if we monitor the specific source.
3143 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
3144 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
3145 *rc = who;
3146 *fo = f;
3147 res = AST_BRIDGE_COMPLETE;
3148 /* Remove from native mode */
3149 break;
3151 /* everything else goes to the other side */
3152 ast_write(other, f);
3154 ast_frfree(f);
3155 /* Swap who gets priority */
3156 cs[2] = cs[0];
3157 cs[0] = cs[1];
3158 cs[1] = cs[2];
3160 lock_both(callno0, callno1);
3161 if(iaxs[callno0])
3162 iaxs[callno0]->bridgecallno = 0;
3163 if(iaxs[callno1])
3164 iaxs[callno1]->bridgecallno = 0;
3165 unlock_both(callno0, callno1);
3166 return res;
3169 static int iax2_answer(struct ast_channel *c)
3171 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
3172 if (option_debug)
3173 ast_log(LOG_DEBUG, "Answering IAX2 call\n");
3174 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
3177 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
3179 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
3181 if (option_debug && iaxdebug)
3182 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
3184 if (!strcasecmp(iaxs[callno]->mohinterpret, "passthrough"))
3185 return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
3187 switch (condition) {
3188 case AST_CONTROL_HOLD:
3189 ast_moh_start(c, data, iaxs[callno]->mohinterpret);
3190 return 0;
3191 case AST_CONTROL_UNHOLD:
3192 ast_moh_stop(c);
3193 return 0;
3194 default:
3195 return send_command_locked(callno, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
3199 static int iax2_transfer(struct ast_channel *c, const char *dest)
3201 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
3202 struct iax_ie_data ied;
3203 char tmp[256], *context;
3204 ast_copy_string(tmp, dest, sizeof(tmp));
3205 context = strchr(tmp, '@');
3206 if (context) {
3207 *context = '\0';
3208 context++;
3210 memset(&ied, 0, sizeof(ied));
3211 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
3212 if (context)
3213 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
3214 if (option_debug)
3215 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
3216 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
3219 static int iax2_getpeertrunk(struct sockaddr_in sin)
3221 struct iax2_peer *peer = NULL;
3222 int res = 0;
3224 AST_LIST_LOCK(&peers);
3225 AST_LIST_TRAVERSE(&peers, peer, entry) {
3226 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
3227 (peer->addr.sin_port == sin.sin_port)) {
3228 res = ast_test_flag(peer, IAX_TRUNK);
3229 break;
3232 AST_LIST_UNLOCK(&peers);
3234 return res;
3237 /*! \brief Create new call, interface with the PBX core */
3238 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
3240 struct ast_channel *tmp;
3241 struct chan_iax2_pvt *i;
3242 struct ast_variable *v = NULL;
3244 if (!(i = iaxs[callno])) {
3245 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
3246 return NULL;
3249 /* Don't hold call lock */
3250 ast_mutex_unlock(&iaxsl[callno]);
3251 tmp = ast_channel_alloc(1);
3252 ast_mutex_lock(&iaxsl[callno]);
3253 if (!tmp)
3254 return NULL;
3255 tmp->tech = &iax2_tech;
3256 ast_string_field_build(tmp, name, "IAX2/%s-%d", i->host, i->callno);
3257 /* We can support any format by default, until we get restricted */
3258 tmp->nativeformats = capability;
3259 tmp->readformat = ast_best_codec(capability);
3260 tmp->writeformat = ast_best_codec(capability);
3261 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
3263 /* Don't use ast_set_callerid() here because it will
3264 * generate a NewCallerID event before the NewChannel event */
3265 tmp->cid.cid_num = ast_strdup(i->cid_num);
3266 tmp->cid.cid_name = ast_strdup(i->cid_name);
3267 if (!ast_strlen_zero(i->ani))
3268 tmp->cid.cid_ani = ast_strdup(i->ani);
3269 else
3270 tmp->cid.cid_ani = ast_strdup(i->cid_num);
3271 tmp->cid.cid_dnid = ast_strdup(i->dnid);
3272 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
3273 tmp->cid.cid_pres = i->calling_pres;
3274 tmp->cid.cid_ton = i->calling_ton;
3275 tmp->cid.cid_tns = i->calling_tns;
3276 if (!ast_strlen_zero(i->language))
3277 ast_string_field_set(tmp, language, i->language);
3278 if (!ast_strlen_zero(i->accountcode))
3279 ast_string_field_set(tmp, accountcode, i->accountcode);
3280 if (i->amaflags)
3281 tmp->amaflags = i->amaflags;
3282 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
3283 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
3284 if (i->adsi)
3285 tmp->adsicpe = i->peeradsicpe;
3286 else
3287 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
3288 i->owner = tmp;
3289 i->capability = capability;
3290 ast_setstate(tmp, state);
3291 if (state != AST_STATE_DOWN) {
3292 if (ast_pbx_start(tmp)) {
3293 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
3294 ast_hangup(tmp);
3295 i->owner = NULL;
3296 return NULL;
3300 for (v = i->vars ; v ; v = v->next)
3301 pbx_builtin_setvar_helper(tmp, v->name, v->value);
3303 ast_atomic_fetchadd_int(&usecnt, 1);
3304 ast_update_use_count();
3306 return tmp;
3309 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
3311 unsigned long int mssincetx; /* unsigned to handle overflows */
3312 long int ms, pred;
3314 tpeer->trunkact = *tv;
3315 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
3316 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
3317 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
3318 tpeer->txtrunktime = *tv;
3319 tpeer->lastsent = 999999;
3321 /* Update last transmit time now */
3322 tpeer->lasttxtime = *tv;
3324 /* Calculate ms offset */
3325 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
3326 /* Predict from last value */
3327 pred = tpeer->lastsent + sampms;
3328 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
3329 ms = pred;
3331 /* We never send the same timestamp twice, so fudge a little if we must */
3332 if (ms == tpeer->lastsent)
3333 ms = tpeer->lastsent + 1;
3334 tpeer->lastsent = ms;
3335 return ms;
3338 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
3340 long ms; /* NOT unsigned */
3341 if (ast_tvzero(iaxs[callno]->rxcore)) {
3342 /* Initialize rxcore time if appropriate */
3343 gettimeofday(&iaxs[callno]->rxcore, NULL);
3344 /* Round to nearest 20ms so traces look pretty */
3345 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
3347 /* Calculate difference between trunk and channel */
3348 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
3349 /* Return as the sum of trunk time and the difference between trunk and real time */
3350 return ms + ts;
3353 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
3355 int ms;
3356 int voice = 0;
3357 int genuine = 0;
3358 int adjust;
3359 struct timeval *delivery = NULL;
3362 /* What sort of frame do we have?: voice is self-explanatory
3363 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
3364 non-genuine frames are CONTROL frames [ringing etc], DTMF
3365 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
3366 the others need a timestamp slaved to the voice frames so that they go in sequence
3368 if (f) {
3369 if (f->frametype == AST_FRAME_VOICE) {
3370 voice = 1;
3371 delivery = &f->delivery;
3372 } else if (f->frametype == AST_FRAME_IAX) {
3373 genuine = 1;
3374 } else if (f->frametype == AST_FRAME_CNG) {
3375 p->notsilenttx = 0;
3378 if (ast_tvzero(p->offset)) {
3379 gettimeofday(&p->offset, NULL);
3380 /* Round to nearest 20ms for nice looking traces */
3381 p->offset.tv_usec -= p->offset.tv_usec % 20000;
3383 /* If the timestamp is specified, just send it as is */
3384 if (ts)
3385 return ts;
3386 /* If we have a time that the frame arrived, always use it to make our timestamp */
3387 if (delivery && !ast_tvzero(*delivery)) {
3388 ms = ast_tvdiff_ms(*delivery, p->offset);
3389 if (option_debug > 2 && iaxdebug)
3390 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
3391 } else {
3392 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
3393 if (ms < 0)
3394 ms = 0;
3395 if (voice) {
3396 /* On a voice frame, use predicted values if appropriate */
3397 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
3398 /* Adjust our txcore, keeping voice and non-voice synchronized */
3399 /* AN EXPLANATION:
3400 When we send voice, we usually send "calculated" timestamps worked out
3401 on the basis of the number of samples sent. When we send other frames,
3402 we usually send timestamps worked out from the real clock.
3403 The problem is that they can tend to drift out of step because the
3404 source channel's clock and our clock may not be exactly at the same rate.
3405 We fix this by continuously "tweaking" p->offset. p->offset is "time zero"
3406 for this call. Moving it adjusts timestamps for non-voice frames.
3407 We make the adjustment in the style of a moving average. Each time we
3408 adjust p->offset by 10% of the difference between our clock-derived
3409 timestamp and the predicted timestamp. That's why you see "10000"
3410 below even though IAX2 timestamps are in milliseconds.
3411 The use of a moving average avoids offset moving too radically.
3412 Generally, "adjust" roams back and forth around 0, with offset hardly
3413 changing at all. But if a consistent different starts to develop it
3414 will be eliminated over the course of 10 frames (200-300msecs)
3416 adjust = (ms - p->nextpred);
3417 if (adjust < 0)
3418 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
3419 else if (adjust > 0)
3420 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
3422 if (!p->nextpred) {
3423 p->nextpred = ms; /*f->samples / 8;*/
3424 if (p->nextpred <= p->lastsent)
3425 p->nextpred = p->lastsent + 3;
3427 ms = p->nextpred;
3428 } else {
3429 /* in this case, just use the actual
3430 * time, since we're either way off
3431 * (shouldn't happen), or we're ending a
3432 * silent period -- and seed the next
3433 * predicted time. Also, round ms to the
3434 * next multiple of frame size (so our
3435 * silent periods are multiples of
3436 * frame size too) */
3438 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
3439 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
3440 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
3442 if (f->samples >= 8) /* check to make sure we dont core dump */
3444 int diff = ms % (f->samples / 8);
3445 if (diff)
3446 ms += f->samples/8 - diff;
3449 p->nextpred = ms;
3450 p->notsilenttx = 1;
3452 } else {
3453 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
3454 it's a genuine frame */
3455 if (genuine) {
3456 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
3457 if (ms <= p->lastsent)
3458 ms = p->lastsent + 3;
3459 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
3460 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
3461 ms = p->lastsent + 3;
3465 p->lastsent = ms;
3466 if (voice)
3467 p->nextpred = p->nextpred + f->samples / 8;
3468 return ms;
3471 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
3473 /* Returns where in "receive time" we are. That is, how many ms
3474 since we received (or would have received) the frame with timestamp 0 */
3475 int ms;
3476 #ifdef IAXTESTS
3477 int jit;
3478 #endif /* IAXTESTS */
3479 /* Setup rxcore if necessary */
3480 if (ast_tvzero(p->rxcore)) {
3481 p->rxcore = ast_tvnow();
3482 if (option_debug && iaxdebug)
3483 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
3484 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
3485 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
3486 #if 1
3487 if (option_debug && iaxdebug)
3488 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
3489 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
3490 #endif
3493 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
3494 #ifdef IAXTESTS
3495 if (test_jit) {
3496 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
3497 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
3498 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
3499 jit = -jit;
3500 ms += jit;
3503 if (test_late) {
3504 ms += test_late;
3505 test_late = 0;
3507 #endif /* IAXTESTS */
3508 return ms;
3511 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
3513 struct iax2_trunk_peer *tpeer;
3515 /* Finds and locks trunk peer */
3516 ast_mutex_lock(&tpeerlock);
3517 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
3518 /* We don't lock here because tpeer->addr *never* changes */
3519 if (!inaddrcmp(&tpeer->addr, sin)) {
3520 ast_mutex_lock(&tpeer->lock);
3521 break;
3524 if (!tpeer) {
3525 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
3526 ast_mutex_init(&tpeer->lock);
3527 tpeer->lastsent = 9999;
3528 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
3529 tpeer->trunkact = ast_tvnow();
3530 ast_mutex_lock(&tpeer->lock);
3531 tpeer->next = tpeers;
3532 tpeer->sockfd = fd;
3533 tpeers = tpeer;
3534 #ifdef SO_NO_CHECK
3535 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
3536 #endif
3537 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
3540 ast_mutex_unlock(&tpeerlock);
3541 return tpeer;
3544 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
3546 struct ast_frame *f;
3547 struct iax2_trunk_peer *tpeer;
3548 void *tmp, *ptr;
3549 struct ast_iax2_meta_trunk_entry *met;
3550 struct ast_iax2_meta_trunk_mini *mtm;
3552 f = &fr->af;
3553 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
3554 if (tpeer) {
3555 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
3556 /* Need to reallocate space */
3557 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
3558 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
3559 ast_mutex_unlock(&tpeer->lock);
3560 return -1;
3563 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
3564 tpeer->trunkdata = tmp;
3565 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
3566 } else {
3567 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
3568 ast_mutex_unlock(&tpeer->lock);
3569 return -1;
3573 /* Append to meta frame */
3574 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
3575 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
3576 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
3577 mtm->len = htons(f->datalen);
3578 mtm->mini.callno = htons(pvt->callno);
3579 mtm->mini.ts = htons(0xffff & fr->ts);
3580 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
3581 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
3582 } else {
3583 met = (struct ast_iax2_meta_trunk_entry *)ptr;
3584 /* Store call number and length in meta header */
3585 met->callno = htons(pvt->callno);
3586 met->len = htons(f->datalen);
3587 /* Advance pointers/decrease length past trunk entry header */
3588 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
3589 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
3591 /* Copy actual trunk data */
3592 memcpy(ptr, f->data, f->datalen);
3593 tpeer->trunkdatalen += f->datalen;
3595 tpeer->calls++;
3596 ast_mutex_unlock(&tpeer->lock);
3598 return 0;
3601 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
3603 aes_encrypt_key128(digest, ecx);
3604 aes_decrypt_key128(digest, dcx);
3607 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
3609 #if 0
3610 /* Debug with "fake encryption" */
3611 int x;
3612 if (len % 16)
3613 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
3614 for (x=0;x<len;x++)
3615 dst[x] = src[x] ^ 0xff;
3616 #else
3617 unsigned char lastblock[16] = { 0 };
3618 int x;
3619 while(len > 0) {
3620 aes_decrypt(src, dst, dcx);
3621 for (x=0;x<16;x++)
3622 dst[x] ^= lastblock[x];
3623 memcpy(lastblock, src, sizeof(lastblock));
3624 dst += 16;
3625 src += 16;
3626 len -= 16;
3628 #endif
3631 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
3633 #if 0
3634 /* Debug with "fake encryption" */
3635 int x;
3636 if (len % 16)
3637 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
3638 for (x=0;x<len;x++)
3639 dst[x] = src[x] ^ 0xff;
3640 #else
3641 unsigned char curblock[16] = { 0 };
3642 int x;
3643 while(len > 0) {
3644 for (x=0;x<16;x++)
3645 curblock[x] ^= src[x];
3646 aes_encrypt(curblock, dst, ecx);
3647 memcpy(curblock, dst, sizeof(curblock));
3648 dst += 16;
3649 src += 16;
3650 len -= 16;
3652 #endif
3655 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
3657 int padding;
3658 unsigned char *workspace;
3659 workspace = alloca(*datalen);
3660 if (!workspace)
3661 return -1;
3662 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
3663 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
3664 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
3665 return -1;
3666 /* Decrypt */
3667 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
3669 padding = 16 + (workspace[15] & 0xf);
3670 if (option_debug && iaxdebug)
3671 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
3672 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
3673 return -1;
3675 *datalen -= padding;
3676 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
3677 f->frametype = fh->type;
3678 if (f->frametype == AST_FRAME_VIDEO) {
3679 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
3680 } else {
3681 f->subclass = uncompress_subclass(fh->csub);
3683 } else {
3684 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
3685 if (option_debug && iaxdebug)
3686 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
3687 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
3688 return -1;
3689 /* Decrypt */
3690 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
3691 padding = 16 + (workspace[15] & 0x0f);
3692 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
3693 return -1;
3694 *datalen -= padding;
3695 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
3697 return 0;
3700 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
3702 int padding;
3703 unsigned char *workspace;
3704 workspace = alloca(*datalen + 32);
3705 if (!workspace)
3706 return -1;
3707 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
3708 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
3709 if (option_debug && iaxdebug)
3710 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
3711 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
3712 padding = 16 + (padding & 0xf);
3713 memcpy(workspace, poo, padding);
3714 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
3715 workspace[15] &= 0xf0;
3716 workspace[15] |= (padding & 0xf);
3717 if (option_debug && iaxdebug)
3718 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
3719 *datalen += padding;
3720 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
3721 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
3722 memcpy(poo, workspace + *datalen - 32, 32);
3723 } else {
3724 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
3725 if (option_debug && iaxdebug)
3726 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
3727 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
3728 padding = 16 + (padding & 0xf);
3729 memcpy(workspace, poo, padding);
3730 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
3731 workspace[15] &= 0xf0;
3732 workspace[15] |= (padding & 0x0f);
3733 *datalen += padding;
3734 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
3735 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
3736 memcpy(poo, workspace + *datalen - 32, 32);
3738 return 0;
3741 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
3743 int res=-1;
3744 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
3745 /* Search for possible keys, given secrets */
3746 struct MD5Context md5;
3747 unsigned char digest[16];
3748 char *tmppw, *stringp;
3750 tmppw = ast_strdupa(iaxs[callno]->secret);
3751 stringp = tmppw;
3752 while ((tmppw = strsep(&stringp, ";"))) {
3753 MD5Init(&md5);
3754 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
3755 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
3756 MD5Final(digest, &md5);
3757 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
3758 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
3759 if (!res) {
3760 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
3761 break;
3764 } else
3765 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
3766 return res;
3769 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
3771 /* Queue a packet for delivery on a given private structure. Use "ts" for
3772 timestamp, or calculate if ts is 0. Send immediately without retransmission
3773 or delayed, with retransmission */
3774 struct ast_iax2_full_hdr *fh;
3775 struct ast_iax2_mini_hdr *mh;
3776 struct ast_iax2_video_hdr *vh;
3777 struct {
3778 struct iax_frame fr2;
3779 unsigned char buffer[4096];
3780 } frb;
3781 struct iax_frame *fr;
3782 int res;
3783 int sendmini=0;
3784 unsigned int lastsent;
3785 unsigned int fts;
3787 if (!pvt) {
3788 ast_log(LOG_WARNING, "No private structure for packet?\n");
3789 return -1;
3792 lastsent = pvt->lastsent;
3794 /* Calculate actual timestamp */
3795 fts = calc_timestamp(pvt, ts, f);
3797 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
3798 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we
3799 * increment the "predicted timestamps" for voice, if we're predecting */
3800 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
3801 return 0;
3804 if ((ast_test_flag(pvt, IAX_TRUNK) ||
3805 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
3806 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
3807 /* High two bytes are the same on timestamp, or sending on a trunk */ &&
3808 (f->frametype == AST_FRAME_VOICE)
3809 /* is a voice frame */ &&
3810 (f->subclass == pvt->svoiceformat)
3811 /* is the same type */ ) {
3812 /* Force immediate rather than delayed transmission */
3813 now = 1;
3814 /* Mark that mini-style frame is appropriate */
3815 sendmini = 1;
3817 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) &&
3818 (f->frametype == AST_FRAME_VIDEO) &&
3819 ((f->subclass & ~0x1) == pvt->svideoformat)) {
3820 now = 1;
3821 sendmini = 1;
3823 /* Allocate an iax_frame */
3824 if (now) {
3825 fr = &frb.fr2;
3826 } else
3827 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen);
3828 if (!fr) {
3829 ast_log(LOG_WARNING, "Out of memory\n");
3830 return -1;
3832 /* Copy our prospective frame into our immediate or retransmitted wrapper */
3833 iax_frame_wrap(fr, f);
3835 fr->ts = fts;
3836 fr->callno = pvt->callno;
3837 fr->transfer = transfer;
3838 fr->final = final;
3839 if (!sendmini) {
3840 /* We need a full frame */
3841 if (seqno > -1)
3842 fr->oseqno = seqno;
3843 else
3844 fr->oseqno = pvt->oseqno++;
3845 fr->iseqno = pvt->iseqno;
3846 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
3847 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
3848 fh->ts = htonl(fr->ts);
3849 fh->oseqno = fr->oseqno;
3850 if (transfer) {
3851 fh->iseqno = 0;
3852 } else
3853 fh->iseqno = fr->iseqno;
3854 /* Keep track of the last thing we've acknowledged */
3855 if (!transfer)
3856 pvt->aseqno = fr->iseqno;
3857 fh->type = fr->af.frametype & 0xFF;
3858 if (fr->af.frametype == AST_FRAME_VIDEO)
3859 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
3860 else
3861 fh->csub = compress_subclass(fr->af.subclass);
3862 if (transfer) {
3863 fr->dcallno = pvt->transfercallno;
3864 } else
3865 fr->dcallno = pvt->peercallno;
3866 fh->dcallno = htons(fr->dcallno);
3867 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
3868 fr->data = fh;
3869 fr->retries = 0;
3870 /* Retry after 2x the ping time has passed */
3871 fr->retrytime = pvt->pingtime * 2;
3872 if (fr->retrytime < MIN_RETRY_TIME)
3873 fr->retrytime = MIN_RETRY_TIME;
3874 if (fr->retrytime > MAX_RETRY_TIME)
3875 fr->retrytime = MAX_RETRY_TIME;
3876 /* Acks' don't get retried */
3877 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
3878 fr->retries = -1;
3879 else if (f->frametype == AST_FRAME_VOICE)
3880 pvt->svoiceformat = f->subclass;
3881 else if (f->frametype == AST_FRAME_VIDEO)
3882 pvt->svideoformat = f->subclass & ~0x1;
3883 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
3884 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
3885 if (iaxdebug) {
3886 if (fr->transfer)
3887 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
3888 else
3889 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
3891 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
3892 } else
3893 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
3896 if (now) {
3897 res = send_packet(fr);
3898 } else
3899 res = iax2_transmit(fr);
3900 } else {
3901 if (ast_test_flag(pvt, IAX_TRUNK)) {
3902 iax2_trunk_queue(pvt, fr);
3903 res = 0;
3904 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
3905 /* Video frame have no sequence number */
3906 fr->oseqno = -1;
3907 fr->iseqno = -1;
3908 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
3909 vh->zeros = 0;
3910 vh->callno = htons(0x8000 | fr->callno);
3911 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
3912 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
3913 fr->data = vh;
3914 fr->retries = -1;
3915 res = send_packet(fr);
3916 } else {
3917 /* Mini-frames have no sequence number */
3918 fr->oseqno = -1;
3919 fr->iseqno = -1;
3920 /* Mini frame will do */
3921 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
3922 mh->callno = htons(fr->callno);
3923 mh->ts = htons(fr->ts & 0xFFFF);
3924 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
3925 fr->data = mh;
3926 fr->retries = -1;
3927 if (pvt->transferring == TRANSFER_MEDIAPASS)
3928 fr->transfer = 1;
3929 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
3930 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
3931 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
3932 } else
3933 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
3935 res = send_packet(fr);
3938 return res;
3941 static int iax2_show_users(int fd, int argc, char *argv[])
3943 regex_t regexbuf;
3944 int havepattern = 0;
3946 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
3947 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
3949 struct iax2_user *user = NULL;
3950 char auth[90];
3951 char *pstr = "";
3953 switch (argc) {
3954 case 5:
3955 if (!strcasecmp(argv[3], "like")) {
3956 if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
3957 return RESULT_SHOWUSAGE;
3958 havepattern = 1;
3959 } else
3960 return RESULT_SHOWUSAGE;
3961 case 3:
3962 break;
3963 default:
3964 return RESULT_SHOWUSAGE;
3967 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
3968 AST_LIST_LOCK(&users);
3969 AST_LIST_TRAVERSE(&users, user, entry) {
3970 if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
3971 continue;
3973 if (!ast_strlen_zero(user->secret)) {
3974 ast_copy_string(auth,user->secret,sizeof(auth));
3975 } else if (!ast_strlen_zero(user->inkeys)) {
3976 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
3977 } else
3978 ast_copy_string(auth, "-no secret-", sizeof(auth));
3980 if(ast_test_flag(user,IAX_CODEC_NOCAP))
3981 pstr = "REQ Only";
3982 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
3983 pstr = "Disabled";
3984 else
3985 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
3987 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
3988 user->contexts ? user->contexts->context : context,
3989 user->ha ? "Yes" : "No", pstr);
3992 AST_LIST_UNLOCK(&users);
3994 if (havepattern)
3995 regfree(&regexbuf);
3997 return RESULT_SUCCESS;
3998 #undef FORMAT
3999 #undef FORMAT2
4002 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
4004 regex_t regexbuf;
4005 int havepattern = 0;
4006 int total_peers = 0;
4007 int online_peers = 0;
4008 int offline_peers = 0;
4009 int unmonitored_peers = 0;
4011 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
4012 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
4014 struct iax2_peer *peer = NULL;
4015 char name[256];
4016 int registeredonly=0;
4017 char *term = manager ? "\r\n" : "\n";
4019 switch (argc) {
4020 case 6:
4021 if (!strcasecmp(argv[3], "registered"))
4022 registeredonly = 1;
4023 else
4024 return RESULT_SHOWUSAGE;
4025 if (!strcasecmp(argv[4], "like")) {
4026 if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
4027 return RESULT_SHOWUSAGE;
4028 havepattern = 1;
4029 } else
4030 return RESULT_SHOWUSAGE;
4031 break;
4032 case 5:
4033 if (!strcasecmp(argv[3], "like")) {
4034 if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
4035 return RESULT_SHOWUSAGE;
4036 havepattern = 1;
4037 } else
4038 return RESULT_SHOWUSAGE;
4039 break;
4040 case 4:
4041 if (!strcasecmp(argv[3], "registered"))
4042 registeredonly = 1;
4043 else
4044 return RESULT_SHOWUSAGE;
4045 break;
4046 case 3:
4047 break;
4048 default:
4049 return RESULT_SHOWUSAGE;
4053 if (s)
4054 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
4055 else
4056 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
4058 AST_LIST_LOCK(&peers);
4059 AST_LIST_TRAVERSE(&peers, peer, entry) {
4060 char nm[20];
4061 char status[20];
4062 char srch[2000];
4063 int retstatus;
4065 if (registeredonly && !peer->addr.sin_addr.s_addr)
4066 continue;
4067 if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
4068 continue;
4070 if (!ast_strlen_zero(peer->username))
4071 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
4072 else
4073 ast_copy_string(name, peer->name, sizeof(name));
4075 retstatus = peer_status(peer, status, sizeof(status));
4076 if (retstatus > 0)
4077 online_peers++;
4078 else if (!retstatus)
4079 offline_peers++;
4080 else
4081 unmonitored_peers++;
4083 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
4085 snprintf(srch, sizeof(srch), FORMAT, name,
4086 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
4087 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
4089 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
4090 peer->encmethods ? "(E)" : " ", status, term);
4092 if (s)
4093 astman_append(s, FORMAT, name,
4094 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
4095 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
4097 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
4098 peer->encmethods ? "(E)" : " ", status, term);
4099 else
4100 ast_cli(fd, FORMAT, name,
4101 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
4102 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
4104 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
4105 peer->encmethods ? "(E)" : " ", status, term);
4106 total_peers++;
4108 AST_LIST_UNLOCK(&peers);
4110 if (s)
4111 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
4112 else
4113 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
4115 if (havepattern)
4116 regfree(&regexbuf);
4118 return RESULT_SUCCESS;
4119 #undef FORMAT
4120 #undef FORMAT2
4123 static int iax2_show_threads(int fd, int argc, char *argv[])
4125 struct iax2_thread *thread = NULL;
4126 time_t t;
4127 int threadcount = 0, dynamiccount = 0;
4128 char type;
4130 if (argc != 3)
4131 return RESULT_SHOWUSAGE;
4133 ast_cli(fd, "IAX2 Thread Information\n");
4134 time(&t);
4135 ast_cli(fd, "Idle Threads:\n");
4136 AST_LIST_LOCK(&idle_list);
4137 AST_LIST_TRAVERSE(&idle_list, thread, list) {
4138 #ifdef DEBUG_SCHED_MULTITHREAD
4139 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4140 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
4141 #else
4142 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
4143 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
4144 #endif
4145 threadcount++;
4147 AST_LIST_UNLOCK(&idle_list);
4148 ast_cli(fd, "Active Threads:\n");
4149 AST_LIST_LOCK(&active_list);
4150 AST_LIST_TRAVERSE(&active_list, thread, list) {
4151 if (thread->type == IAX_TYPE_DYNAMIC)
4152 type = 'D';
4153 else
4154 type = 'P';
4155 #ifdef DEBUG_SCHED_MULTITHREAD
4156 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
4157 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
4158 #else
4159 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
4160 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
4161 #endif
4162 threadcount++;
4164 AST_LIST_UNLOCK(&active_list);
4165 ast_cli(fd, "Dynamic Threads:\n");
4166 AST_LIST_LOCK(&dynamic_list);
4167 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
4168 #ifdef DEBUG_SCHED_MULTITHREAD
4169 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
4170 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
4171 #else
4172 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
4173 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
4174 #endif
4175 dynamiccount++;
4177 AST_LIST_UNLOCK(&dynamic_list);
4178 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
4179 return RESULT_SUCCESS;
4182 static int iax2_show_peers(int fd, int argc, char *argv[])
4184 return __iax2_show_peers(0, fd, NULL, argc, argv);
4186 static int manager_iax2_show_netstats( struct mansession *s, struct message *m )
4188 ast_cli_netstats(s, -1, 0);
4189 astman_append(s, "\r\n");
4190 return RESULT_SUCCESS;
4193 static int iax2_show_firmware(int fd, int argc, char *argv[])
4195 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
4196 #if !defined(__FreeBSD__)
4197 #define FORMAT "%-15.15s %-15d %-15d\n"
4198 #else /* __FreeBSD__ */
4199 #define FORMAT "%-15.15s %-15d %-15d\n" /* XXX 2.95 ? */
4200 #endif /* __FreeBSD__ */
4201 struct iax_firmware *cur;
4202 if ((argc != 3) && (argc != 4))
4203 return RESULT_SHOWUSAGE;
4204 ast_mutex_lock(&waresl.lock);
4206 ast_cli(fd, FORMAT2, "Device", "Version", "Size");
4207 for (cur = waresl.wares;cur;cur = cur->next) {
4208 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
4209 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
4210 (int)ntohl(cur->fwh->datalen));
4212 ast_mutex_unlock(&waresl.lock);
4213 return RESULT_SUCCESS;
4214 #undef FORMAT
4215 #undef FORMAT2
4218 /* JDG: callback to display iax peers in manager */
4219 static int manager_iax2_show_peers( struct mansession *s, struct message *m )
4221 char *a[] = { "iax2", "show", "users" };
4222 int ret;
4223 char *id;
4224 id = astman_get_header(m,"ActionID");
4225 if (!ast_strlen_zero(id))
4226 astman_append(s, "ActionID: %s\r\n",id);
4227 ret = __iax2_show_peers(1, -1, s, 3, a );
4228 astman_append(s, "\r\n\r\n" );
4229 return ret;
4230 } /* /JDG */
4232 static char *regstate2str(int regstate)
4234 switch(regstate) {
4235 case REG_STATE_UNREGISTERED:
4236 return "Unregistered";
4237 case REG_STATE_REGSENT:
4238 return "Request Sent";
4239 case REG_STATE_AUTHSENT:
4240 return "Auth. Sent";
4241 case REG_STATE_REGISTERED:
4242 return "Registered";
4243 case REG_STATE_REJECTED:
4244 return "Rejected";
4245 case REG_STATE_TIMEOUT:
4246 return "Timeout";
4247 case REG_STATE_NOAUTH:
4248 return "No Authentication";
4249 default:
4250 return "Unknown";
4254 static int iax2_show_registry(int fd, int argc, char *argv[])
4256 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
4257 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
4258 struct iax2_registry *reg = NULL;
4260 char host[80];
4261 char perceived[80];
4262 if (argc != 3)
4263 return RESULT_SHOWUSAGE;
4264 AST_LIST_LOCK(&peers);
4265 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
4266 for (reg = registrations;reg;reg = reg->next) {
4267 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
4268 if (reg->us.sin_addr.s_addr)
4269 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
4270 else
4271 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
4272 ast_cli(fd, FORMAT, host,
4273 (reg->dnsmgr) ? "Y" : "N",
4274 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
4276 AST_LIST_UNLOCK(&peers);
4277 return RESULT_SUCCESS;
4278 #undef FORMAT
4279 #undef FORMAT2
4282 static int iax2_show_channels(int fd, int argc, char *argv[])
4284 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
4285 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
4286 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
4287 int x;
4288 int numchans = 0;
4290 if (argc != 3)
4291 return RESULT_SHOWUSAGE;
4292 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
4293 for (x=0;x<IAX_MAX_CALLS;x++) {
4294 ast_mutex_lock(&iaxsl[x]);
4295 if (iaxs[x]) {
4296 int lag, jitter, localdelay;
4297 jb_info jbinfo;
4299 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
4300 jb_getinfo(iaxs[x]->jb, &jbinfo);
4301 jitter = jbinfo.jitter;
4302 localdelay = jbinfo.current - jbinfo.min;
4303 } else {
4304 jitter = -1;
4305 localdelay = 0;
4307 lag = iaxs[x]->remote_rr.delay;
4308 ast_cli(fd, FORMAT,
4309 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
4310 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
4311 S_OR(iaxs[x]->username, "(None)"),
4312 iaxs[x]->callno, iaxs[x]->peercallno,
4313 iaxs[x]->oseqno, iaxs[x]->iseqno,
4314 lag,
4315 jitter,
4316 localdelay,
4317 ast_getformatname(iaxs[x]->voiceformat) );
4318 numchans++;
4320 ast_mutex_unlock(&iaxsl[x]);
4322 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
4323 return RESULT_SUCCESS;
4324 #undef FORMAT
4325 #undef FORMAT2
4326 #undef FORMATB
4329 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
4331 int x;
4332 int numchans = 0;
4333 for (x=0;x<IAX_MAX_CALLS;x++) {
4334 ast_mutex_lock(&iaxsl[x]);
4335 if (iaxs[x]) {
4336 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
4337 char *fmt;
4338 jb_info jbinfo;
4340 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
4341 jb_getinfo(iaxs[x]->jb, &jbinfo);
4342 localjitter = jbinfo.jitter;
4343 localdelay = jbinfo.current - jbinfo.min;
4344 locallost = jbinfo.frames_lost;
4345 locallosspct = jbinfo.losspct/1000;
4346 localdropped = jbinfo.frames_dropped;
4347 localooo = jbinfo.frames_ooo;
4348 } else {
4349 localjitter = -1;
4350 localdelay = 0;
4351 locallost = -1;
4352 locallosspct = -1;
4353 localdropped = 0;
4354 localooo = -1;
4356 if (limit_fmt)
4357 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
4358 else
4359 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
4360 if (s)
4362 astman_append(s, fmt,
4363 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
4364 iaxs[x]->pingtime,
4365 localjitter,
4366 localdelay,
4367 locallost,
4368 locallosspct,
4369 localdropped,
4370 localooo,
4371 iaxs[x]->frames_received/1000,
4372 iaxs[x]->remote_rr.jitter,
4373 iaxs[x]->remote_rr.delay,
4374 iaxs[x]->remote_rr.losscnt,
4375 iaxs[x]->remote_rr.losspct,
4376 iaxs[x]->remote_rr.dropped,
4377 iaxs[x]->remote_rr.ooo,
4378 iaxs[x]->remote_rr.packets/1000);
4379 else
4380 ast_cli(fd, fmt,
4381 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
4382 iaxs[x]->pingtime,
4383 localjitter,
4384 localdelay,
4385 locallost,
4386 locallosspct,
4387 localdropped,
4388 localooo,
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
4398 numchans++;
4400 ast_mutex_unlock(&iaxsl[x]);
4402 return numchans;
4405 static int iax2_show_netstats(int fd, int argc, char *argv[])
4407 int numchans = 0;
4408 if (argc != 3)
4409 return RESULT_SHOWUSAGE;
4410 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
4411 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
4412 numchans = ast_cli_netstats(NULL, fd, 1);
4413 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
4414 return RESULT_SUCCESS;
4417 static int iax2_do_debug(int fd, int argc, char *argv[])
4419 if (argc != 2)
4420 return RESULT_SHOWUSAGE;
4421 iaxdebug = 1;
4422 ast_cli(fd, "IAX2 Debugging Enabled\n");
4423 return RESULT_SUCCESS;
4426 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
4428 if (argc != 3)
4429 return RESULT_SHOWUSAGE;
4430 iaxtrunkdebug = 1;
4431 ast_cli(fd, "IAX2 Trunk Debug Requested\n");
4432 return RESULT_SUCCESS;
4435 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
4437 if (argc != 3)
4438 return RESULT_SHOWUSAGE;
4439 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
4440 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
4441 return RESULT_SUCCESS;
4444 static int iax2_no_debug_deprecated(int fd, int argc, char *argv[])
4446 if (argc != 3)
4447 return RESULT_SHOWUSAGE;
4448 iaxdebug = 0;
4449 ast_cli(fd, "IAX2 Debugging Disabled\n");
4450 return RESULT_SUCCESS;
4453 static int iax2_no_debug(int fd, int argc, char *argv[])
4455 if (argc != 2)
4456 return RESULT_SHOWUSAGE;
4457 iaxdebug = 0;
4458 ast_cli(fd, "IAX2 Debugging Disabled\n");
4459 return RESULT_SUCCESS;
4462 static int iax2_no_trunk_debug_deprecated(int fd, int argc, char *argv[])
4464 if (argc != 4)
4465 return RESULT_SHOWUSAGE;
4466 iaxtrunkdebug = 0;
4467 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
4468 return RESULT_SUCCESS;
4471 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
4473 if (argc != 3)
4474 return RESULT_SHOWUSAGE;
4475 iaxtrunkdebug = 0;
4476 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
4477 return RESULT_SUCCESS;
4480 static int iax2_no_jb_debug_deprecated(int fd, int argc, char *argv[])
4482 if (argc != 4)
4483 return RESULT_SHOWUSAGE;
4484 jb_setoutput(jb_error_output, jb_warning_output, NULL);
4485 jb_debug_output("\n");
4486 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
4487 return RESULT_SUCCESS;
4490 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
4492 if (argc != 3)
4493 return RESULT_SHOWUSAGE;
4494 jb_setoutput(jb_error_output, jb_warning_output, NULL);
4495 jb_debug_output("\n");
4496 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
4497 return RESULT_SUCCESS;
4500 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
4502 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
4503 int res = -1;
4504 ast_mutex_lock(&iaxsl[callno]);
4505 if (iaxs[callno]) {
4506 /* If there's an outstanding error, return failure now */
4507 if (!iaxs[callno]->error) {
4508 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
4509 res = 0;
4510 /* Don't waste bandwidth sending null frames */
4511 else if (f->frametype == AST_FRAME_NULL)
4512 res = 0;
4513 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
4514 res = 0;
4515 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
4516 res = 0;
4517 else
4518 /* Simple, just queue for transmission */
4519 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
4520 } else {
4521 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
4524 /* If it's already gone, just return */
4525 ast_mutex_unlock(&iaxsl[callno]);
4526 return res;
4529 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
4530 int now, int transfer, int final)
4532 struct ast_frame f;
4533 f.frametype = type;
4534 f.subclass = command;
4535 f.datalen = datalen;
4536 f.samples = 0;
4537 f.mallocd = 0;
4538 f.offset = 0;
4539 f.src = (char *)__FUNCTION__;
4540 f.data = (char *)data;
4541 return iax2_send(i, &f, ts, seqno, now, transfer, final);
4544 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
4546 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
4549 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
4551 int res;
4552 ast_mutex_lock(&iaxsl[callno]);
4553 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
4554 ast_mutex_unlock(&iaxsl[callno]);
4555 return res;
4558 static int send_command_final(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
4560 /* It is assumed that the callno has already been locked */
4561 iax2_predestroy_nolock(i->callno);
4562 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
4565 static int send_command_immediate(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
4567 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
4570 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
4572 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
4575 static int apply_context(struct iax2_context *con, const char *context)
4577 while(con) {
4578 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
4579 return -1;
4580 con = con->next;
4582 return 0;
4586 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
4588 /* Start pessimistic */
4589 int res = -1;
4590 int version = 2;
4591 struct iax2_user *user = NULL, *best = NULL;
4592 int bestscore = 0;
4593 int gotcapability = 0;
4594 struct ast_variable *v = NULL, *tmpvar = NULL;
4596 if (!iaxs[callno])
4597 return res;
4598 if (ies->called_number)
4599 ast_string_field_set(iaxs[callno], exten, ies->called_number);
4600 if (ies->calling_number) {
4601 ast_shrink_phone_number(ies->calling_number);
4602 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
4604 if (ies->calling_name)
4605 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
4606 if (ies->calling_ani)
4607 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
4608 if (ies->dnid)
4609 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
4610 if (ies->rdnis)
4611 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
4612 if (ies->called_context)
4613 ast_string_field_set(iaxs[callno], context, ies->called_context);
4614 if (ies->language)
4615 ast_string_field_set(iaxs[callno], language, ies->language);
4616 if (ies->username)
4617 ast_string_field_set(iaxs[callno], username, ies->username);
4618 if (ies->calling_ton > -1)
4619 iaxs[callno]->calling_ton = ies->calling_ton;
4620 if (ies->calling_tns > -1)
4621 iaxs[callno]->calling_tns = ies->calling_tns;
4622 if (ies->calling_pres > -1)
4623 iaxs[callno]->calling_pres = ies->calling_pres;
4624 if (ies->format)
4625 iaxs[callno]->peerformat = ies->format;
4626 if (ies->adsicpe)
4627 iaxs[callno]->peeradsicpe = ies->adsicpe;
4628 if (ies->capability) {
4629 gotcapability = 1;
4630 iaxs[callno]->peercapability = ies->capability;
4632 if (ies->version)
4633 version = ies->version;
4635 /* Use provided preferences until told otherwise for actual preferences */
4636 if(ies->codec_prefs) {
4637 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
4638 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
4641 if (!gotcapability)
4642 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
4643 if (version > IAX_PROTO_VERSION) {
4644 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
4645 ast_inet_ntoa(sin->sin_addr), version);
4646 return res;
4648 /* Search the userlist for a compatible entry, and fill in the rest */
4649 AST_LIST_LOCK(&users);
4650 AST_LIST_TRAVERSE(&users, user, entry) {
4651 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */
4652 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
4653 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */
4654 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */
4655 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */
4656 if (!ast_strlen_zero(iaxs[callno]->username)) {
4657 /* Exact match, stop right now. */
4658 best = user;
4659 break;
4660 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
4661 /* No required authentication */
4662 if (user->ha) {
4663 /* There was host authentication and we passed, bonus! */
4664 if (bestscore < 4) {
4665 bestscore = 4;
4666 best = user;
4668 } else {
4669 /* No host access, but no secret, either, not bad */
4670 if (bestscore < 3) {
4671 bestscore = 3;
4672 best = user;
4675 } else {
4676 if (user->ha) {
4677 /* Authentication, but host access too, eh, it's something.. */
4678 if (bestscore < 2) {
4679 bestscore = 2;
4680 best = user;
4682 } else {
4683 /* Authentication and no host access... This is our baseline */
4684 if (bestscore < 1) {
4685 bestscore = 1;
4686 best = user;
4692 AST_LIST_UNLOCK(&users);
4693 user = best;
4694 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
4695 user = realtime_user(iaxs[callno]->username);
4696 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */
4697 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */
4698 destroy_user(user);
4699 user = NULL;
4702 if (user) {
4703 /* We found our match (use the first) */
4704 /* copy vars */
4705 for (v = user->vars ; v ; v = v->next) {
4706 if((tmpvar = ast_variable_new(v->name, v->value))) {
4707 tmpvar->next = iaxs[callno]->vars;
4708 iaxs[callno]->vars = tmpvar;
4711 /* If a max AUTHREQ restriction is in place, activate it */
4712 if (user->maxauthreq > 0)
4713 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
4714 iaxs[callno]->prefs = user->prefs;
4715 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
4716 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
4717 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
4718 iaxs[callno]->encmethods = user->encmethods;
4719 /* Store the requested username if not specified */
4720 if (ast_strlen_zero(iaxs[callno]->username))
4721 ast_string_field_set(iaxs[callno], username, user->name);
4722 /* Store whether this is a trunked call, too, of course, and move if appropriate */
4723 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
4724 iaxs[callno]->capability = user->capability;
4725 /* And use the default context */
4726 if (ast_strlen_zero(iaxs[callno]->context)) {
4727 if (user->contexts)
4728 ast_string_field_set(iaxs[callno], context, user->contexts->context);
4729 else
4730 ast_string_field_set(iaxs[callno], context, context);
4732 /* And any input keys */
4733 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
4734 /* And the permitted authentication methods */
4735 iaxs[callno]->authmethods = user->authmethods;
4736 iaxs[callno]->adsi = user->adsi;
4737 /* If they have callerid, override the given caller id. Always store the ANI */
4738 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
4739 if (ast_test_flag(user, IAX_HASCALLERID)) {
4740 iaxs[callno]->calling_tns = 0;
4741 iaxs[callno]->calling_ton = 0;
4742 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
4743 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
4744 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
4746 if (ast_strlen_zero(iaxs[callno]->ani))
4747 ast_string_field_set(iaxs[callno], ani, user->cid_num);
4748 } else {
4749 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
4751 if (!ast_strlen_zero(user->accountcode))
4752 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
4753 if (!ast_strlen_zero(user->mohinterpret))
4754 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
4755 if (!ast_strlen_zero(user->mohsuggest))
4756 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
4757 if (user->amaflags)
4758 iaxs[callno]->amaflags = user->amaflags;
4759 if (!ast_strlen_zero(user->language))
4760 ast_string_field_set(iaxs[callno], language, user->language);
4761 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
4762 /* Keep this check last */
4763 if (!ast_strlen_zero(user->dbsecret)) {
4764 char *family, *key=NULL;
4765 char buf[80];
4766 family = ast_strdupa(user->dbsecret);
4767 key = strchr(family, '/');
4768 if (key) {
4769 *key = '\0';
4770 key++;
4772 if (!key || ast_db_get(family, key, buf, sizeof(buf))) {
4773 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
4774 if (ast_test_flag(user, IAX_TEMPONLY)) {
4775 destroy_user(user);
4776 user = NULL;
4778 } else
4779 ast_string_field_set(iaxs[callno], secret, buf);
4780 } else
4781 ast_string_field_set(iaxs[callno], secret, user->secret);
4782 res = 0;
4784 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
4785 return res;
4788 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
4790 struct ast_iax2_full_hdr fh;
4791 fh.scallno = htons(src | IAX_FLAG_FULL);
4792 fh.dcallno = htons(dst);
4793 fh.ts = 0;
4794 fh.oseqno = 0;
4795 fh.iseqno = 0;
4796 fh.type = AST_FRAME_IAX;
4797 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
4798 if (iaxdebug)
4799 iax_showframe(NULL, &fh, 0, sin, 0);
4800 #if 0
4801 if (option_debug)
4802 #endif
4803 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
4804 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
4805 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
4808 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
4810 /* Select exactly one common encryption if there are any */
4811 p->encmethods &= enc;
4812 if (p->encmethods) {
4813 if (p->encmethods & IAX_ENCRYPT_AES128)
4814 p->encmethods = IAX_ENCRYPT_AES128;
4815 else
4816 p->encmethods = 0;
4820 static int authenticate_request(struct chan_iax2_pvt *p)
4822 struct iax2_user *user = NULL;
4823 struct iax_ie_data ied;
4824 int res = -1, authreq_restrict = 0;
4825 char challenge[10];
4827 memset(&ied, 0, sizeof(ied));
4829 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
4830 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
4831 AST_LIST_LOCK(&users);
4832 AST_LIST_TRAVERSE(&users, user, entry) {
4833 if (!strcmp(user->name, p->username)) {
4834 if (user->curauthreq == user->maxauthreq)
4835 authreq_restrict = 1;
4836 else
4837 user->curauthreq++;
4838 break;
4841 AST_LIST_UNLOCK(&users);
4844 /* If the AUTHREQ limit test failed, send back an error */
4845 if (authreq_restrict) {
4846 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
4847 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
4848 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
4849 return 0;
4852 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
4853 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
4854 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
4855 ast_string_field_set(p, challenge, challenge);
4856 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
4857 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
4859 if (p->encmethods)
4860 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
4862 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
4864 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
4866 if (p->encmethods)
4867 ast_set_flag(p, IAX_ENCRYPTED);
4869 return res;
4872 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
4874 char requeststr[256];
4875 char md5secret[256] = "";
4876 char secret[256] = "";
4877 char rsasecret[256] = "";
4878 int res = -1;
4879 int x;
4880 struct iax2_user *user = NULL;
4882 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
4883 AST_LIST_LOCK(&users);
4884 AST_LIST_TRAVERSE(&users, user, entry) {
4885 if (!strcmp(user->name, p->username)) {
4886 user->curauthreq--;
4887 break;
4890 AST_LIST_UNLOCK(&users);
4891 ast_clear_flag(p, IAX_MAXAUTHREQ);
4894 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
4895 return res;
4896 if (ies->password)
4897 ast_copy_string(secret, ies->password, sizeof(secret));
4898 if (ies->md5_result)
4899 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
4900 if (ies->rsa_result)
4901 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
4902 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
4903 struct ast_key *key;
4904 char *keyn;
4905 char tmpkey[256];
4906 char *stringp=NULL;
4907 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
4908 stringp=tmpkey;
4909 keyn = strsep(&stringp, ":");
4910 while(keyn) {
4911 key = ast_key_get(keyn, AST_KEY_PUBLIC);
4912 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
4913 res = 0;
4914 break;
4915 } else if (!key)
4916 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
4917 keyn = strsep(&stringp, ":");
4919 } else if (p->authmethods & IAX_AUTH_MD5) {
4920 struct MD5Context md5;
4921 unsigned char digest[16];
4922 char *tmppw, *stringp;
4924 tmppw = ast_strdupa(p->secret);
4925 stringp = tmppw;
4926 while((tmppw = strsep(&stringp, ";"))) {
4927 MD5Init(&md5);
4928 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
4929 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
4930 MD5Final(digest, &md5);
4931 /* If they support md5, authenticate with it. */
4932 for (x=0;x<16;x++)
4933 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
4934 if (!strcasecmp(requeststr, md5secret)) {
4935 res = 0;
4936 break;
4939 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
4940 if (!strcmp(secret, p->secret))
4941 res = 0;
4943 return res;
4946 /*! \brief Verify inbound registration */
4947 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
4949 char requeststr[256] = "";
4950 char peer[256] = "";
4951 char md5secret[256] = "";
4952 char rsasecret[256] = "";
4953 char secret[256] = "";
4954 struct iax2_peer *p;
4955 struct ast_key *key;
4956 char *keyn;
4957 int x;
4958 int expire = 0;
4960 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
4961 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
4962 if (ies->username)
4963 ast_copy_string(peer, ies->username, sizeof(peer));
4964 if (ies->password)
4965 ast_copy_string(secret, ies->password, sizeof(secret));
4966 if (ies->md5_result)
4967 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
4968 if (ies->rsa_result)
4969 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
4970 if (ies->refresh)
4971 expire = ies->refresh;
4973 if (ast_strlen_zero(peer)) {
4974 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
4975 return -1;
4977 /* We release the lock for the call to prevent a deadlock, but it's okay because
4978 only the current thread could possibly make it go away or make changes */
4979 ast_mutex_unlock(&iaxsl[callno]);
4980 /* SLD: first call to lookup peer during registration */
4981 p = find_peer(peer, 1);
4982 ast_mutex_lock(&iaxsl[callno]);
4984 if (!iaxs[callno]) {
4985 /* Call has disappeared */
4986 ast_mutex_unlock(&iaxsl[callno]);
4987 return -1;
4989 if (!p) {
4990 if (authdebug)
4991 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
4992 return -1;
4995 if (!ast_test_flag(p, IAX_DYNAMIC)) {
4996 if (authdebug)
4997 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
4998 if (ast_test_flag(p, IAX_TEMPONLY))
4999 destroy_peer(p);
5000 return -1;
5003 if (!ast_apply_ha(p->ha, sin)) {
5004 if (authdebug)
5005 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
5006 if (ast_test_flag(p, IAX_TEMPONLY))
5007 destroy_peer(p);
5008 return -1;
5010 if (!inaddrcmp(&p->addr, sin))
5011 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
5012 ast_string_field_set(iaxs[callno], secret, p->secret);
5013 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
5014 /* Check secret against what we have on file */
5015 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
5016 if (!ast_strlen_zero(p->inkeys)) {
5017 char tmpkeys[256];
5018 char *stringp=NULL;
5019 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
5020 stringp=tmpkeys;
5021 keyn = strsep(&stringp, ":");
5022 while(keyn) {
5023 key = ast_key_get(keyn, AST_KEY_PUBLIC);
5024 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
5025 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
5026 break;
5027 } else if (!key)
5028 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
5029 keyn = strsep(&stringp, ":");
5031 if (!keyn) {
5032 if (authdebug)
5033 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
5034 if (ast_test_flag(p, IAX_TEMPONLY))
5035 destroy_peer(p);
5036 return -1;
5038 } else {
5039 if (authdebug)
5040 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
5041 if (ast_test_flag(p, IAX_TEMPONLY))
5042 destroy_peer(p);
5043 return -1;
5045 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
5046 struct MD5Context md5;
5047 unsigned char digest[16];
5048 char *tmppw, *stringp;
5050 tmppw = ast_strdupa(p->secret);
5051 stringp = tmppw;
5052 while((tmppw = strsep(&stringp, ";"))) {
5053 MD5Init(&md5);
5054 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
5055 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
5056 MD5Final(digest, &md5);
5057 for (x=0;x<16;x++)
5058 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
5059 if (!strcasecmp(requeststr, md5secret))
5060 break;
5062 if (tmppw) {
5063 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
5064 } else {
5065 if (authdebug)
5066 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
5067 if (ast_test_flag(p, IAX_TEMPONLY))
5068 destroy_peer(p);
5069 return -1;
5071 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
5072 /* They've provided a plain text password and we support that */
5073 if (strcmp(secret, p->secret)) {
5074 if (authdebug)
5075 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
5076 if (ast_test_flag(p, IAX_TEMPONLY))
5077 destroy_peer(p);
5078 return -1;
5079 } else
5080 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
5081 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
5082 if (authdebug)
5083 ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
5084 if (ast_test_flag(p, IAX_TEMPONLY))
5085 destroy_peer(p);
5086 return -1;
5088 ast_string_field_set(iaxs[callno], peer, peer);
5089 /* Choose lowest expiry number */
5090 if (expire && (expire < iaxs[callno]->expiry))
5091 iaxs[callno]->expiry = expire;
5093 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
5095 if (ast_test_flag(p, IAX_TEMPONLY))
5096 destroy_peer(p);
5097 return 0;
5101 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
5103 int res = -1;
5104 int x;
5105 if (!ast_strlen_zero(keyn)) {
5106 if (!(authmethods & IAX_AUTH_RSA)) {
5107 if (ast_strlen_zero(secret))
5108 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
5109 } else if (ast_strlen_zero(challenge)) {
5110 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
5111 } else {
5112 char sig[256];
5113 struct ast_key *key;
5114 key = ast_key_get(keyn, AST_KEY_PRIVATE);
5115 if (!key) {
5116 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
5117 } else {
5118 if (ast_sign(key, (char*)challenge, sig)) {
5119 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
5120 res = -1;
5121 } else {
5122 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
5123 res = 0;
5128 /* Fall back */
5129 if (res && !ast_strlen_zero(secret)) {
5130 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
5131 struct MD5Context md5;
5132 unsigned char digest[16];
5133 char digres[128];
5134 MD5Init(&md5);
5135 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
5136 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
5137 MD5Final(digest, &md5);
5138 /* If they support md5, authenticate with it. */
5139 for (x=0;x<16;x++)
5140 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */
5141 if (ecx && dcx)
5142 build_enc_keys(digest, ecx, dcx);
5143 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
5144 res = 0;
5145 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
5146 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
5147 res = 0;
5148 } else
5149 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
5151 return res;
5154 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
5156 struct iax2_peer *peer = NULL;
5157 /* Start pessimistic */
5158 int res = -1;
5159 int authmethods = 0;
5160 struct iax_ie_data ied;
5162 memset(&ied, 0, sizeof(ied));
5164 if (ies->username)
5165 ast_string_field_set(p, username, ies->username);
5166 if (ies->challenge)
5167 ast_string_field_set(p, challenge, ies->challenge);
5168 if (ies->authmethods)
5169 authmethods = ies->authmethods;
5170 if (authmethods & IAX_AUTH_MD5)
5171 merge_encryption(p, ies->encmethods);
5172 else
5173 p->encmethods = 0;
5175 /* Check for override RSA authentication first */
5176 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
5177 /* Normal password authentication */
5178 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
5179 } else {
5180 AST_LIST_LOCK(&peers);
5181 AST_LIST_TRAVERSE(&peers, peer, entry) {
5182 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
5183 /* No peer specified at our end, or this is the peer */
5184 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
5185 /* No username specified in peer rule, or this is the right username */
5186 && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr)))
5187 /* No specified host, or this is our host */
5189 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
5190 if (!res)
5191 break;
5194 AST_LIST_UNLOCK(&peers);
5195 if (!peer) {
5196 /* We checked our list and didn't find one. It's unlikely, but possible,
5197 that we're trying to authenticate *to* a realtime peer */
5198 if ((peer = realtime_peer(p->peer, NULL))) {
5199 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
5200 if (ast_test_flag(peer, IAX_TEMPONLY))
5201 destroy_peer(peer);
5205 if (ies->encmethods)
5206 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
5207 if (!res)
5208 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
5209 return res;
5212 static int iax2_do_register(struct iax2_registry *reg);
5214 static void __iax2_do_register_s(void *data)
5216 struct iax2_registry *reg = data;
5217 reg->expire = -1;
5218 iax2_do_register(reg);
5221 static int iax2_do_register_s(void *data)
5223 #ifdef SCHED_MULTITHREADED
5224 if (schedule_action(__iax2_do_register_s, data))
5225 #endif
5226 __iax2_do_register_s(data);
5227 return 0;
5230 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
5232 int newcall = 0;
5233 char newip[256];
5234 struct iax_ie_data ied;
5235 struct sockaddr_in new;
5238 memset(&ied, 0, sizeof(ied));
5239 if (ies->apparent_addr)
5240 bcopy(ies->apparent_addr, &new, sizeof(new));
5241 if (ies->callno)
5242 newcall = ies->callno;
5243 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
5244 ast_log(LOG_WARNING, "Invalid transfer request\n");
5245 return -1;
5247 pvt->transfercallno = newcall;
5248 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
5249 inet_aton(newip, &pvt->transfer.sin_addr);
5250 pvt->transfer.sin_family = AF_INET;
5251 pvt->transferring = TRANSFER_BEGIN;
5252 pvt->transferid = ies->transferid;
5253 if (ies->transferid)
5254 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
5255 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
5256 return 0;
5259 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
5261 char exten[256] = "";
5262 int status = CACHE_FLAG_UNKNOWN;
5263 int expiry = iaxdefaultdpcache;
5264 int x;
5265 int matchmore = 0;
5266 struct iax2_dpcache *dp, *prev;
5268 if (ies->called_number)
5269 ast_copy_string(exten, ies->called_number, sizeof(exten));
5271 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
5272 status = CACHE_FLAG_EXISTS;
5273 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
5274 status = CACHE_FLAG_CANEXIST;
5275 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
5276 status = CACHE_FLAG_NONEXISTENT;
5278 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
5279 /* Don't really do anything with this */
5281 if (ies->refresh)
5282 expiry = ies->refresh;
5283 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
5284 matchmore = CACHE_FLAG_MATCHMORE;
5285 ast_mutex_lock(&dpcache_lock);
5286 prev = NULL;
5287 dp = pvt->dpentries;
5288 while(dp) {
5289 if (!strcmp(dp->exten, exten)) {
5290 /* Let them go */
5291 if (prev)
5292 prev->peer = dp->peer;
5293 else
5294 pvt->dpentries = dp->peer;
5295 dp->peer = NULL;
5296 dp->callno = 0;
5297 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
5298 if (dp->flags & CACHE_FLAG_PENDING) {
5299 dp->flags &= ~CACHE_FLAG_PENDING;
5300 dp->flags |= status;
5301 dp->flags |= matchmore;
5303 /* Wake up waiters */
5304 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
5305 if (dp->waiters[x] > -1)
5306 write(dp->waiters[x], "asdf", 4);
5308 prev = dp;
5309 dp = dp->peer;
5311 ast_mutex_unlock(&dpcache_lock);
5312 return 0;
5315 static int complete_transfer(int callno, struct iax_ies *ies)
5317 int peercallno = 0;
5318 struct chan_iax2_pvt *pvt = iaxs[callno];
5319 struct iax_frame *cur;
5320 jb_frame frame;
5322 if (ies->callno)
5323 peercallno = ies->callno;
5325 if (peercallno < 1) {
5326 ast_log(LOG_WARNING, "Invalid transfer request\n");
5327 return -1;
5329 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
5330 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
5331 /* Reset sequence numbers */
5332 pvt->oseqno = 0;
5333 pvt->rseqno = 0;
5334 pvt->iseqno = 0;
5335 pvt->aseqno = 0;
5336 pvt->peercallno = peercallno;
5337 pvt->transferring = TRANSFER_NONE;
5338 pvt->svoiceformat = -1;
5339 pvt->voiceformat = 0;
5340 pvt->svideoformat = -1;
5341 pvt->videoformat = 0;
5342 pvt->transfercallno = -1;
5343 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
5344 memset(&pvt->offset, 0, sizeof(pvt->offset));
5345 /* reset jitterbuffer */
5346 while(jb_getall(pvt->jb,&frame) == JB_OK)
5347 iax2_frame_free(frame.data);
5348 jb_reset(pvt->jb);
5349 pvt->lag = 0;
5350 pvt->last = 0;
5351 pvt->lastsent = 0;
5352 pvt->nextpred = 0;
5353 pvt->pingtime = DEFAULT_RETRY_TIME;
5354 AST_LIST_LOCK(&iaxq.queue);
5355 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
5356 /* We must cancel any packets that would have been transmitted
5357 because now we're talking to someone new. It's okay, they
5358 were transmitted to someone that didn't care anyway. */
5359 if (callno == cur->callno)
5360 cur->retries = -1;
5362 AST_LIST_UNLOCK(&iaxq.queue);
5363 return 0;
5366 /*! \brief Acknowledgment received for OUR registration */
5367 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
5369 struct iax2_registry *reg;
5370 /* Start pessimistic */
5371 char peer[256] = "";
5372 char msgstatus[60];
5373 int refresh = 0;
5374 char ourip[256] = "<Unspecified>";
5375 struct sockaddr_in oldus;
5376 struct sockaddr_in us;
5377 int oldmsgs;
5379 memset(&us, 0, sizeof(us));
5380 if (ies->apparent_addr)
5381 bcopy(ies->apparent_addr, &us, sizeof(us));
5382 if (ies->username)
5383 ast_copy_string(peer, ies->username, sizeof(peer));
5384 if (ies->refresh)
5385 refresh = ies->refresh;
5386 if (ies->calling_number) {
5387 /* We don't do anything with it really, but maybe we should */
5389 reg = iaxs[callno]->reg;
5390 if (!reg) {
5391 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
5392 return -1;
5394 memcpy(&oldus, &reg->us, sizeof(oldus));
5395 oldmsgs = reg->messages;
5396 if (inaddrcmp(&reg->addr, sin)) {
5397 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
5398 return -1;
5400 memcpy(&reg->us, &us, sizeof(reg->us));
5401 if (ies->msgcount >= 0)
5402 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */
5403 /* always refresh the registration at the interval requested by the server
5404 we are registering to
5406 reg->refresh = refresh;
5407 if (reg->expire > -1)
5408 ast_sched_del(sched, reg->expire);
5409 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
5410 if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
5411 if (option_verbose > 2) {
5412 if (reg->messages > 255)
5413 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
5414 else if (reg->messages > 1)
5415 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
5416 else if (reg->messages > 0)
5417 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
5418 else
5419 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
5420 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
5421 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
5423 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
5425 reg->regstate = REG_STATE_REGISTERED;
5426 return 0;
5429 static int iax2_register(char *value, int lineno)
5431 struct iax2_registry *reg;
5432 char copy[256];
5433 char *username, *hostname, *secret;
5434 char *porta;
5435 char *stringp=NULL;
5437 if (!value)
5438 return -1;
5439 ast_copy_string(copy, value, sizeof(copy));
5440 stringp=copy;
5441 username = strsep(&stringp, "@");
5442 hostname = strsep(&stringp, "@");
5443 if (!hostname) {
5444 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d", lineno);
5445 return -1;
5447 stringp=username;
5448 username = strsep(&stringp, ":");
5449 secret = strsep(&stringp, ":");
5450 stringp=hostname;
5451 hostname = strsep(&stringp, ":");
5452 porta = strsep(&stringp, ":");
5454 if (porta && !atoi(porta)) {
5455 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
5456 return -1;
5458 if (!(reg = ast_calloc(1, sizeof(*reg))))
5459 return -1;
5460 if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
5461 free(reg);
5462 return -1;
5464 ast_copy_string(reg->username, username, sizeof(reg->username));
5465 if (secret)
5466 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
5467 reg->expire = -1;
5468 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
5469 reg->addr.sin_family = AF_INET;
5470 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
5471 reg->next = registrations;
5472 reg->callno = 0;
5473 registrations = reg;
5475 return 0;
5478 static void register_peer_exten(struct iax2_peer *peer, int onoff)
5480 char multi[256];
5481 char *stringp, *ext;
5482 if (!ast_strlen_zero(regcontext)) {
5483 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
5484 stringp = multi;
5485 while((ext = strsep(&stringp, "&"))) {
5486 if (onoff) {
5487 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
5488 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
5489 "Noop", ast_strdup(peer->name), ast_free, "IAX2");
5490 } else
5491 ast_context_remove_extension(regcontext, ext, 1, NULL);
5495 static void prune_peers(void);
5497 static void __expire_registry(void *data)
5499 char *name = data;
5500 struct iax2_peer *p = NULL;
5502 /* Go through and grab this peer... and if it needs to be removed... then do it */
5503 AST_LIST_LOCK(&peers);
5504 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) {
5505 if (!strcasecmp(p->name, name)) {
5506 p->expire = -1;
5507 break;
5510 AST_LIST_TRAVERSE_SAFE_END
5511 AST_LIST_UNLOCK(&peers);
5513 /* Peer is already gone for whatever reason */
5514 if (!p)
5515 return;
5517 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
5518 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
5519 realtime_update_peer(p->name, &p->addr, 0);
5520 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name);
5521 /* Reset the address */
5522 memset(&p->addr, 0, sizeof(p->addr));
5523 /* Reset expiry value */
5524 p->expiry = min_reg_expire;
5525 if (!ast_test_flag(p, IAX_TEMPONLY))
5526 ast_db_del("IAX/Registry", p->name);
5527 register_peer_exten(p, 0);
5528 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
5529 if (iax2_regfunk)
5530 iax2_regfunk(p->name, 0);
5532 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
5533 ast_set_flag(p, IAX_DELME);
5534 prune_peers();
5538 static int expire_registry(void *data)
5540 #ifdef SCHED_MULTITHREADED
5541 if (schedule_action(__expire_registry, data))
5542 #endif
5543 __expire_registry(data);
5544 return 0;
5547 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
5549 static void reg_source_db(struct iax2_peer *p)
5551 char data[80];
5552 struct in_addr in;
5553 char *c, *d;
5554 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
5555 c = strchr(data, ':');
5556 if (c) {
5557 *c = '\0';
5558 c++;
5559 if (inet_aton(data, &in)) {
5560 d = strchr(c, ':');
5561 if (d) {
5562 *d = '\0';
5563 d++;
5564 if (option_verbose > 2)
5565 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
5566 ast_inet_ntoa(in), atoi(c), atoi(d));
5567 iax2_poke_peer(p, 0);
5568 p->expiry = atoi(d);
5569 memset(&p->addr, 0, sizeof(p->addr));
5570 p->addr.sin_family = AF_INET;
5571 p->addr.sin_addr = in;
5572 p->addr.sin_port = htons(atoi(c));
5573 if (p->expire > -1)
5574 ast_sched_del(sched, p->expire);
5575 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
5576 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
5577 if (iax2_regfunk)
5578 iax2_regfunk(p->name, 1);
5579 register_peer_exten(p, 1);
5587 static int update_registry(const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
5589 /* Called from IAX thread only, with proper iaxsl lock */
5590 struct iax_ie_data ied;
5591 struct iax2_peer *p;
5592 int msgcount;
5593 char data[80];
5594 int version;
5596 memset(&ied, 0, sizeof(ied));
5598 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
5599 if (!(p = find_peer(name, 1))) {
5600 ast_log(LOG_WARNING, "No such peer '%s'\n", name);
5601 return -1;
5604 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
5605 if (sin->sin_addr.s_addr) {
5606 time_t nowtime;
5607 time(&nowtime);
5608 realtime_update_peer(name, sin, nowtime);
5609 } else {
5610 realtime_update_peer(name, sin, 0);
5613 if (inaddrcmp(&p->addr, sin)) {
5614 if (iax2_regfunk)
5615 iax2_regfunk(p->name, 1);
5616 /* Stash the IP address from which they registered */
5617 memcpy(&p->addr, sin, sizeof(p->addr));
5618 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
5619 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
5620 ast_db_put("IAX/Registry", p->name, data);
5621 if (option_verbose > 2)
5622 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
5623 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
5624 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
5625 register_peer_exten(p, 1);
5626 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
5627 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
5628 if (option_verbose > 2)
5629 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
5630 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
5631 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
5632 register_peer_exten(p, 0);
5633 ast_db_del("IAX/Registry", p->name);
5634 ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
5636 /* Update the host */
5637 /* Verify that the host is really there */
5638 iax2_poke_peer(p, callno);
5640 /* Store socket fd */
5641 p->sockfd = fd;
5642 /* Setup the expiry */
5643 if (p->expire > -1)
5644 ast_sched_del(sched, p->expire);
5645 /* treat an unspecified refresh interval as the minimum */
5646 if (!refresh)
5647 refresh = min_reg_expire;
5648 if (refresh > max_reg_expire) {
5649 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5650 p->name, max_reg_expire, refresh);
5651 p->expiry = max_reg_expire;
5652 } else if (refresh < min_reg_expire) {
5653 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
5654 p->name, min_reg_expire, refresh);
5655 p->expiry = min_reg_expire;
5656 } else {
5657 p->expiry = refresh;
5659 if (p->expiry && sin->sin_addr.s_addr)
5660 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
5661 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
5662 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
5663 if (sin->sin_addr.s_addr) {
5664 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
5665 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
5666 if (!ast_strlen_zero(p->mailbox)) {
5667 int new, old;
5668 ast_app_inboxcount(p->mailbox, &new, &old);
5669 if (new > 255)
5670 new = 255;
5671 if (old > 255)
5672 old = 255;
5673 msgcount = (old << 8) | new;
5674 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
5676 if (ast_test_flag(p, IAX_HASCALLERID)) {
5677 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
5678 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
5681 version = iax_check_version(devtype);
5682 if (version)
5683 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
5684 if (ast_test_flag(p, IAX_TEMPONLY))
5685 destroy_peer(p);
5686 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
5689 static int registry_authrequest(const char *name, int callno)
5691 struct iax_ie_data ied;
5692 struct iax2_peer *p;
5693 char challenge[10];
5694 /* SLD: third call to find_peer in registration */
5695 p = find_peer(name, 1);
5696 if (p) {
5697 memset(&ied, 0, sizeof(ied));
5698 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
5699 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
5700 /* Build the challenge */
5701 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
5702 ast_string_field_set(iaxs[callno], challenge, challenge);
5703 /* snprintf(iaxs[callno]->challenge, sizeof(iaxs[callno]->challenge), "%d", (int)ast_random()); */
5704 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
5706 iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
5707 if (ast_test_flag(p, IAX_TEMPONLY))
5708 destroy_peer(p);
5709 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
5711 ast_log(LOG_WARNING, "No such peer '%s'\n", name);
5712 return 0;
5715 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
5717 struct iax2_registry *reg;
5718 /* Start pessimistic */
5719 struct iax_ie_data ied;
5720 char peer[256] = "";
5721 char challenge[256] = "";
5722 int res;
5723 int authmethods = 0;
5724 if (ies->authmethods)
5725 authmethods = ies->authmethods;
5726 if (ies->username)
5727 ast_copy_string(peer, ies->username, sizeof(peer));
5728 if (ies->challenge)
5729 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
5730 memset(&ied, 0, sizeof(ied));
5731 reg = iaxs[callno]->reg;
5732 if (reg) {
5733 if (inaddrcmp(&reg->addr, sin)) {
5734 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
5735 return -1;
5737 if (ast_strlen_zero(reg->secret)) {
5738 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
5739 reg->regstate = REG_STATE_NOAUTH;
5740 return -1;
5742 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
5743 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
5744 if (reg->secret[0] == '[') {
5745 char tmpkey[256];
5746 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
5747 tmpkey[strlen(tmpkey) - 1] = '\0';
5748 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
5749 } else
5750 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
5751 if (!res) {
5752 reg->regstate = REG_STATE_AUTHSENT;
5753 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
5754 } else
5755 return -1;
5756 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
5757 } else
5758 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
5759 return -1;
5762 static void stop_stuff(int callno)
5764 iax2_destroy_helper(iaxs[callno]);
5767 static void __auth_reject(void *nothing)
5769 /* Called from IAX thread only, without iaxs lock */
5770 int callno = (int)(long)(nothing);
5771 struct iax_ie_data ied;
5772 ast_mutex_lock(&iaxsl[callno]);
5773 if (iaxs[callno]) {
5774 memset(&ied, 0, sizeof(ied));
5775 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
5776 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
5777 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
5778 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
5779 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
5780 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
5782 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
5784 ast_mutex_unlock(&iaxsl[callno]);
5787 static int auth_reject(void *data)
5789 int callno = (int)(long)(data);
5790 ast_mutex_lock(&iaxsl[callno]);
5791 if (iaxs[callno])
5792 iaxs[callno]->authid = -1;
5793 ast_mutex_unlock(&iaxsl[callno]);
5794 #ifdef SCHED_MULTITHREADED
5795 if (schedule_action(__auth_reject, data))
5796 #endif
5797 __auth_reject(data);
5798 return 0;
5801 static int auth_fail(int callno, int failcode)
5803 /* Schedule sending the authentication failure in one second, to prevent
5804 guessing */
5805 ast_mutex_lock(&iaxsl[callno]);
5806 if (iaxs[callno]) {
5807 iaxs[callno]->authfail = failcode;
5808 if (delayreject) {
5809 if (iaxs[callno]->authid > -1)
5810 ast_sched_del(sched, iaxs[callno]->authid);
5811 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
5812 } else
5813 auth_reject((void *)(long)callno);
5815 ast_mutex_unlock(&iaxsl[callno]);
5816 return 0;
5819 static void __auto_hangup(void *nothing)
5821 /* Called from IAX thread only, without iaxs lock */
5822 int callno = (int)(long)(nothing);
5823 struct iax_ie_data ied;
5824 ast_mutex_lock(&iaxsl[callno]);
5825 if (iaxs[callno]) {
5826 memset(&ied, 0, sizeof(ied));
5827 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
5828 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
5829 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
5831 ast_mutex_unlock(&iaxsl[callno]);
5834 static int auto_hangup(void *data)
5836 int callno = (int)(long)(data);
5837 ast_mutex_lock(&iaxsl[callno]);
5838 if (iaxs[callno]) {
5839 iaxs[callno]->autoid = -1;
5841 ast_mutex_unlock(&iaxsl[callno]);
5842 #ifdef SCHED_MULTITHREADED
5843 if (schedule_action(__auto_hangup, data))
5844 #endif
5845 __auto_hangup(data);
5846 return 0;
5849 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
5851 struct iax_ie_data ied;
5852 /* Auto-hangup with 30 seconds of inactivity */
5853 if (iaxs[callno]->autoid > -1)
5854 ast_sched_del(sched, iaxs[callno]->autoid);
5855 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
5856 memset(&ied, 0, sizeof(ied));
5857 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
5858 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
5859 dp->flags |= CACHE_FLAG_TRANSMITTED;
5862 static int iax2_vnak(int callno)
5864 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
5867 static void vnak_retransmit(int callno, int last)
5869 struct iax_frame *f;
5871 AST_LIST_LOCK(&iaxq.queue);
5872 AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
5873 /* Send a copy immediately */
5874 if ((f->callno == callno) && iaxs[f->callno] &&
5875 (f->oseqno >= last)) {
5876 send_packet(f);
5879 AST_LIST_UNLOCK(&iaxq.queue);
5882 static void __iax2_poke_peer_s(void *data)
5884 struct iax2_peer *peer = data;
5885 iax2_poke_peer(peer, 0);
5888 static int iax2_poke_peer_s(void *data)
5890 struct iax2_peer *peer = data;
5891 peer->pokeexpire = -1;
5892 #ifdef SCHED_MULTITHREADED
5893 if (schedule_action(__iax2_poke_peer_s, data))
5894 #endif
5895 __iax2_poke_peer_s(data);
5896 return 0;
5899 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
5901 int res = 0;
5902 struct iax_frame *fr;
5903 struct ast_iax2_meta_hdr *meta;
5904 struct ast_iax2_meta_trunk_hdr *mth;
5905 int calls = 0;
5907 /* Point to frame */
5908 fr = (struct iax_frame *)tpeer->trunkdata;
5909 /* Point to meta data */
5910 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
5911 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
5912 if (tpeer->trunkdatalen) {
5913 /* We're actually sending a frame, so fill the meta trunk header and meta header */
5914 meta->zeros = 0;
5915 meta->metacmd = IAX_META_TRUNK;
5916 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
5917 meta->cmddata = IAX_META_TRUNK_MINI;
5918 else
5919 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
5920 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
5921 /* And the rest of the ast_iax2 header */
5922 fr->direction = DIRECTION_OUTGRESS;
5923 fr->retrans = -1;
5924 fr->transfer = 0;
5925 /* Any appropriate call will do */
5926 fr->data = fr->afdata;
5927 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
5928 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
5929 calls = tpeer->calls;
5930 #if 0
5931 ast_log(LOG_DEBUG, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
5932 #endif
5933 /* Reset transmit trunk side data */
5934 tpeer->trunkdatalen = 0;
5935 tpeer->calls = 0;
5937 if (res < 0)
5938 return res;
5939 return calls;
5942 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
5944 /* Drop when trunk is about 5 seconds idle */
5945 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
5946 return 1;
5947 return 0;
5950 static int timing_read(int *id, int fd, short events, void *cbdata)
5952 char buf[1024];
5953 int res;
5954 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
5955 int processed = 0;
5956 int totalcalls = 0;
5957 #ifdef ZT_TIMERACK
5958 int x = 1;
5959 #endif
5960 struct timeval now;
5961 if (iaxtrunkdebug)
5962 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
5963 gettimeofday(&now, NULL);
5964 if (events & AST_IO_PRI) {
5965 #ifdef ZT_TIMERACK
5966 /* Great, this is a timing interface, just call the ioctl */
5967 if (ioctl(fd, ZT_TIMERACK, &x))
5968 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
5969 res = 0;
5970 #endif
5971 } else {
5972 /* Read and ignore from the pseudo channel for timing */
5973 res = read(fd, buf, sizeof(buf));
5974 if (res < 1) {
5975 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
5976 return 1;
5979 /* For each peer that supports trunking... */
5980 ast_mutex_lock(&tpeerlock);
5981 tpeer = tpeers;
5982 while(tpeer) {
5983 processed++;
5984 res = 0;
5985 ast_mutex_lock(&tpeer->lock);
5986 /* We can drop a single tpeer per pass. That makes all this logic
5987 substantially easier */
5988 if (!drop && iax2_trunk_expired(tpeer, &now)) {
5989 /* Take it out of the list, but don't free it yet, because it
5990 could be in use */
5991 if (prev)
5992 prev->next = tpeer->next;
5993 else
5994 tpeers = tpeer->next;
5995 drop = tpeer;
5996 } else {
5997 res = send_trunk(tpeer, &now);
5998 if (iaxtrunkdebug)
5999 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
6001 totalcalls += res;
6002 res = 0;
6003 ast_mutex_unlock(&tpeer->lock);
6004 prev = tpeer;
6005 tpeer = tpeer->next;
6007 ast_mutex_unlock(&tpeerlock);
6008 if (drop) {
6009 ast_mutex_lock(&drop->lock);
6010 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it,
6011 because by the time they could get tpeerlock, we've already grabbed it */
6012 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
6013 free(drop->trunkdata);
6014 ast_mutex_unlock(&drop->lock);
6015 ast_mutex_destroy(&drop->lock);
6016 free(drop);
6019 if (iaxtrunkdebug)
6020 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
6021 iaxtrunkdebug =0;
6022 return 1;
6025 struct dpreq_data {
6026 int callno;
6027 char context[AST_MAX_EXTENSION];
6028 char callednum[AST_MAX_EXTENSION];
6029 char *callerid;
6032 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
6034 unsigned short dpstatus = 0;
6035 struct iax_ie_data ied1;
6036 int mm;
6038 memset(&ied1, 0, sizeof(ied1));
6039 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
6040 /* Must be started */
6041 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
6042 dpstatus = IAX_DPSTATUS_EXISTS;
6043 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
6044 dpstatus = IAX_DPSTATUS_CANEXIST;
6045 } else {
6046 dpstatus = IAX_DPSTATUS_NONEXISTENT;
6048 if (ast_ignore_pattern(context, callednum))
6049 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
6050 if (mm)
6051 dpstatus |= IAX_DPSTATUS_MATCHMORE;
6052 if (!skiplock)
6053 ast_mutex_lock(&iaxsl[callno]);
6054 if (iaxs[callno]) {
6055 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
6056 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
6057 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
6058 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
6060 if (!skiplock)
6061 ast_mutex_unlock(&iaxsl[callno]);
6064 static void *dp_lookup_thread(void *data)
6066 /* Look up for dpreq */
6067 struct dpreq_data *dpr = data;
6068 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
6069 if (dpr->callerid)
6070 free(dpr->callerid);
6071 free(dpr);
6072 return NULL;
6075 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
6077 pthread_t newthread;
6078 struct dpreq_data *dpr;
6080 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
6081 return;
6083 dpr->callno = callno;
6084 ast_copy_string(dpr->context, context, sizeof(dpr->context));
6085 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
6086 if (callerid)
6087 dpr->callerid = ast_strdup(callerid);
6088 if (ast_pthread_create(&newthread, NULL, dp_lookup_thread, dpr)) {
6089 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
6093 struct iax_dual {
6094 struct ast_channel *chan1;
6095 struct ast_channel *chan2;
6098 static void *iax_park_thread(void *stuff)
6100 struct ast_channel *chan1, *chan2;
6101 struct iax_dual *d;
6102 struct ast_frame *f;
6103 int ext;
6104 int res;
6105 d = stuff;
6106 chan1 = d->chan1;
6107 chan2 = d->chan2;
6108 free(d);
6109 f = ast_read(chan1);
6110 if (f)
6111 ast_frfree(f);
6112 res = ast_park_call(chan1, chan2, 0, &ext);
6113 ast_hangup(chan2);
6114 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
6115 return NULL;
6118 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
6120 struct iax_dual *d;
6121 struct ast_channel *chan1m, *chan2m;
6122 pthread_t th;
6123 chan1m = ast_channel_alloc(0);
6124 chan2m = ast_channel_alloc(0);
6125 if (chan2m && chan1m) {
6126 ast_string_field_build(chan1m, name, "Parking/%s", chan1->name);
6127 /* Make formats okay */
6128 chan1m->readformat = chan1->readformat;
6129 chan1m->writeformat = chan1->writeformat;
6130 ast_channel_masquerade(chan1m, chan1);
6131 /* Setup the extensions and such */
6132 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
6133 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
6134 chan1m->priority = chan1->priority;
6136 /* We make a clone of the peer channel too, so we can play
6137 back the announcement */
6138 ast_string_field_build(chan2m, name, "IAXPeer/%s",chan2->name);
6139 /* Make formats okay */
6140 chan2m->readformat = chan2->readformat;
6141 chan2m->writeformat = chan2->writeformat;
6142 ast_channel_masquerade(chan2m, chan2);
6143 /* Setup the extensions and such */
6144 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
6145 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
6146 chan2m->priority = chan2->priority;
6147 if (ast_do_masquerade(chan2m)) {
6148 ast_log(LOG_WARNING, "Masquerade failed :(\n");
6149 ast_hangup(chan2m);
6150 return -1;
6152 } else {
6153 if (chan1m)
6154 ast_hangup(chan1m);
6155 if (chan2m)
6156 ast_hangup(chan2m);
6157 return -1;
6159 if ((d = ast_calloc(1, sizeof(*d)))) {
6160 d->chan1 = chan1m;
6161 d->chan2 = chan2m;
6162 if (!ast_pthread_create(&th, NULL, iax_park_thread, d))
6163 return 0;
6164 free(d);
6166 return -1;
6170 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
6172 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
6174 unsigned int ourver;
6175 char rsi[80];
6176 snprintf(rsi, sizeof(rsi), "si-%s", si);
6177 if (iax_provision_version(&ourver, rsi, 1))
6178 return 0;
6179 if (option_debug)
6180 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
6181 if (ourver != ver)
6182 iax2_provision(sin, sockfd, NULL, rsi, 1);
6183 return 0;
6186 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
6188 jb_info stats;
6189 jb_getinfo(pvt->jb, &stats);
6191 memset(iep, 0, sizeof(*iep));
6193 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
6194 if(stats.frames_in == 0) stats.frames_in = 1;
6195 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
6196 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
6197 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
6198 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
6199 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
6202 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
6204 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
6205 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
6206 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
6207 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
6208 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
6209 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
6210 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
6213 static int socket_read(int *id, int fd, short events, void *cbdata)
6215 struct iax2_thread *thread;
6216 socklen_t len;
6217 time_t t;
6218 static time_t last_errtime=0;
6220 thread = find_idle_thread();
6221 if (thread) {
6222 len = sizeof(thread->iosin);
6223 thread->iofd = fd;
6224 thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0,(struct sockaddr *) &thread->iosin, &len);
6225 if (thread->iores < 0) {
6226 if (errno != ECONNREFUSED && errno != EAGAIN)
6227 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
6228 handle_error();
6229 AST_LIST_LOCK(&idle_list);
6230 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
6231 AST_LIST_UNLOCK(&idle_list);
6232 return 1;
6234 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
6235 AST_LIST_LOCK(&idle_list);
6236 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
6237 AST_LIST_UNLOCK(&idle_list);
6238 return 1;
6240 /* Mark as ready and send on its way */
6241 thread->iostate = IAX_IOSTATE_READY;
6242 #ifdef DEBUG_SCHED_MULTITHREAD
6243 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
6244 #endif
6245 signal_condition(&thread->lock, &thread->cond);
6246 } else {
6247 time(&t);
6248 if (t != last_errtime)
6249 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
6250 last_errtime = t;
6251 usleep(1);
6253 return 1;
6256 static int socket_process(struct iax2_thread *thread)
6258 struct sockaddr_in sin;
6259 int res;
6260 int updatehistory=1;
6261 int new = NEW_PREVENT;
6262 void *ptr;
6263 int dcallno = 0;
6264 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
6265 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
6266 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
6267 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
6268 struct ast_iax2_meta_trunk_hdr *mth;
6269 struct ast_iax2_meta_trunk_entry *mte;
6270 struct ast_iax2_meta_trunk_mini *mtm;
6271 struct iax_frame *fr;
6272 struct iax_frame *cur;
6273 struct ast_frame f;
6274 struct ast_channel *c;
6275 struct iax2_dpcache *dp;
6276 struct iax2_peer *peer;
6277 struct iax2_trunk_peer *tpeer;
6278 struct timeval rxtrunktime;
6279 struct iax_ies ies;
6280 struct iax_ie_data ied0, ied1;
6281 int format;
6282 int fd;
6283 int exists;
6284 int minivid = 0;
6285 unsigned int ts;
6286 char empty[32]=""; /* Safety measure */
6287 struct iax_frame *duped_fr;
6288 char host_pref_buf[128];
6289 char caller_pref_buf[128];
6290 struct ast_codec_pref pref;
6291 char *using_prefs = "mine";
6293 /* allocate an iax_frame with 4096 bytes of data buffer */
6294 fr = alloca(sizeof(*fr) + 4096);
6295 fr->callno = 0;
6297 /* Copy frequently used parameters to the stack */
6298 res = thread->iores;
6299 fd = thread->iofd;
6300 memcpy(&sin, &thread->iosin, sizeof(sin));
6302 if (res < sizeof(*mh)) {
6303 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
6304 return 1;
6306 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
6307 if (res < sizeof(*vh)) {
6308 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
6309 return 1;
6312 /* This is a video frame, get call number */
6313 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
6314 minivid = 1;
6315 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
6316 unsigned char metatype;
6318 if (res < sizeof(*meta)) {
6319 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
6320 return 1;
6323 /* This is a meta header */
6324 switch(meta->metacmd) {
6325 case IAX_META_TRUNK:
6326 if (res < (sizeof(*meta) + sizeof(*mth))) {
6327 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
6328 sizeof(*meta) + sizeof(*mth));
6329 return 1;
6331 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
6332 ts = ntohl(mth->ts);
6333 metatype = meta->cmddata;
6334 res -= (sizeof(*meta) + sizeof(*mth));
6335 ptr = mth->data;
6336 tpeer = find_tpeer(&sin, fd);
6337 if (!tpeer) {
6338 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
6339 return 1;
6341 tpeer->trunkact = ast_tvnow();
6342 if (!ts || ast_tvzero(tpeer->rxtrunktime))
6343 tpeer->rxtrunktime = tpeer->trunkact;
6344 rxtrunktime = tpeer->rxtrunktime;
6345 ast_mutex_unlock(&tpeer->lock);
6346 while(res >= sizeof(*mte)) {
6347 /* Process channels */
6348 unsigned short callno, trunked_ts, len;
6350 if (metatype == IAX_META_TRUNK_MINI) {
6351 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
6352 ptr += sizeof(*mtm);
6353 res -= sizeof(*mtm);
6354 len = ntohs(mtm->len);
6355 callno = ntohs(mtm->mini.callno);
6356 trunked_ts = ntohs(mtm->mini.ts);
6357 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
6358 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
6359 ptr += sizeof(*mte);
6360 res -= sizeof(*mte);
6361 len = ntohs(mte->len);
6362 callno = ntohs(mte->callno);
6363 trunked_ts = 0;
6364 } else {
6365 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
6366 break;
6368 /* Stop if we don't have enough data */
6369 if (len > res)
6370 break;
6371 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
6372 if (fr->callno) {
6373 ast_mutex_lock(&iaxsl[fr->callno]);
6374 /* If it's a valid call, deliver the contents. If not, we
6375 drop it, since we don't have a scallno to use for an INVAL */
6376 /* Process as a mini frame */
6377 f.frametype = AST_FRAME_VOICE;
6378 if (iaxs[fr->callno]) {
6379 if (iaxs[fr->callno]->voiceformat > 0) {
6380 f.subclass = iaxs[fr->callno]->voiceformat;
6381 f.datalen = len;
6382 if (f.datalen >= 0) {
6383 if (f.datalen)
6384 f.data = ptr;
6385 else
6386 f.data = NULL;
6387 if(trunked_ts) {
6388 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
6389 } else
6390 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
6391 /* Don't pass any packets until we're started */
6392 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
6393 /* Common things */
6394 f.src = "IAX2";
6395 f.mallocd = 0;
6396 f.offset = 0;
6397 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
6398 f.samples = ast_codec_get_samples(&f);
6399 else
6400 f.samples = 0;
6401 fr->outoforder = 0;
6402 iax_frame_wrap(fr, &f);
6403 duped_fr = iaxfrdup2(fr);
6404 if (duped_fr) {
6405 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
6407 if (iaxs[fr->callno]->last < fr->ts) {
6408 iaxs[fr->callno]->last = fr->ts;
6409 #if 1
6410 if (option_debug && iaxdebug)
6411 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
6412 #endif
6415 } else {
6416 ast_log(LOG_WARNING, "Datalen < 0?\n");
6418 } else {
6419 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
6420 iax2_vnak(fr->callno);
6423 ast_mutex_unlock(&iaxsl[fr->callno]);
6425 ptr += len;
6426 res -= len;
6430 return 1;
6433 #ifdef DEBUG_SUPPORT
6434 if (iaxdebug && (res >= sizeof(*fh)))
6435 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
6436 #endif
6437 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
6438 if (res < sizeof(*fh)) {
6439 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
6440 return 1;
6443 /* Get the destination call number */
6444 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
6445 /* Retrieve the type and subclass */
6446 f.frametype = fh->type;
6447 if (f.frametype == AST_FRAME_VIDEO) {
6448 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
6449 } else {
6450 f.subclass = uncompress_subclass(fh->csub);
6452 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
6453 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
6454 (f.subclass == IAX_COMMAND_REGREL)))
6455 new = NEW_ALLOW;
6456 } else {
6457 /* Don't know anything about it yet */
6458 f.frametype = AST_FRAME_NULL;
6459 f.subclass = 0;
6462 if (!fr->callno)
6463 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
6465 if (fr->callno > 0)
6466 ast_mutex_lock(&iaxsl[fr->callno]);
6468 if (!fr->callno || !iaxs[fr->callno]) {
6469 /* A call arrived for a nonexistent destination. Unless it's an "inval"
6470 frame, reply with an inval */
6471 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
6472 /* We can only raw hangup control frames */
6473 if (((f.subclass != IAX_COMMAND_INVAL) &&
6474 (f.subclass != IAX_COMMAND_TXCNT) &&
6475 (f.subclass != IAX_COMMAND_TXACC) &&
6476 (f.subclass != IAX_COMMAND_FWDOWNL))||
6477 (f.frametype != AST_FRAME_IAX))
6478 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
6479 fd);
6481 if (fr->callno > 0)
6482 ast_mutex_unlock(&iaxsl[fr->callno]);
6483 return 1;
6485 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
6486 if (decrypt_frame(fr->callno, fh, &f, &res)) {
6487 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
6488 ast_mutex_unlock(&iaxsl[fr->callno]);
6489 return 1;
6491 #ifdef DEBUG_SUPPORT
6492 else if (iaxdebug)
6493 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
6494 #endif
6497 /* count this frame */
6498 iaxs[fr->callno]->frames_received++;
6500 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
6501 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */
6502 f.subclass != IAX_COMMAND_TXACC) /* for attended transfer */
6503 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
6504 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
6505 if (option_debug && iaxdebug)
6506 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
6507 /* Check if it's out of order (and not an ACK or INVAL) */
6508 fr->oseqno = fh->oseqno;
6509 fr->iseqno = fh->iseqno;
6510 fr->ts = ntohl(fh->ts);
6511 #ifdef IAXTESTS
6512 if (test_resync) {
6513 if (option_debug)
6514 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
6515 fr->ts += test_resync;
6517 #endif /* IAXTESTS */
6518 #if 0
6519 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
6520 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
6521 (f.subclass == IAX_COMMAND_NEW ||
6522 f.subclass == IAX_COMMAND_AUTHREQ ||
6523 f.subclass == IAX_COMMAND_ACCEPT ||
6524 f.subclass == IAX_COMMAND_REJECT)) ) )
6525 #endif
6526 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
6527 updatehistory = 0;
6528 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
6529 (iaxs[fr->callno]->iseqno ||
6530 ((f.subclass != IAX_COMMAND_TXCNT) &&
6531 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */
6532 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */
6533 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
6534 (f.subclass != IAX_COMMAND_TXACC)) ||
6535 (f.frametype != AST_FRAME_IAX))) {
6536 if (
6537 ((f.subclass != IAX_COMMAND_ACK) &&
6538 (f.subclass != IAX_COMMAND_INVAL) &&
6539 (f.subclass != IAX_COMMAND_TXCNT) &&
6540 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */
6541 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */
6542 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */
6543 (f.subclass != IAX_COMMAND_TXACC) &&
6544 (f.subclass != IAX_COMMAND_VNAK)) ||
6545 (f.frametype != AST_FRAME_IAX)) {
6546 /* If it's not an ACK packet, it's out of order. */
6547 if (option_debug)
6548 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
6549 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
6550 if (iaxs[fr->callno]->iseqno > fr->oseqno) {
6551 /* If we've already seen it, ack it XXX There's a border condition here XXX */
6552 if ((f.frametype != AST_FRAME_IAX) ||
6553 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
6554 if (option_debug)
6555 ast_log(LOG_DEBUG, "Acking anyway\n");
6556 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
6557 we have anything to send, we'll retransmit and get an ACK back anyway XXX */
6558 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
6560 } else {
6561 /* Send a VNAK requesting retransmission */
6562 iax2_vnak(fr->callno);
6564 ast_mutex_unlock(&iaxsl[fr->callno]);
6565 return 1;
6567 } else {
6568 /* Increment unless it's an ACK or VNAK */
6569 if (((f.subclass != IAX_COMMAND_ACK) &&
6570 (f.subclass != IAX_COMMAND_INVAL) &&
6571 (f.subclass != IAX_COMMAND_TXCNT) &&
6572 (f.subclass != IAX_COMMAND_TXACC) &&
6573 (f.subclass != IAX_COMMAND_VNAK)) ||
6574 (f.frametype != AST_FRAME_IAX))
6575 iaxs[fr->callno]->iseqno++;
6577 /* A full frame */
6578 if (res < sizeof(*fh)) {
6579 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
6580 ast_mutex_unlock(&iaxsl[fr->callno]);
6581 return 1;
6583 f.datalen = res - sizeof(*fh);
6585 /* Handle implicit ACKing unless this is an INVAL, and only if this is
6586 from the real peer, not the transfer peer */
6587 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
6588 ((f.subclass != IAX_COMMAND_INVAL) ||
6589 (f.frametype != AST_FRAME_IAX))) {
6590 unsigned char x;
6591 /* XXX This code is not very efficient. Surely there is a better way which still
6592 properly handles boundary conditions? XXX */
6593 /* First we have to qualify that the ACKed value is within our window */
6594 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
6595 if (fr->iseqno == x)
6596 break;
6597 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
6598 /* The acknowledgement is within our window. Time to acknowledge everything
6599 that it says to */
6600 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
6601 /* Ack the packet with the given timestamp */
6602 if (option_debug && iaxdebug)
6603 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
6604 AST_LIST_LOCK(&iaxq.queue);
6605 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
6606 /* If it's our call, and our timestamp, mark -1 retries */
6607 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
6608 cur->retries = -1;
6609 /* Destroy call if this is the end */
6610 if (cur->final) {
6611 if (iaxdebug && option_debug)
6612 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
6613 iax2_destroy_nolock(fr->callno);
6617 AST_LIST_UNLOCK(&iaxq.queue);
6619 /* Note how much we've received acknowledgement for */
6620 if (iaxs[fr->callno])
6621 iaxs[fr->callno]->rseqno = fr->iseqno;
6622 else {
6623 /* Stop processing now */
6624 ast_mutex_unlock(&iaxsl[fr->callno]);
6625 return 1;
6627 } else
6628 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
6630 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
6631 ((f.frametype != AST_FRAME_IAX) ||
6632 ((f.subclass != IAX_COMMAND_TXACC) &&
6633 (f.subclass != IAX_COMMAND_TXCNT)))) {
6634 /* Only messages we accept from a transfer host are TXACC and TXCNT */
6635 ast_mutex_unlock(&iaxsl[fr->callno]);
6636 return 1;
6639 if (f.datalen) {
6640 if (f.frametype == AST_FRAME_IAX) {
6641 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
6642 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
6643 ast_mutex_unlock(&iaxsl[fr->callno]);
6644 return 1;
6646 f.data = NULL;
6647 } else
6648 f.data = thread->buf + sizeof(*fh);
6649 } else {
6650 if (f.frametype == AST_FRAME_IAX)
6651 f.data = NULL;
6652 else
6653 f.data = empty;
6654 memset(&ies, 0, sizeof(ies));
6656 if (f.frametype == AST_FRAME_VOICE) {
6657 if (f.subclass != iaxs[fr->callno]->voiceformat) {
6658 iaxs[fr->callno]->voiceformat = f.subclass;
6659 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
6660 if (iaxs[fr->callno]->owner) {
6661 int orignative;
6662 retryowner:
6663 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
6664 ast_mutex_unlock(&iaxsl[fr->callno]);
6665 usleep(1);
6666 ast_mutex_lock(&iaxsl[fr->callno]);
6667 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
6669 if (iaxs[fr->callno]) {
6670 if (iaxs[fr->callno]->owner) {
6671 orignative = iaxs[fr->callno]->owner->nativeformats;
6672 iaxs[fr->callno]->owner->nativeformats = f.subclass;
6673 if (iaxs[fr->callno]->owner->readformat)
6674 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
6675 iaxs[fr->callno]->owner->nativeformats = orignative;
6676 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
6678 } else {
6679 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
6680 ast_mutex_unlock(&iaxsl[fr->callno]);
6681 return 1;
6686 if (f.frametype == AST_FRAME_VIDEO) {
6687 if (f.subclass != iaxs[fr->callno]->videoformat) {
6688 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
6689 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
6692 if (f.frametype == AST_FRAME_IAX) {
6693 if (iaxs[fr->callno]->initid > -1) {
6694 /* Don't auto congest anymore since we've gotten something usefulb ack */
6695 ast_sched_del(sched, iaxs[fr->callno]->initid);
6696 iaxs[fr->callno]->initid = -1;
6698 /* Handle the IAX pseudo frame itself */
6699 if (option_debug && iaxdebug)
6700 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
6702 /* Update last ts unless the frame's timestamp originated with us. */
6703 if (iaxs[fr->callno]->last < fr->ts &&
6704 f.subclass != IAX_COMMAND_ACK &&
6705 f.subclass != IAX_COMMAND_PONG &&
6706 f.subclass != IAX_COMMAND_LAGRP) {
6707 iaxs[fr->callno]->last = fr->ts;
6708 if (option_debug && iaxdebug)
6709 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
6712 switch(f.subclass) {
6713 case IAX_COMMAND_ACK:
6714 /* Do nothing */
6715 break;
6716 case IAX_COMMAND_QUELCH:
6717 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
6718 /* Generate Manager Hold event, if necessary*/
6719 if (iaxs[fr->callno]->owner) {
6720 manager_event(EVENT_FLAG_CALL, "Hold",
6721 "Channel: %s\r\n"
6722 "Uniqueid: %s\r\n",
6723 iaxs[fr->callno]->owner->name,
6724 iaxs[fr->callno]->owner->uniqueid);
6727 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
6728 if (ies.musiconhold) {
6729 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
6730 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
6731 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD,
6732 S_OR(mohsuggest, NULL),
6733 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
6737 break;
6738 case IAX_COMMAND_UNQUELCH:
6739 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
6740 /* Generate Manager Unhold event, if necessary*/
6741 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
6742 manager_event(EVENT_FLAG_CALL, "Unhold",
6743 "Channel: %s\r\n"
6744 "Uniqueid: %s\r\n",
6745 iaxs[fr->callno]->owner->name,
6746 iaxs[fr->callno]->owner->uniqueid);
6749 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
6750 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner))
6751 ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD);
6753 break;
6754 case IAX_COMMAND_TXACC:
6755 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
6756 /* Ack the packet with the given timestamp */
6757 AST_LIST_LOCK(&iaxq.queue);
6758 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
6759 /* Cancel any outstanding txcnt's */
6760 if ((fr->callno == cur->callno) && (cur->transfer))
6761 cur->retries = -1;
6763 AST_LIST_UNLOCK(&iaxq.queue);
6764 memset(&ied1, 0, sizeof(ied1));
6765 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
6766 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
6767 iaxs[fr->callno]->transferring = TRANSFER_READY;
6769 break;
6770 case IAX_COMMAND_NEW:
6771 /* Ignore if it's already up */
6772 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
6773 break;
6774 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
6775 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
6776 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
6777 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
6778 fr->callno = make_trunk(fr->callno, 1);
6780 /* For security, always ack immediately */
6781 if (delayreject)
6782 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
6783 if (check_access(fr->callno, &sin, &ies)) {
6784 /* They're not allowed on */
6785 auth_fail(fr->callno, IAX_COMMAND_REJECT);
6786 if (authdebug)
6787 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
6788 break;
6790 /* This might re-enter the IAX code and need the lock */
6791 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
6792 ast_mutex_unlock(&iaxsl[fr->callno]);
6793 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
6794 ast_mutex_lock(&iaxsl[fr->callno]);
6795 } else
6796 exists = 0;
6797 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
6798 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
6799 memset(&ied0, 0, sizeof(ied0));
6800 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
6801 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
6802 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
6803 if (authdebug)
6804 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
6805 } else {
6806 /* Select an appropriate format */
6808 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
6809 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
6810 using_prefs = "reqonly";
6811 } else {
6812 using_prefs = "disabled";
6814 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
6815 memset(&pref, 0, sizeof(pref));
6816 strcpy(caller_pref_buf, "disabled");
6817 strcpy(host_pref_buf, "disabled");
6818 } else {
6819 using_prefs = "mine";
6820 /* If the information elements are in here... use them */
6821 if (ies.codec_prefs)
6822 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
6823 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
6824 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
6825 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
6826 pref = iaxs[fr->callno]->rprefs;
6827 using_prefs = "caller";
6828 } else {
6829 pref = iaxs[fr->callno]->prefs;
6831 } else
6832 pref = iaxs[fr->callno]->prefs;
6834 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
6835 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
6836 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
6838 if (!format) {
6839 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
6840 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
6841 if (!format) {
6842 memset(&ied0, 0, sizeof(ied0));
6843 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
6844 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
6845 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
6846 if (authdebug) {
6847 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
6848 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
6849 else
6850 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
6852 } else {
6853 /* Pick one... */
6854 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
6855 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
6856 format = 0;
6857 } else {
6858 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
6859 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
6860 memset(&pref, 0, sizeof(pref));
6861 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
6862 strcpy(caller_pref_buf,"disabled");
6863 strcpy(host_pref_buf,"disabled");
6864 } else {
6865 using_prefs = "mine";
6866 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
6867 /* Do the opposite of what we tried above. */
6868 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
6869 pref = iaxs[fr->callno]->prefs;
6870 } else {
6871 pref = iaxs[fr->callno]->rprefs;
6872 using_prefs = "caller";
6874 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
6876 } else /* if no codec_prefs IE do it the old way */
6877 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
6881 if (!format) {
6882 memset(&ied0, 0, sizeof(ied0));
6883 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
6884 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
6885 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
6886 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
6887 if (authdebug)
6888 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
6889 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
6890 break;
6894 if (format) {
6895 /* No authentication required, let them in */
6896 memset(&ied1, 0, sizeof(ied1));
6897 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
6898 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
6899 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
6900 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
6901 if (option_verbose > 2)
6902 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
6903 "%srequested format = %s,\n"
6904 "%srequested prefs = %s,\n"
6905 "%sactual format = %s,\n"
6906 "%shost prefs = %s,\n"
6907 "%spriority = %s\n",
6908 ast_inet_ntoa(sin.sin_addr),
6909 VERBOSE_PREFIX_4,
6910 ast_getformatname(iaxs[fr->callno]->peerformat),
6911 VERBOSE_PREFIX_4,
6912 caller_pref_buf,
6913 VERBOSE_PREFIX_4,
6914 ast_getformatname(format),
6915 VERBOSE_PREFIX_4,
6916 host_pref_buf,
6917 VERBOSE_PREFIX_4,
6918 using_prefs);
6920 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
6921 iax2_destroy_nolock(fr->callno);
6922 } else {
6923 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
6924 /* If this is a TBD call, we're ready but now what... */
6925 if (option_verbose > 2)
6926 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
6930 break;
6932 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
6933 merge_encryption(iaxs[fr->callno],ies.encmethods);
6934 else
6935 iaxs[fr->callno]->encmethods = 0;
6936 if (!authenticate_request(iaxs[fr->callno]))
6937 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
6938 break;
6939 case IAX_COMMAND_DPREQ:
6940 /* Request status in the dialplan */
6941 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
6942 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
6943 if (iaxcompat) {
6944 /* Spawn a thread for the lookup */
6945 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
6946 } else {
6947 /* Just look it up */
6948 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
6951 break;
6952 case IAX_COMMAND_HANGUP:
6953 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
6954 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
6955 /* Set hangup cause according to remote */
6956 if (ies.causecode && iaxs[fr->callno]->owner)
6957 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
6958 /* Send ack immediately, before we destroy */
6959 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
6960 iax2_destroy_nolock(fr->callno);
6961 break;
6962 case IAX_COMMAND_REJECT:
6963 /* Set hangup cause according to remote */
6964 if (ies.causecode && iaxs[fr->callno]->owner)
6965 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
6967 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
6968 if (iaxs[fr->callno]->owner && authdebug)
6969 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
6970 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
6971 ies.cause ? ies.cause : "<Unknown>");
6972 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
6973 fr->callno);
6975 /* Send ack immediately, before we destroy */
6976 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
6977 fr->ts, NULL, 0, fr->iseqno);
6978 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
6979 iaxs[fr->callno]->error = EPERM;
6980 iax2_destroy_nolock(fr->callno);
6981 break;
6982 case IAX_COMMAND_TRANSFER:
6983 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
6984 /* Set BLINDTRANSFER channel variables */
6985 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
6986 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
6987 if (!strcmp(ies.called_number, ast_parking_ext())) {
6988 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
6989 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
6990 } else
6991 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
6992 } else {
6993 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
6994 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name,
6995 ies.called_number, iaxs[fr->callno]->context);
6996 else
6997 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name,
6998 ies.called_number, iaxs[fr->callno]->context);
7000 } else
7001 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
7002 break;
7003 case IAX_COMMAND_ACCEPT:
7004 /* Ignore if call is already up or needs authentication or is a TBD */
7005 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
7006 break;
7007 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
7008 /* Send ack immediately, before we destroy */
7009 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7010 iax2_destroy_nolock(fr->callno);
7011 break;
7013 if (ies.format) {
7014 iaxs[fr->callno]->peerformat = ies.format;
7015 } else {
7016 if (iaxs[fr->callno]->owner)
7017 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
7018 else
7019 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
7021 if (option_verbose > 2)
7022 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
7023 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
7024 memset(&ied0, 0, sizeof(ied0));
7025 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
7026 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
7027 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7028 if (authdebug)
7029 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
7030 } else {
7031 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
7032 if (iaxs[fr->callno]->owner) {
7033 /* Switch us to use a compatible format */
7034 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
7035 if (option_verbose > 2)
7036 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
7037 retryowner2:
7038 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
7039 ast_mutex_unlock(&iaxsl[fr->callno]);
7040 usleep(1);
7041 ast_mutex_lock(&iaxsl[fr->callno]);
7042 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
7045 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
7046 /* Setup read/write formats properly. */
7047 if (iaxs[fr->callno]->owner->writeformat)
7048 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
7049 if (iaxs[fr->callno]->owner->readformat)
7050 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
7051 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
7055 ast_mutex_lock(&dpcache_lock);
7056 dp = iaxs[fr->callno]->dpentries;
7057 while(dp) {
7058 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
7059 iax2_dprequest(dp, fr->callno);
7061 dp = dp->peer;
7063 ast_mutex_unlock(&dpcache_lock);
7064 break;
7065 case IAX_COMMAND_POKE:
7066 /* Send back a pong packet with the original timestamp */
7067 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
7068 break;
7069 case IAX_COMMAND_PING:
7071 struct iax_ie_data pingied;
7072 construct_rr(iaxs[fr->callno], &pingied);
7073 /* Send back a pong packet with the original timestamp */
7074 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
7076 break;
7077 case IAX_COMMAND_PONG:
7078 /* Calculate ping time */
7079 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
7080 /* save RR info */
7081 save_rr(fr, &ies);
7083 if (iaxs[fr->callno]->peerpoke) {
7084 peer = iaxs[fr->callno]->peerpoke;
7085 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
7086 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
7087 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
7088 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
7089 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
7091 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
7092 if (iaxs[fr->callno]->pingtime > peer->maxms) {
7093 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
7094 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
7095 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
7098 peer->lastms = iaxs[fr->callno]->pingtime;
7099 if (peer->smoothing && (peer->lastms > -1))
7100 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
7101 else if (peer->smoothing && peer->lastms < 0)
7102 peer->historicms = (0 + peer->historicms) / 2;
7103 else
7104 peer->historicms = iaxs[fr->callno]->pingtime;
7106 /* Remove scheduled iax2_poke_noanswer */
7107 if (peer->pokeexpire > -1)
7108 ast_sched_del(sched, peer->pokeexpire);
7109 /* Schedule the next cycle */
7110 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
7111 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
7112 else
7113 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
7114 /* and finally send the ack */
7115 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7116 /* And wrap up the qualify call */
7117 iax2_destroy_nolock(fr->callno);
7118 peer->callno = 0;
7119 if (option_debug)
7120 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
7122 break;
7123 case IAX_COMMAND_LAGRQ:
7124 case IAX_COMMAND_LAGRP:
7125 f.src = "LAGRQ";
7126 f.mallocd = 0;
7127 f.offset = 0;
7128 f.samples = 0;
7129 iax_frame_wrap(fr, &f);
7130 if(f.subclass == IAX_COMMAND_LAGRQ) {
7131 /* Received a LAGRQ - echo back a LAGRP */
7132 fr->af.subclass = IAX_COMMAND_LAGRP;
7133 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
7134 } else {
7135 /* Received LAGRP in response to our LAGRQ */
7136 unsigned int ts;
7137 /* This is a reply we've been given, actually measure the difference */
7138 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
7139 iaxs[fr->callno]->lag = ts - fr->ts;
7140 if (option_debug && iaxdebug)
7141 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
7142 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
7144 break;
7145 case IAX_COMMAND_AUTHREQ:
7146 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
7147 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
7148 break;
7150 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
7151 ast_log(LOG_WARNING,
7152 "I don't know how to authenticate %s to %s\n",
7153 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
7155 break;
7156 case IAX_COMMAND_AUTHREP:
7157 /* For security, always ack immediately */
7158 if (delayreject)
7159 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7160 /* Ignore once we've started */
7161 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
7162 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
7163 break;
7165 if (authenticate_verify(iaxs[fr->callno], &ies)) {
7166 if (authdebug)
7167 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
7168 memset(&ied0, 0, sizeof(ied0));
7169 auth_fail(fr->callno, IAX_COMMAND_REJECT);
7170 break;
7172 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
7173 /* This might re-enter the IAX code and need the lock */
7174 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
7175 } else
7176 exists = 0;
7177 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
7178 if (authdebug)
7179 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
7180 memset(&ied0, 0, sizeof(ied0));
7181 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
7182 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
7183 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7184 } else {
7185 /* Select an appropriate format */
7186 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
7187 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
7188 using_prefs = "reqonly";
7189 } else {
7190 using_prefs = "disabled";
7192 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
7193 memset(&pref, 0, sizeof(pref));
7194 strcpy(caller_pref_buf, "disabled");
7195 strcpy(host_pref_buf, "disabled");
7196 } else {
7197 using_prefs = "mine";
7198 if (ies.codec_prefs)
7199 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
7200 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
7201 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
7202 pref = iaxs[fr->callno]->rprefs;
7203 using_prefs = "caller";
7204 } else {
7205 pref = iaxs[fr->callno]->prefs;
7207 } else /* if no codec_prefs IE do it the old way */
7208 pref = iaxs[fr->callno]->prefs;
7210 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
7211 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
7212 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
7214 if (!format) {
7215 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
7216 ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
7217 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
7219 if (!format) {
7220 if (authdebug) {
7221 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
7222 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
7223 else
7224 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
7226 memset(&ied0, 0, sizeof(ied0));
7227 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
7228 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
7229 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7230 } else {
7231 /* Pick one... */
7232 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
7233 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
7234 format = 0;
7235 } else {
7236 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
7237 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
7238 memset(&pref, 0, sizeof(pref));
7239 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
7240 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
7241 strcpy(caller_pref_buf,"disabled");
7242 strcpy(host_pref_buf,"disabled");
7243 } else {
7244 using_prefs = "mine";
7245 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
7246 /* Do the opposite of what we tried above. */
7247 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
7248 pref = iaxs[fr->callno]->prefs;
7249 } else {
7250 pref = iaxs[fr->callno]->rprefs;
7251 using_prefs = "caller";
7253 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
7254 } else /* if no codec_prefs IE do it the old way */
7255 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
7258 if (!format) {
7259 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
7260 if (authdebug) {
7261 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
7262 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
7263 else
7264 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
7266 memset(&ied0, 0, sizeof(ied0));
7267 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
7268 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
7269 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7273 if (format) {
7274 /* Authentication received */
7275 memset(&ied1, 0, sizeof(ied1));
7276 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
7277 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
7278 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
7279 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
7280 if (option_verbose > 2)
7281 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
7282 "%srequested format = %s,\n"
7283 "%srequested prefs = %s,\n"
7284 "%sactual format = %s,\n"
7285 "%shost prefs = %s,\n"
7286 "%spriority = %s\n",
7287 ast_inet_ntoa(sin.sin_addr),
7288 VERBOSE_PREFIX_4,
7289 ast_getformatname(iaxs[fr->callno]->peerformat),
7290 VERBOSE_PREFIX_4,
7291 caller_pref_buf,
7292 VERBOSE_PREFIX_4,
7293 ast_getformatname(format),
7294 VERBOSE_PREFIX_4,
7295 host_pref_buf,
7296 VERBOSE_PREFIX_4,
7297 using_prefs);
7299 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
7300 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
7301 iax2_destroy_nolock(fr->callno);
7302 } else {
7303 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
7304 /* If this is a TBD call, we're ready but now what... */
7305 if (option_verbose > 2)
7306 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
7310 break;
7311 case IAX_COMMAND_DIAL:
7312 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
7313 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
7314 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
7315 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
7316 if (authdebug)
7317 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
7318 memset(&ied0, 0, sizeof(ied0));
7319 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
7320 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
7321 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7322 } else {
7323 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
7324 if (option_verbose > 2)
7325 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
7326 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
7327 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
7328 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
7329 iax2_destroy_nolock(fr->callno);
7332 break;
7333 case IAX_COMMAND_INVAL:
7334 iaxs[fr->callno]->error = ENOTCONN;
7335 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
7336 iax2_destroy_nolock(fr->callno);
7337 if (option_debug)
7338 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
7339 break;
7340 case IAX_COMMAND_VNAK:
7341 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
7342 /* Force retransmission */
7343 vnak_retransmit(fr->callno, fr->iseqno);
7344 break;
7345 case IAX_COMMAND_REGREQ:
7346 case IAX_COMMAND_REGREL:
7347 /* For security, always ack immediately */
7348 if (delayreject)
7349 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7350 if (register_verify(fr->callno, &sin, &ies)) {
7351 /* Send delayed failure */
7352 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
7353 break;
7355 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
7356 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
7357 if (f.subclass == IAX_COMMAND_REGREL)
7358 memset(&sin, 0, sizeof(sin));
7359 if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
7360 ast_log(LOG_WARNING, "Registry error\n");
7361 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
7362 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
7363 break;
7365 registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
7366 break;
7367 case IAX_COMMAND_REGACK:
7368 if (iax2_ack_registry(&ies, &sin, fr->callno))
7369 ast_log(LOG_WARNING, "Registration failure\n");
7370 /* Send ack immediately, before we destroy */
7371 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7372 iax2_destroy_nolock(fr->callno);
7373 break;
7374 case IAX_COMMAND_REGREJ:
7375 if (iaxs[fr->callno]->reg) {
7376 if (authdebug) {
7377 ast_log(LOG_NOTICE, "Registration of '%s' rejected: '%s' from: '%s'\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>", ast_inet_ntoa(sin.sin_addr));
7378 manager_event(EVENT_FLAG_SYSTEM, "Registry", "Channel: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
7380 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
7382 /* Send ack immediately, before we destroy */
7383 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7384 iax2_destroy_nolock(fr->callno);
7385 break;
7386 case IAX_COMMAND_REGAUTH:
7387 /* Authentication request */
7388 if (registry_rerequest(&ies, fr->callno, &sin)) {
7389 memset(&ied0, 0, sizeof(ied0));
7390 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
7391 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
7392 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7394 break;
7395 case IAX_COMMAND_TXREJ:
7396 iaxs[fr->callno]->transferring = 0;
7397 if (option_verbose > 2)
7398 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
7399 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
7400 if (iaxs[fr->callno]->bridgecallno) {
7401 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
7402 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
7403 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
7406 break;
7407 case IAX_COMMAND_TXREADY:
7408 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
7409 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
7410 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
7411 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
7412 else
7413 iaxs[fr->callno]->transferring = TRANSFER_READY;
7414 if (option_verbose > 2)
7415 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
7416 if (iaxs[fr->callno]->bridgecallno) {
7417 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
7418 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
7419 /* They're both ready, now release them. */
7420 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
7421 if (option_verbose > 2)
7422 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
7423 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
7425 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
7426 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
7428 memset(&ied0, 0, sizeof(ied0));
7429 memset(&ied1, 0, sizeof(ied1));
7430 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
7431 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
7432 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
7433 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
7434 } else {
7435 if (option_verbose > 2)
7436 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
7437 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
7439 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
7440 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
7441 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
7442 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
7444 /* Stop doing lag & ping requests */
7445 stop_stuff(fr->callno);
7446 stop_stuff(iaxs[fr->callno]->bridgecallno);
7448 memset(&ied0, 0, sizeof(ied0));
7449 memset(&ied1, 0, sizeof(ied1));
7450 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
7451 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
7452 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
7453 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
7459 break;
7460 case IAX_COMMAND_TXREQ:
7461 try_transfer(iaxs[fr->callno], &ies);
7462 break;
7463 case IAX_COMMAND_TXCNT:
7464 if (iaxs[fr->callno]->transferring)
7465 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
7466 break;
7467 case IAX_COMMAND_TXREL:
7468 /* Send ack immediately, rather than waiting until we've changed addresses */
7469 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7470 complete_transfer(fr->callno, &ies);
7471 stop_stuff(fr->callno); /* for attended transfer to work with libiax */
7472 break;
7473 case IAX_COMMAND_TXMEDIA:
7474 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
7475 /* Start sending our media to the transfer address, but otherwise leave the call as-is */
7476 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
7478 break;
7479 case IAX_COMMAND_DPREP:
7480 complete_dpreply(iaxs[fr->callno], &ies);
7481 break;
7482 case IAX_COMMAND_UNSUPPORT:
7483 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
7484 break;
7485 case IAX_COMMAND_FWDOWNL:
7486 /* Firmware download */
7487 memset(&ied0, 0, sizeof(ied0));
7488 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
7489 if (res < 0)
7490 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
7491 else if (res > 0)
7492 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
7493 else
7494 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
7495 break;
7496 default:
7497 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
7498 memset(&ied0, 0, sizeof(ied0));
7499 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
7500 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
7502 /* Don't actually pass these frames along */
7503 if ((f.subclass != IAX_COMMAND_ACK) &&
7504 (f.subclass != IAX_COMMAND_TXCNT) &&
7505 (f.subclass != IAX_COMMAND_TXACC) &&
7506 (f.subclass != IAX_COMMAND_INVAL) &&
7507 (f.subclass != IAX_COMMAND_VNAK)) {
7508 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
7509 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7511 ast_mutex_unlock(&iaxsl[fr->callno]);
7512 return 1;
7514 /* Unless this is an ACK or INVAL frame, ack it */
7515 if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
7516 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
7517 } else if (minivid) {
7518 f.frametype = AST_FRAME_VIDEO;
7519 if (iaxs[fr->callno]->videoformat > 0)
7520 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
7521 else {
7522 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
7523 iax2_vnak(fr->callno);
7524 ast_mutex_unlock(&iaxsl[fr->callno]);
7525 return 1;
7527 f.datalen = res - sizeof(*vh);
7528 if (f.datalen)
7529 f.data = thread->buf + sizeof(*vh);
7530 else
7531 f.data = NULL;
7532 #ifdef IAXTESTS
7533 if (test_resync) {
7534 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(mh->ts) + test_resync) & 0x7fff);
7535 } else
7536 #endif /* IAXTESTS */
7537 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(mh->ts) & 0x7fff);
7538 } else {
7539 /* A mini frame */
7540 f.frametype = AST_FRAME_VOICE;
7541 if (iaxs[fr->callno]->voiceformat > 0)
7542 f.subclass = iaxs[fr->callno]->voiceformat;
7543 else {
7544 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
7545 iax2_vnak(fr->callno);
7546 ast_mutex_unlock(&iaxsl[fr->callno]);
7547 return 1;
7549 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
7550 if (f.datalen < 0) {
7551 ast_log(LOG_WARNING, "Datalen < 0?\n");
7552 ast_mutex_unlock(&iaxsl[fr->callno]);
7553 return 1;
7555 if (f.datalen)
7556 f.data = thread->buf + sizeof(*mh);
7557 else
7558 f.data = NULL;
7559 #ifdef IAXTESTS
7560 if (test_resync) {
7561 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
7562 } else
7563 #endif /* IAXTESTS */
7564 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
7565 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
7567 /* Don't pass any packets until we're started */
7568 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
7569 ast_mutex_unlock(&iaxsl[fr->callno]);
7570 return 1;
7572 /* Common things */
7573 f.src = "IAX2";
7574 f.mallocd = 0;
7575 f.offset = 0;
7576 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
7577 f.samples = ast_codec_get_samples(&f);
7578 /* We need to byteswap incoming slinear samples from network byte order */
7579 if (f.subclass == AST_FORMAT_SLINEAR)
7580 ast_frame_byteswap_be(&f);
7581 } else
7582 f.samples = 0;
7583 iax_frame_wrap(fr, &f);
7585 /* If this is our most recent packet, use it as our basis for timestamping */
7586 if (iaxs[fr->callno]->last < fr->ts) {
7587 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
7588 fr->outoforder = 0;
7589 } else {
7590 if (option_debug && iaxdebug)
7591 ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
7592 fr->outoforder = -1;
7594 duped_fr = iaxfrdup2(fr);
7595 if (duped_fr) {
7596 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
7598 if (iaxs[fr->callno]->last < fr->ts) {
7599 iaxs[fr->callno]->last = fr->ts;
7600 #if 1
7601 if (option_debug && iaxdebug)
7602 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
7603 #endif
7606 /* Always run again */
7607 ast_mutex_unlock(&iaxsl[fr->callno]);
7608 return 1;
7611 static void *iax2_process_thread(void *data)
7613 struct iax2_thread *thread = data;
7614 struct timeval tv;
7615 struct timespec ts;
7617 for(;;) {
7618 /* Wait for something to signal us to be awake */
7619 ast_mutex_lock(&thread->lock);
7620 if (thread->type == IAX_TYPE_DYNAMIC) {
7621 /* Wait to be signalled or time out */
7622 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
7623 ts.tv_sec = tv.tv_sec;
7624 ts.tv_nsec = tv.tv_usec * 1000;
7625 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
7626 ast_mutex_unlock(&thread->lock);
7627 AST_LIST_LOCK(&dynamic_list);
7628 AST_LIST_REMOVE(&dynamic_list, thread, list);
7629 iaxdynamicthreadcount--;
7630 AST_LIST_UNLOCK(&dynamic_list);
7631 break;
7633 } else {
7634 ast_cond_wait(&thread->cond, &thread->lock);
7636 ast_mutex_unlock(&thread->lock);
7638 /* If we were signalled, then we are already out of both lists or we are shutting down */
7639 if (thread->halt) {
7640 break;
7643 /* Add ourselves to the active list now */
7644 AST_LIST_LOCK(&active_list);
7645 AST_LIST_INSERT_HEAD(&active_list, thread, list);
7646 AST_LIST_UNLOCK(&active_list);
7648 /* See what we need to do */
7649 switch(thread->iostate) {
7650 case IAX_IOSTATE_READY:
7651 thread->actions++;
7652 thread->iostate = IAX_IOSTATE_PROCESSING;
7653 socket_process(thread);
7654 break;
7655 case IAX_IOSTATE_SCHEDREADY:
7656 thread->actions++;
7657 thread->iostate = IAX_IOSTATE_PROCESSING;
7658 #ifdef SCHED_MULTITHREADED
7659 thread->schedfunc(thread->scheddata);
7660 #endif
7661 break;
7663 time(&thread->checktime);
7664 thread->iostate = IAX_IOSTATE_IDLE;
7665 #ifdef DEBUG_SCHED_MULTITHREAD
7666 thread->curfunc[0]='\0';
7667 #endif
7669 /* Now... remove ourselves from the active list, and return to the idle list */
7670 AST_LIST_LOCK(&active_list);
7671 AST_LIST_REMOVE(&active_list, thread, list);
7672 AST_LIST_UNLOCK(&active_list);
7674 /* Go back into our respective list */
7675 if (thread->type == IAX_TYPE_DYNAMIC) {
7676 AST_LIST_LOCK(&dynamic_list);
7677 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
7678 AST_LIST_UNLOCK(&dynamic_list);
7679 } else {
7680 AST_LIST_LOCK(&idle_list);
7681 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
7682 AST_LIST_UNLOCK(&idle_list);
7686 /* Free our own memory */
7687 ast_mutex_destroy(&thread->lock);
7688 ast_cond_destroy(&thread->cond);
7689 free(thread);
7691 return NULL;
7694 static int iax2_do_register(struct iax2_registry *reg)
7696 struct iax_ie_data ied;
7697 if (option_debug && iaxdebug)
7698 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
7700 if (reg->dnsmgr &&
7701 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
7702 /* Maybe the IP has changed, force DNS refresh */
7703 ast_dnsmgr_refresh(reg->dnsmgr);
7707 * if IP has Changed, free allocated call to create a new one with new IP
7708 * call has the pointer to IP and must be updated to the new one
7710 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
7711 iax2_destroy(reg->callno);
7712 reg->callno = 0;
7714 if (!reg->addr.sin_addr.s_addr) {
7715 if (option_debug && iaxdebug)
7716 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
7717 /* Setup the next registration attempt */
7718 if (reg->expire > -1)
7719 ast_sched_del(sched, reg->expire);
7720 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
7721 return -1;
7724 if (!reg->callno) {
7725 if (option_debug)
7726 ast_log(LOG_DEBUG, "Allocate call number\n");
7727 reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, 1, defaultsockfd);
7728 if (reg->callno < 1) {
7729 ast_log(LOG_WARNING, "Unable to create call for registration\n");
7730 return -1;
7731 } else if (option_debug)
7732 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
7733 iaxs[reg->callno]->reg = reg;
7735 /* Schedule the next registration attempt */
7736 if (reg->expire > -1)
7737 ast_sched_del(sched, reg->expire);
7738 /* Setup the next registration a little early */
7739 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
7740 /* Send the request */
7741 memset(&ied, 0, sizeof(ied));
7742 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
7743 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
7744 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
7745 reg->regstate = REG_STATE_REGSENT;
7746 return 0;
7749 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
7751 if (pos != 3)
7752 return NULL;
7753 return iax_prov_complete_template(line, word, pos, state);
7756 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
7758 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
7759 is found for template */
7760 struct iax_ie_data provdata;
7761 struct iax_ie_data ied;
7762 unsigned int sig;
7763 struct sockaddr_in sin;
7764 int callno;
7765 struct create_addr_info cai;
7767 memset(&cai, 0, sizeof(cai));
7769 if (option_debug)
7770 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
7772 if (iax_provision_build(&provdata, &sig, template, force)) {
7773 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
7774 return 0;
7777 if (end) {
7778 memcpy(&sin, end, sizeof(sin));
7779 cai.sockfd = sockfd;
7780 } else if (create_addr(dest, &sin, &cai))
7781 return -1;
7783 /* Build the rest of the message */
7784 memset(&ied, 0, sizeof(ied));
7785 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
7787 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
7788 if (!callno)
7789 return -1;
7791 ast_mutex_lock(&iaxsl[callno]);
7792 if (iaxs[callno]) {
7793 /* Schedule autodestruct in case they don't ever give us anything back */
7794 if (iaxs[callno]->autoid > -1)
7795 ast_sched_del(sched, iaxs[callno]->autoid);
7796 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
7797 ast_set_flag(iaxs[callno], IAX_PROVISION);
7798 /* Got a call number now, so go ahead and send the provisioning information */
7799 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
7801 ast_mutex_unlock(&iaxsl[callno]);
7803 return 1;
7806 static char *papp = "IAX2Provision";
7807 static char *psyn = "Provision a calling IAXy with a given template";
7808 static char *pdescrip =
7809 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
7810 "the calling entity is in fact an IAXy) with the given template or\n"
7811 "default if one is not specified. Returns -1 on error or 0 on success.\n";
7813 /*! iax2provision
7814 \ingroup applications
7816 static int iax2_prov_app(struct ast_channel *chan, void *data)
7818 int res;
7819 char *sdata;
7820 char *opts;
7821 int force =0;
7822 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
7823 if (ast_strlen_zero(data))
7824 data = "default";
7825 sdata = ast_strdupa(data);
7826 opts = strchr(sdata, '|');
7827 if (opts)
7828 *opts='\0';
7830 if (chan->tech != &iax2_tech) {
7831 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
7832 return -1;
7834 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
7835 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
7836 return -1;
7838 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
7839 if (option_verbose > 2)
7840 ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
7841 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
7842 sdata, res);
7843 return res;
7847 static int iax2_prov_cmd(int fd, int argc, char *argv[])
7849 int force = 0;
7850 int res;
7851 if (argc < 4)
7852 return RESULT_SHOWUSAGE;
7853 if ((argc > 4)) {
7854 if (!strcasecmp(argv[4], "forced"))
7855 force = 1;
7856 else
7857 return RESULT_SHOWUSAGE;
7859 res = iax2_provision(NULL, -1, argv[2], argv[3], force);
7860 if (res < 0)
7861 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
7862 else if (res < 1)
7863 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
7864 else
7865 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
7866 return RESULT_SUCCESS;
7869 static void __iax2_poke_noanswer(void *data)
7871 struct iax2_peer *peer = data;
7872 if (peer->lastms > -1) {
7873 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
7874 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
7875 ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
7877 if (peer->callno > 0)
7878 iax2_destroy(peer->callno);
7879 peer->callno = 0;
7880 peer->lastms = -1;
7881 /* Try again quickly */
7882 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
7885 static int iax2_poke_noanswer(void *data)
7887 struct iax2_peer *peer = data;
7888 peer->pokeexpire = -1;
7889 #ifdef SCHED_MULTITHREADED
7890 if (schedule_action(__iax2_poke_noanswer, data))
7891 #endif
7892 __iax2_poke_noanswer(data);
7893 return 0;
7896 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
7898 if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
7899 /* IF we have no IP, or this isn't to be monitored, return
7900 immediately after clearing things out */
7901 peer->lastms = 0;
7902 peer->historicms = 0;
7903 peer->pokeexpire = -1;
7904 peer->callno = 0;
7905 return 0;
7907 if (peer->callno > 0) {
7908 ast_log(LOG_NOTICE, "Still have a callno...\n");
7909 iax2_destroy(peer->callno);
7911 if (heldcall)
7912 ast_mutex_unlock(&iaxsl[heldcall]);
7913 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
7914 if (heldcall)
7915 ast_mutex_lock(&iaxsl[heldcall]);
7916 if (peer->callno < 1) {
7917 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
7918 return -1;
7921 /* Speed up retransmission times for this qualify call */
7922 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
7923 iaxs[peer->callno]->peerpoke = peer;
7925 /* Remove any pending pokeexpire task */
7926 if (peer->pokeexpire > -1)
7927 ast_sched_del(sched, peer->pokeexpire);
7929 /* Queue up a new task to handle no reply */
7930 /* If the host is already unreachable then use the unreachable interval instead */
7931 if (peer->lastms < 0) {
7932 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
7933 } else
7934 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
7936 /* And send the poke */
7937 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
7939 return 0;
7942 static void free_context(struct iax2_context *con)
7944 struct iax2_context *conl;
7945 while(con) {
7946 conl = con;
7947 con = con->next;
7948 free(conl);
7952 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
7954 int callno;
7955 int res;
7956 int fmt, native;
7957 struct sockaddr_in sin;
7958 struct ast_channel *c;
7959 struct parsed_dial_string pds;
7960 struct create_addr_info cai;
7961 char *tmpstr;
7963 memset(&pds, 0, sizeof(pds));
7964 tmpstr = ast_strdupa(data);
7965 parse_dial_string(tmpstr, &pds);
7967 memset(&cai, 0, sizeof(cai));
7968 cai.capability = iax2_capability;
7970 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
7972 if (!pds.peer) {
7973 ast_log(LOG_WARNING, "No peer given\n");
7974 return NULL;
7978 /* Populate our address from the given */
7979 if (create_addr(pds.peer, &sin, &cai)) {
7980 *cause = AST_CAUSE_UNREGISTERED;
7981 return NULL;
7984 if (pds.port)
7985 sin.sin_port = htons(atoi(pds.port));
7987 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
7988 if (callno < 1) {
7989 ast_log(LOG_WARNING, "Unable to create call\n");
7990 *cause = AST_CAUSE_CONGESTION;
7991 return NULL;
7994 ast_mutex_lock(&iaxsl[callno]);
7996 /* If this is a trunk, update it now */
7997 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
7998 if (ast_test_flag(&cai, IAX_TRUNK))
7999 callno = make_trunk(callno, 1);
8000 iaxs[callno]->maxtime = cai.maxtime;
8001 if (cai.found)
8002 ast_string_field_set(iaxs[callno], host, pds.peer);
8004 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
8006 ast_mutex_unlock(&iaxsl[callno]);
8008 if (c) {
8009 /* Choose a format we can live with */
8010 if (c->nativeformats & format)
8011 c->nativeformats &= format;
8012 else {
8013 native = c->nativeformats;
8014 fmt = format;
8015 res = ast_translator_best_choice(&fmt, &native);
8016 if (res < 0) {
8017 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
8018 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
8019 ast_hangup(c);
8020 return NULL;
8022 c->nativeformats = native;
8024 c->readformat = ast_best_codec(c->nativeformats);
8025 c->writeformat = c->readformat;
8028 return c;
8031 static void *sched_thread(void *ignore)
8033 int count;
8034 int res;
8035 struct timeval tv;
8036 struct timespec ts;
8038 for (;;) {
8039 res = ast_sched_wait(sched);
8040 if ((res > 1000) || (res < 0))
8041 res = 1000;
8042 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
8043 ts.tv_sec = tv.tv_sec;
8044 ts.tv_nsec = tv.tv_usec * 1000;
8046 ast_mutex_lock(&sched_lock);
8047 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
8048 if (sched_halt == 1)
8049 break;
8050 ast_mutex_unlock(&sched_lock);
8052 count = ast_sched_runq(sched);
8053 if (count >= 20)
8054 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
8056 ast_mutex_unlock(&sched_lock);
8057 return NULL;
8060 static void *network_thread(void *ignore)
8062 /* Our job is simple: Send queued messages, retrying if necessary. Read frames
8063 from the network, and queue them for delivery to the channels */
8064 int res, count;
8065 struct iax_frame *f;
8067 if (timingfd > -1)
8068 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
8070 for(;;) {
8071 /* Go through the queue, sending messages which have not yet been
8072 sent, and scheduling retransmissions if appropriate */
8073 AST_LIST_LOCK(&iaxq.queue);
8074 count = 0;
8075 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
8076 if (f->sentyet)
8077 continue;
8079 f->sentyet++;
8080 /* Send a copy immediately -- errors here are ok, so don't bother locking */
8081 if (iaxs[f->callno]) {
8082 send_packet(f);
8083 count++;
8085 if (f->retries < 0) {
8086 /* This is not supposed to be retransmitted */
8087 AST_LIST_REMOVE(&iaxq.queue, f, list);
8088 iaxq.count--;
8089 /* Free the iax frame */
8090 iax_frame_free(f);
8091 } else {
8092 /* We need reliable delivery. Schedule a retransmission */
8093 f->retries++;
8094 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
8095 signal_condition(&sched_lock, &sched_cond);
8098 AST_LIST_TRAVERSE_SAFE_END
8099 AST_LIST_UNLOCK(&iaxq.queue);
8101 if (count >= 20)
8102 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
8104 /* Now do the IO, and run scheduled tasks */
8105 res = ast_io_wait(io, -1);
8106 if (res >= 0) {
8107 if (res >= 20)
8108 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
8111 return NULL;
8114 static int start_network_thread(void)
8116 int threadcount = 0;
8117 int x;
8118 for (x = 0; x < iaxthreadcount; x++) {
8119 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
8120 if (thread) {
8121 thread->type = IAX_TYPE_POOL;
8122 thread->threadnum = ++threadcount;
8123 ast_mutex_init(&thread->lock);
8124 ast_cond_init(&thread->cond, NULL);
8125 if (ast_pthread_create(&thread->threadid, NULL, iax2_process_thread, thread)) {
8126 ast_log(LOG_WARNING, "Failed to create new thread!\n");
8127 free(thread);
8128 thread = NULL;
8130 AST_LIST_LOCK(&idle_list);
8131 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
8132 AST_LIST_UNLOCK(&idle_list);
8135 ast_pthread_create(&schedthreadid, NULL, sched_thread, NULL);
8136 ast_pthread_create(&netthreadid, NULL, network_thread, NULL);
8137 if (option_verbose > 1)
8138 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
8139 return 0;
8142 static struct iax2_context *build_context(char *context)
8144 struct iax2_context *con;
8146 if ((con = ast_calloc(1, sizeof(*con))))
8147 ast_copy_string(con->context, context, sizeof(con->context));
8149 return con;
8152 static int get_auth_methods(char *value)
8154 int methods = 0;
8155 if (strstr(value, "rsa"))
8156 methods |= IAX_AUTH_RSA;
8157 if (strstr(value, "md5"))
8158 methods |= IAX_AUTH_MD5;
8159 if (strstr(value, "plaintext"))
8160 methods |= IAX_AUTH_PLAINTEXT;
8161 return methods;
8165 /*! \brief Check if address can be used as packet source.
8166 \return 0 address available, 1 address unavailable, -1 error
8168 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
8170 int sd;
8171 int res;
8173 sd = socket(AF_INET, SOCK_DGRAM, 0);
8174 if (sd < 0) {
8175 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
8176 return -1;
8179 res = bind(sd, sa, salen);
8180 if (res < 0) {
8181 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
8182 close(sd);
8183 return 1;
8186 close(sd);
8187 return 0;
8190 /*! \brief Parse the "sourceaddress" value,
8191 lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
8192 not found. */
8193 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
8195 struct sockaddr_in sin;
8196 int nonlocal = 1;
8197 int port = IAX_DEFAULT_PORTNO;
8198 int sockfd = defaultsockfd;
8199 char *tmp;
8200 char *addr;
8201 char *portstr;
8203 if (!(tmp = ast_strdupa(srcaddr)))
8204 return -1;
8206 addr = strsep(&tmp, ":");
8207 portstr = tmp;
8209 if (portstr) {
8210 port = atoi(portstr);
8211 if (port < 1)
8212 port = IAX_DEFAULT_PORTNO;
8215 if (!ast_get_ip(&sin, addr)) {
8216 struct ast_netsock *sock;
8217 int res;
8219 sin.sin_port = 0;
8220 sin.sin_family = AF_INET;
8221 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
8222 if (res == 0) {
8223 /* ip address valid. */
8224 sin.sin_port = htons(port);
8225 sock = ast_netsock_find(netsock, &sin);
8226 if (sock) {
8227 sockfd = ast_netsock_sockfd(sock);
8228 nonlocal = 0;
8233 peer->sockfd = sockfd;
8235 if (nonlocal) {
8236 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
8237 srcaddr, peer->name);
8238 return -1;
8239 } else {
8240 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
8241 return 0;
8246 /*! \brief Create peer structure based on configuration */
8247 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
8249 struct iax2_peer *peer = NULL;
8250 struct ast_ha *oldha = NULL;
8251 int maskfound=0;
8252 int found=0;
8253 int firstpass=1;
8255 AST_LIST_LOCK(&peers);
8256 if (!temponly) {
8257 AST_LIST_TRAVERSE(&peers, peer, entry) {
8258 if (!strcmp(peer->name, name)) {
8259 if (!ast_test_flag(peer, IAX_DELME))
8260 firstpass = 0;
8261 break;
8264 } else
8265 peer = NULL;
8266 if (peer) {
8267 found++;
8268 if (firstpass) {
8269 oldha = peer->ha;
8270 peer->ha = NULL;
8272 AST_LIST_REMOVE(&peers, peer, entry);
8273 AST_LIST_UNLOCK(&peers);
8274 } else {
8275 AST_LIST_UNLOCK(&peers);
8276 if ((peer = ast_calloc(1, sizeof(*peer)))) {
8277 peer->expire = -1;
8278 peer->pokeexpire = -1;
8279 peer->sockfd = defaultsockfd;
8280 if (ast_string_field_init(peer, 32)) {
8281 free(peer);
8282 peer = NULL;
8286 if (peer) {
8287 if (firstpass) {
8288 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
8289 peer->encmethods = iax2_encryption;
8290 peer->adsi = adsi;
8291 ast_string_field_set(peer,secret,"");
8292 if (!found) {
8293 ast_string_field_set(peer, name, name);
8294 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
8295 peer->expiry = min_reg_expire;
8297 peer->prefs = prefs;
8298 peer->capability = iax2_capability;
8299 peer->smoothing = 0;
8300 peer->pokefreqok = DEFAULT_FREQ_OK;
8301 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
8302 ast_string_field_set(peer,context,"");
8303 ast_string_field_set(peer,peercontext,"");
8306 if (!v) {
8307 v = alt;
8308 alt = NULL;
8310 while(v) {
8311 if (!strcasecmp(v->name, "secret")) {
8312 ast_string_field_set(peer, secret, v->value);
8313 } else if (!strcasecmp(v->name, "mailbox")) {
8314 ast_string_field_set(peer, mailbox, v->value);
8315 } else if (!strcasecmp(v->name, "mohinterpret")) {
8316 ast_string_field_set(peer, mohinterpret, v->value);
8317 } else if (!strcasecmp(v->name, "mohsuggest")) {
8318 ast_string_field_set(peer, mohsuggest, v->value);
8319 } else if (!strcasecmp(v->name, "dbsecret")) {
8320 ast_string_field_set(peer, dbsecret, v->value);
8321 } else if (!strcasecmp(v->name, "trunk")) {
8322 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
8323 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
8324 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
8325 ast_clear_flag(peer, IAX_TRUNK);
8327 } else if (!strcasecmp(v->name, "auth")) {
8328 peer->authmethods = get_auth_methods(v->value);
8329 } else if (!strcasecmp(v->name, "encryption")) {
8330 peer->encmethods = get_encrypt_methods(v->value);
8331 } else if (!strcasecmp(v->name, "notransfer")) {
8332 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8333 ast_clear_flag(peer, IAX_TRANSFERMEDIA);
8334 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
8335 } else if (!strcasecmp(v->name, "transfer")) {
8336 if (!strcasecmp(v->value, "mediaonly")) {
8337 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
8338 } else if (ast_true(v->value)) {
8339 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
8340 } else
8341 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
8342 } else if (!strcasecmp(v->name, "jitterbuffer")) {
8343 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
8344 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
8345 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
8346 } else if (!strcasecmp(v->name, "host")) {
8347 if (!strcasecmp(v->value, "dynamic")) {
8348 /* They'll register with us */
8349 ast_set_flag(peer, IAX_DYNAMIC);
8350 if (!found) {
8351 /* Initialize stuff iff we're not found, otherwise
8352 we keep going with what we had */
8353 memset(&peer->addr.sin_addr, 0, 4);
8354 if (peer->addr.sin_port) {
8355 /* If we've already got a port, make it the default rather than absolute */
8356 peer->defaddr.sin_port = peer->addr.sin_port;
8357 peer->addr.sin_port = 0;
8360 } else {
8361 /* Non-dynamic. Make sure we become that way if we're not */
8362 if (peer->expire > -1)
8363 ast_sched_del(sched, peer->expire);
8364 peer->expire = -1;
8365 ast_clear_flag(peer, IAX_DYNAMIC);
8366 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
8367 ast_string_field_free_all(peer);
8368 free(peer);
8369 return NULL;
8371 if (!peer->addr.sin_port)
8372 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
8374 if (!maskfound)
8375 inet_aton("255.255.255.255", &peer->mask);
8376 } else if (!strcasecmp(v->name, "defaultip")) {
8377 if (ast_get_ip(&peer->defaddr, v->value)) {
8378 ast_string_field_free_all(peer);
8379 free(peer);
8380 return NULL;
8382 } else if (!strcasecmp(v->name, "sourceaddress")) {
8383 peer_set_srcaddr(peer, v->value);
8384 } else if (!strcasecmp(v->name, "permit") ||
8385 !strcasecmp(v->name, "deny")) {
8386 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
8387 } else if (!strcasecmp(v->name, "mask")) {
8388 maskfound++;
8389 inet_aton(v->value, &peer->mask);
8390 } else if (!strcasecmp(v->name, "context")) {
8391 if (ast_strlen_zero(peer->context))
8392 ast_string_field_set(peer, context, v->value);
8393 } else if (!strcasecmp(v->name, "regexten")) {
8394 ast_string_field_set(peer, regexten, v->value);
8395 } else if (!strcasecmp(v->name, "peercontext")) {
8396 if (ast_strlen_zero(peer->peercontext))
8397 ast_string_field_set(peer, peercontext, v->value);
8398 } else if (!strcasecmp(v->name, "port")) {
8399 if (ast_test_flag(peer, IAX_DYNAMIC))
8400 peer->defaddr.sin_port = htons(atoi(v->value));
8401 else
8402 peer->addr.sin_port = htons(atoi(v->value));
8403 } else if (!strcasecmp(v->name, "username")) {
8404 ast_string_field_set(peer, username, v->value);
8405 } else if (!strcasecmp(v->name, "allow")) {
8406 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
8407 } else if (!strcasecmp(v->name, "disallow")) {
8408 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
8409 } else if (!strcasecmp(v->name, "callerid")) {
8410 char name2[80];
8411 char num2[80];
8412 ast_callerid_split(v->value, name2, 80, num2, 80);
8413 ast_string_field_set(peer, cid_name, name2);
8414 ast_string_field_set(peer, cid_num, num2);
8415 ast_set_flag(peer, IAX_HASCALLERID);
8416 } else if (!strcasecmp(v->name, "fullname")) {
8417 ast_string_field_set(peer, cid_name, v->value);
8418 ast_set_flag(peer, IAX_HASCALLERID);
8419 } else if (!strcasecmp(v->name, "cid_number")) {
8420 ast_string_field_set(peer, cid_num, v->value);
8421 ast_set_flag(peer, IAX_HASCALLERID);
8422 } else if (!strcasecmp(v->name, "sendani")) {
8423 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
8424 } else if (!strcasecmp(v->name, "inkeys")) {
8425 ast_string_field_set(peer, inkeys, v->value);
8426 } else if (!strcasecmp(v->name, "outkey")) {
8427 ast_string_field_set(peer, outkey, v->value);
8428 } else if (!strcasecmp(v->name, "qualify")) {
8429 if (!strcasecmp(v->value, "no")) {
8430 peer->maxms = 0;
8431 } else if (!strcasecmp(v->value, "yes")) {
8432 peer->maxms = DEFAULT_MAXMS;
8433 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
8434 ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
8435 peer->maxms = 0;
8437 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
8438 peer->smoothing = ast_true(v->value);
8439 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
8440 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
8441 ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when OK should a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
8443 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
8444 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
8445 ast_log(LOG_WARNING, "Qualification testing frequency of peer '%s' when NOT OK should be a number of milliseconds at line %d of iax.conf\n", peer->name, v->lineno);
8446 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
8447 } else if (!strcasecmp(v->name, "timezone")) {
8448 ast_string_field_set(peer, zonetag, v->value);
8449 } else if (!strcasecmp(v->name, "adsi")) {
8450 peer->adsi = ast_true(v->value);
8451 }/* else if (strcasecmp(v->name,"type")) */
8452 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8453 v = v->next;
8454 if (!v) {
8455 v = alt;
8456 alt = NULL;
8459 if (!peer->authmethods)
8460 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
8461 ast_clear_flag(peer, IAX_DELME);
8462 /* Make sure these are IPv4 addresses */
8463 peer->addr.sin_family = AF_INET;
8465 if (oldha)
8466 ast_free_ha(oldha);
8467 return peer;
8470 /*! \brief Create in-memory user structure from configuration */
8471 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
8473 struct iax2_user *user = NULL;
8474 struct iax2_context *con, *conl = NULL;
8475 struct ast_ha *oldha = NULL;
8476 struct iax2_context *oldcon = NULL;
8477 int format;
8478 int firstpass=1;
8479 int oldcurauthreq = 0;
8480 char *varname = NULL, *varval = NULL;
8481 struct ast_variable *tmpvar = NULL;
8483 AST_LIST_LOCK(&users);
8484 if (!temponly) {
8485 AST_LIST_TRAVERSE(&users, user, entry) {
8486 if (!strcmp(user->name, name)) {
8487 if (!ast_test_flag(user, IAX_DELME))
8488 firstpass = 0;
8489 break;
8492 } else
8493 user = NULL;
8495 if (user) {
8496 if (firstpass) {
8497 oldcurauthreq = user->curauthreq;
8498 oldha = user->ha;
8499 oldcon = user->contexts;
8500 user->ha = NULL;
8501 user->contexts = NULL;
8503 /* Already in the list, remove it and it will be added back (or FREE'd) */
8504 AST_LIST_REMOVE(&users, user, entry);
8505 AST_LIST_UNLOCK(&users);
8506 } else {
8507 AST_LIST_UNLOCK(&users);
8508 /* This is going to memset'd to 0 in the next block */
8509 user = ast_calloc(sizeof(*user),1);
8512 if (user) {
8513 if (firstpass) {
8514 ast_string_field_free_all(user);
8515 memset(user, 0, sizeof(struct iax2_user));
8516 if (ast_string_field_init(user, 32)) {
8517 free(user);
8518 user = NULL;
8520 user->maxauthreq = maxauthreq;
8521 user->curauthreq = oldcurauthreq;
8522 user->prefs = prefs;
8523 user->capability = iax2_capability;
8524 user->encmethods = iax2_encryption;
8525 user->adsi = adsi;
8526 ast_string_field_set(user, name, name);
8527 ast_string_field_set(user, language, language);
8528 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
8530 if (!v) {
8531 v = alt;
8532 alt = NULL;
8534 while(v) {
8535 if (!strcasecmp(v->name, "context")) {
8536 con = build_context(v->value);
8537 if (con) {
8538 if (conl)
8539 conl->next = con;
8540 else
8541 user->contexts = con;
8542 conl = con;
8544 } else if (!strcasecmp(v->name, "permit") ||
8545 !strcasecmp(v->name, "deny")) {
8546 user->ha = ast_append_ha(v->name, v->value, user->ha);
8547 } else if (!strcasecmp(v->name, "setvar")) {
8548 varname = ast_strdupa(v->value);
8549 if (varname && (varval = strchr(varname,'='))) {
8550 *varval = '\0';
8551 varval++;
8552 if((tmpvar = ast_variable_new(varname, varval))) {
8553 tmpvar->next = user->vars;
8554 user->vars = tmpvar;
8557 } else if (!strcasecmp(v->name, "allow")) {
8558 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
8559 } else if (!strcasecmp(v->name, "disallow")) {
8560 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
8561 } else if (!strcasecmp(v->name, "trunk")) {
8562 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
8563 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
8564 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
8565 ast_clear_flag(user, IAX_TRUNK);
8567 } else if (!strcasecmp(v->name, "auth")) {
8568 user->authmethods = get_auth_methods(v->value);
8569 } else if (!strcasecmp(v->name, "encryption")) {
8570 user->encmethods = get_encrypt_methods(v->value);
8571 } else if (!strcasecmp(v->name, "notransfer")) {
8572 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8573 ast_clear_flag(user, IAX_TRANSFERMEDIA);
8574 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
8575 } else if (!strcasecmp(v->name, "transfer")) {
8576 if (!strcasecmp(v->value, "mediaonly")) {
8577 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
8578 } else if (ast_true(v->value)) {
8579 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
8580 } else
8581 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
8582 } else if (!strcasecmp(v->name, "codecpriority")) {
8583 if(!strcasecmp(v->value, "caller"))
8584 ast_set_flag(user, IAX_CODEC_USER_FIRST);
8585 else if(!strcasecmp(v->value, "disabled"))
8586 ast_set_flag(user, IAX_CODEC_NOPREFS);
8587 else if(!strcasecmp(v->value, "reqonly")) {
8588 ast_set_flag(user, IAX_CODEC_NOCAP);
8589 ast_set_flag(user, IAX_CODEC_NOPREFS);
8591 } else if (!strcasecmp(v->name, "jitterbuffer")) {
8592 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
8593 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
8594 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
8595 } else if (!strcasecmp(v->name, "dbsecret")) {
8596 ast_string_field_set(user, dbsecret, v->value);
8597 } else if (!strcasecmp(v->name, "secret")) {
8598 if (!ast_strlen_zero(user->secret)) {
8599 char buf99[100];
8600 strncpy(buf99,user->secret,100); /* just in case some weirdness happens in the string_field_build */
8601 ast_string_field_build(user,secret,"%s;%s",buf99,v->value);
8602 /* strncpy(user->secret + strlen(user->secret), ";", sizeof(user->secret) - strlen(user->secret) - 1);
8603 strncpy(user->secret + strlen(user->secret), v->value, sizeof(user->secret) - strlen(user->secret) - 1); */
8604 } else
8605 ast_string_field_set(user, secret, v->value);
8606 } else if (!strcasecmp(v->name, "callerid")) {
8607 char name2[80];
8608 char num2[80];
8609 ast_callerid_split(v->value, name2, 80, num2, 80);
8610 ast_string_field_set(user, cid_name, name2);
8611 ast_string_field_set(user, cid_num, num2);
8612 ast_set_flag(user, IAX_HASCALLERID);
8613 } else if (!strcasecmp(v->name, "fullname")) {
8614 ast_string_field_set(user, cid_name, v->value);
8615 ast_set_flag(user, IAX_HASCALLERID);
8616 } else if (!strcasecmp(v->name, "cid_number")) {
8617 ast_string_field_set(user, cid_num, v->value);
8618 ast_set_flag(user, IAX_HASCALLERID);
8619 } else if (!strcasecmp(v->name, "accountcode")) {
8620 ast_string_field_set(user, accountcode, v->value);
8621 } else if (!strcasecmp(v->name, "mohinterpret")) {
8622 ast_string_field_set(user, mohinterpret, v->value);
8623 } else if (!strcasecmp(v->name, "mohsuggest")) {
8624 ast_string_field_set(user, mohsuggest, v->value);
8625 } else if (!strcasecmp(v->name, "language")) {
8626 ast_string_field_set(user, language, v->value);
8627 } else if (!strcasecmp(v->name, "amaflags")) {
8628 format = ast_cdr_amaflags2int(v->value);
8629 if (format < 0) {
8630 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
8631 } else {
8632 user->amaflags = format;
8634 } else if (!strcasecmp(v->name, "inkeys")) {
8635 ast_string_field_set(user, inkeys, v->value);
8636 } else if (!strcasecmp(v->name, "maxauthreq")) {
8637 user->maxauthreq = atoi(v->value);
8638 if (user->maxauthreq < 0)
8639 user->maxauthreq = 0;
8640 } else if (!strcasecmp(v->name, "adsi")) {
8641 user->adsi = ast_true(v->value);
8642 }/* else if (strcasecmp(v->name,"type")) */
8643 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
8644 v = v->next;
8645 if (!v) {
8646 v = alt;
8647 alt = NULL;
8650 if (!user->authmethods) {
8651 if (!ast_strlen_zero(user->secret)) {
8652 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
8653 if (!ast_strlen_zero(user->inkeys))
8654 user->authmethods |= IAX_AUTH_RSA;
8655 } else if (!ast_strlen_zero(user->inkeys)) {
8656 user->authmethods = IAX_AUTH_RSA;
8657 } else {
8658 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
8661 ast_clear_flag(user, IAX_DELME);
8663 if (oldha)
8664 ast_free_ha(oldha);
8665 if (oldcon)
8666 free_context(oldcon);
8667 return user;
8670 static void delete_users(void)
8672 struct iax2_user *user = NULL;
8673 struct iax2_peer *peer = NULL;
8674 struct iax2_registry *reg, *regl;
8676 AST_LIST_LOCK(&users);
8677 AST_LIST_TRAVERSE(&users, user, entry)
8678 ast_set_flag(user, IAX_DELME);
8679 AST_LIST_UNLOCK(&users);
8681 for (reg = registrations;reg;) {
8682 regl = reg;
8683 reg = reg->next;
8684 if (regl->expire > -1) {
8685 ast_sched_del(sched, regl->expire);
8687 if (regl->callno) {
8688 /* XXX Is this a potential lock? I don't think so, but you never know */
8689 ast_mutex_lock(&iaxsl[regl->callno]);
8690 if (iaxs[regl->callno]) {
8691 iaxs[regl->callno]->reg = NULL;
8692 iax2_destroy_nolock(regl->callno);
8694 ast_mutex_unlock(&iaxsl[regl->callno]);
8696 if (regl->dnsmgr)
8697 ast_dnsmgr_release(regl->dnsmgr);
8698 free(regl);
8700 registrations = NULL;
8702 AST_LIST_LOCK(&peers);
8703 AST_LIST_TRAVERSE(&peers, peer, entry)
8704 ast_set_flag(peer, IAX_DELME);
8705 AST_LIST_UNLOCK(&peers);
8708 static void destroy_user(struct iax2_user *user)
8710 ast_free_ha(user->ha);
8711 free_context(user->contexts);
8712 if(user->vars) {
8713 ast_variables_destroy(user->vars);
8714 user->vars = NULL;
8716 ast_string_field_free_all(user);
8717 free(user);
8720 static void prune_users(void)
8722 struct iax2_user *user = NULL;
8724 AST_LIST_LOCK(&users);
8725 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, entry) {
8726 if (ast_test_flag(user, IAX_DELME)) {
8727 destroy_user(user);
8728 AST_LIST_REMOVE_CURRENT(&users, entry);
8731 AST_LIST_TRAVERSE_SAFE_END
8732 AST_LIST_UNLOCK(&users);
8736 static void destroy_peer(struct iax2_peer *peer)
8738 int x;
8739 ast_free_ha(peer->ha);
8740 for (x=0;x<IAX_MAX_CALLS;x++) {
8741 ast_mutex_lock(&iaxsl[x]);
8742 if (iaxs[x] && (iaxs[x]->peerpoke == peer)) {
8743 iax2_destroy(x);
8745 ast_mutex_unlock(&iaxsl[x]);
8747 /* Delete it, it needs to disappear */
8748 if (peer->expire > -1)
8749 ast_sched_del(sched, peer->expire);
8750 if (peer->pokeexpire > -1)
8751 ast_sched_del(sched, peer->pokeexpire);
8752 if (peer->callno > 0)
8753 iax2_destroy(peer->callno);
8754 register_peer_exten(peer, 0);
8755 if (peer->dnsmgr)
8756 ast_dnsmgr_release(peer->dnsmgr);
8757 ast_string_field_free_all(peer);
8758 free(peer);
8761 static void prune_peers(void){
8762 /* Prune peers who still are supposed to be deleted */
8763 struct iax2_peer *peer = NULL;
8765 AST_LIST_LOCK(&peers);
8766 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) {
8767 if (ast_test_flag(peer, IAX_DELME)) {
8768 destroy_peer(peer);
8769 AST_LIST_REMOVE_CURRENT(&peers, entry);
8772 AST_LIST_TRAVERSE_SAFE_END
8773 AST_LIST_UNLOCK(&peers);
8776 static void set_timing(void)
8778 #ifdef HAVE_ZAPTEL
8779 int bs = trunkfreq * 8;
8780 if (timingfd > -1) {
8781 if (
8782 #ifdef ZT_TIMERACK
8783 ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
8784 #endif
8785 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
8786 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
8788 #endif
8792 /*! \brief Load configuration */
8793 static int set_config(char *config_file, int reload)
8795 struct ast_config *cfg, *ucfg;
8796 int capability=iax2_capability;
8797 struct ast_variable *v;
8798 char *cat;
8799 char *utype;
8800 char *tosval;
8801 int format;
8802 int portno = IAX_DEFAULT_PORTNO;
8803 int x;
8804 struct iax2_user *user;
8805 struct iax2_peer *peer;
8806 struct ast_netsock *ns;
8807 #if 0
8808 static unsigned short int last_port=0;
8809 #endif
8811 cfg = ast_config_load(config_file);
8813 if (!cfg) {
8814 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
8815 return -1;
8818 /* Reset global codec prefs */
8819 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
8821 /* Reset Global Flags */
8822 memset(&globalflags, 0, sizeof(globalflags));
8823 ast_set_flag(&globalflags, IAX_RTUPDATE);
8825 #ifdef SO_NO_CHECK
8826 nochecksums = 0;
8827 #endif
8829 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
8830 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
8832 maxauthreq = 3;
8834 v = ast_variable_browse(cfg, "general");
8836 /* Seed initial tos value */
8837 tosval = ast_variable_retrieve(cfg, "general", "tos");
8838 if (tosval) {
8839 if (ast_str2tos(tosval, &tos))
8840 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
8842 while(v) {
8843 if (!strcasecmp(v->name, "bindport")){
8844 if (reload)
8845 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
8846 else
8847 portno = atoi(v->value);
8848 } else if (!strcasecmp(v->name, "pingtime"))
8849 ping_time = atoi(v->value);
8850 else if (!strcasecmp(v->name, "iaxthreadcount")) {
8851 if (reload) {
8852 if (atoi(v->value) != iaxthreadcount)
8853 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
8854 } else {
8855 iaxthreadcount = atoi(v->value);
8856 if (iaxthreadcount < 1) {
8857 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
8858 iaxthreadcount = 1;
8859 } else if (iaxthreadcount > 256) {
8860 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
8861 iaxthreadcount = 256;
8864 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
8865 if (reload) {
8866 AST_LIST_LOCK(&dynamic_list);
8867 iaxmaxthreadcount = atoi(v->value);
8868 AST_LIST_UNLOCK(&dynamic_list);
8869 } else {
8870 iaxmaxthreadcount = atoi(v->value);
8871 if (iaxmaxthreadcount < 0) {
8872 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
8873 iaxmaxthreadcount = 0;
8874 } else if (iaxmaxthreadcount > 256) {
8875 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
8876 iaxmaxthreadcount = 256;
8879 } else if (!strcasecmp(v->name, "nochecksums")) {
8880 #ifdef SO_NO_CHECK
8881 if (ast_true(v->value))
8882 nochecksums = 1;
8883 else
8884 nochecksums = 0;
8885 #else
8886 if (ast_true(v->value))
8887 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
8888 #endif
8890 else if (!strcasecmp(v->name, "maxjitterbuffer"))
8891 maxjitterbuffer = atoi(v->value);
8892 else if (!strcasecmp(v->name, "resyncthreshold"))
8893 resyncthreshold = atoi(v->value);
8894 else if (!strcasecmp(v->name, "maxjitterinterps"))
8895 maxjitterinterps = atoi(v->value);
8896 else if (!strcasecmp(v->name, "lagrqtime"))
8897 lagrq_time = atoi(v->value);
8898 else if (!strcasecmp(v->name, "maxregexpire"))
8899 max_reg_expire = atoi(v->value);
8900 else if (!strcasecmp(v->name, "minregexpire"))
8901 min_reg_expire = atoi(v->value);
8902 else if (!strcasecmp(v->name, "bindaddr")) {
8903 if (reload) {
8904 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
8905 } else {
8906 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
8907 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
8908 } else {
8909 if (option_verbose > 1) {
8910 if (strchr(v->value, ':'))
8911 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
8912 else
8913 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
8915 if (defaultsockfd < 0)
8916 defaultsockfd = ast_netsock_sockfd(ns);
8917 ast_netsock_unref(ns);
8920 } else if (!strcasecmp(v->name, "authdebug"))
8921 authdebug = ast_true(v->value);
8922 else if (!strcasecmp(v->name, "encryption"))
8923 iax2_encryption = get_encrypt_methods(v->value);
8924 else if (!strcasecmp(v->name, "notransfer")) {
8925 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
8926 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
8927 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
8928 } else if (!strcasecmp(v->name, "transfer")) {
8929 if (!strcasecmp(v->value, "mediaonly")) {
8930 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
8931 } else if (ast_true(v->value)) {
8932 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
8933 } else
8934 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
8935 } else if (!strcasecmp(v->name, "codecpriority")) {
8936 if(!strcasecmp(v->value, "caller"))
8937 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
8938 else if(!strcasecmp(v->value, "disabled"))
8939 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
8940 else if(!strcasecmp(v->value, "reqonly")) {
8941 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
8942 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
8944 } else if (!strcasecmp(v->name, "jitterbuffer"))
8945 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
8946 else if (!strcasecmp(v->name, "forcejitterbuffer"))
8947 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
8948 else if (!strcasecmp(v->name, "delayreject"))
8949 delayreject = ast_true(v->value);
8950 else if (!strcasecmp(v->name, "rtcachefriends"))
8951 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
8952 else if (!strcasecmp(v->name, "rtignoreregexpire"))
8953 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
8954 else if (!strcasecmp(v->name, "rtupdate"))
8955 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
8956 else if (!strcasecmp(v->name, "trunktimestamps"))
8957 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
8958 else if (!strcasecmp(v->name, "rtautoclear")) {
8959 int i = atoi(v->value);
8960 if(i > 0)
8961 global_rtautoclear = i;
8962 else
8963 i = 0;
8964 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
8965 } else if (!strcasecmp(v->name, "trunkfreq")) {
8966 trunkfreq = atoi(v->value);
8967 if (trunkfreq < 10)
8968 trunkfreq = 10;
8969 } else if (!strcasecmp(v->name, "autokill")) {
8970 if (sscanf(v->value, "%d", &x) == 1) {
8971 if (x >= 0)
8972 autokill = x;
8973 else
8974 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
8975 } else if (ast_true(v->value)) {
8976 autokill = DEFAULT_MAXMS;
8977 } else {
8978 autokill = 0;
8980 } else if (!strcasecmp(v->name, "bandwidth")) {
8981 if (!strcasecmp(v->value, "low")) {
8982 capability = IAX_CAPABILITY_LOWBANDWIDTH;
8983 } else if (!strcasecmp(v->value, "medium")) {
8984 capability = IAX_CAPABILITY_MEDBANDWIDTH;
8985 } else if (!strcasecmp(v->value, "high")) {
8986 capability = IAX_CAPABILITY_FULLBANDWIDTH;
8987 } else
8988 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
8989 } else if (!strcasecmp(v->name, "allow")) {
8990 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
8991 } else if (!strcasecmp(v->name, "disallow")) {
8992 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
8993 } else if (!strcasecmp(v->name, "register")) {
8994 iax2_register(v->value, v->lineno);
8995 } else if (!strcasecmp(v->name, "iaxcompat")) {
8996 iaxcompat = ast_true(v->value);
8997 } else if (!strcasecmp(v->name, "regcontext")) {
8998 ast_copy_string(regcontext, v->value, sizeof(regcontext));
8999 /* Create context if it doesn't exist already */
9000 if (!ast_context_find(regcontext))
9001 ast_context_create(NULL, regcontext, "IAX2");
9002 } else if (!strcasecmp(v->name, "tos")) {
9003 if (ast_str2tos(v->value, &tos))
9004 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
9005 } else if (!strcasecmp(v->name, "accountcode")) {
9006 ast_copy_string(accountcode, v->value, sizeof(accountcode));
9007 } else if (!strcasecmp(v->name, "mohinterpret")) {
9008 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
9009 } else if (!strcasecmp(v->name, "mohsuggest")) {
9010 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
9011 } else if (!strcasecmp(v->name, "amaflags")) {
9012 format = ast_cdr_amaflags2int(v->value);
9013 if (format < 0) {
9014 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
9015 } else {
9016 amaflags = format;
9018 } else if (!strcasecmp(v->name, "language")) {
9019 ast_copy_string(language, v->value, sizeof(language));
9020 } else if (!strcasecmp(v->name, "maxauthreq")) {
9021 maxauthreq = atoi(v->value);
9022 if (maxauthreq < 0)
9023 maxauthreq = 0;
9024 } else if (!strcasecmp(v->name, "adsi")) {
9025 adsi = ast_true(v->value);
9026 } /*else if (strcasecmp(v->name,"type")) */
9027 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
9028 v = v->next;
9031 if (defaultsockfd < 0) {
9032 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
9033 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
9034 } else {
9035 if (option_verbose > 1)
9036 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
9037 defaultsockfd = ast_netsock_sockfd(ns);
9038 ast_netsock_unref(ns);
9042 if (min_reg_expire > max_reg_expire) {
9043 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
9044 min_reg_expire, max_reg_expire, max_reg_expire);
9045 min_reg_expire = max_reg_expire;
9047 iax2_capability = capability;
9049 ucfg = ast_config_load("users.conf");
9050 if (ucfg) {
9051 struct ast_variable *gen;
9052 int genhasiax;
9053 int genregisteriax;
9054 char *hasiax, *registeriax;
9056 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
9057 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
9058 gen = ast_variable_browse(ucfg, "general");
9059 cat = ast_category_browse(ucfg, NULL);
9060 while (cat) {
9061 if (strcasecmp(cat, "general")) {
9062 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
9063 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
9064 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
9065 /* Start with general parameters, then specific parameters, user and peer */
9066 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
9067 if (user) {
9068 AST_LIST_LOCK(&users);
9069 AST_LIST_INSERT_HEAD(&users, user, entry);
9070 AST_LIST_UNLOCK(&users);
9072 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
9073 if (peer) {
9074 AST_LIST_LOCK(&peers);
9075 AST_LIST_INSERT_HEAD(&peers, peer, entry);
9076 AST_LIST_UNLOCK(&peers);
9077 if (ast_test_flag(peer, IAX_DYNAMIC))
9078 reg_source_db(peer);
9081 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
9082 char tmp[256];
9083 char *host = ast_variable_retrieve(ucfg, cat, "host");
9084 char *username = ast_variable_retrieve(ucfg, cat, "username");
9085 char *secret = ast_variable_retrieve(ucfg, cat, "secret");
9086 if (!host)
9087 host = ast_variable_retrieve(ucfg, "general", "host");
9088 if (!username)
9089 username = ast_variable_retrieve(ucfg, "general", "username");
9090 if (!secret)
9091 secret = ast_variable_retrieve(ucfg, "general", "secret");
9092 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
9093 if (!ast_strlen_zero(secret))
9094 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
9095 else
9096 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
9097 iax2_register(tmp, 0);
9101 cat = ast_category_browse(ucfg, cat);
9103 ast_config_destroy(ucfg);
9106 cat = ast_category_browse(cfg, NULL);
9107 while(cat) {
9108 if (strcasecmp(cat, "general")) {
9109 utype = ast_variable_retrieve(cfg, cat, "type");
9110 if (utype) {
9111 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
9112 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
9113 if (user) {
9114 AST_LIST_LOCK(&users);
9115 AST_LIST_INSERT_HEAD(&users, user, entry);
9116 AST_LIST_UNLOCK(&users);
9119 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
9120 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
9121 if (peer) {
9122 AST_LIST_LOCK(&peers);
9123 AST_LIST_INSERT_HEAD(&peers, peer, entry);
9124 AST_LIST_UNLOCK(&peers);
9125 if (ast_test_flag(peer, IAX_DYNAMIC))
9126 reg_source_db(peer);
9128 } else if (strcasecmp(utype, "user")) {
9129 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
9131 } else
9132 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
9134 cat = ast_category_browse(cfg, cat);
9136 ast_config_destroy(cfg);
9137 set_timing();
9138 return capability;
9141 static int reload_config(void)
9143 char *config = "iax.conf";
9144 struct iax2_registry *reg;
9145 struct iax2_peer *peer = NULL;
9147 strcpy(accountcode, "");
9148 strcpy(language, "");
9149 strcpy(mohinterpret, "default");
9150 strcpy(mohsuggest, "");
9151 amaflags = 0;
9152 delayreject = 0;
9153 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
9154 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
9155 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
9156 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
9157 delete_users();
9158 set_config(config,1);
9159 prune_peers();
9160 prune_users();
9161 for (reg = registrations; reg; reg = reg->next)
9162 iax2_do_register(reg);
9163 /* Qualify hosts, too */
9164 AST_LIST_LOCK(&peers);
9165 AST_LIST_TRAVERSE(&peers, peer, entry)
9166 iax2_poke_peer(peer, 0);
9167 AST_LIST_UNLOCK(&peers);
9168 reload_firmware();
9169 iax_provision_reload();
9171 return 0;
9174 static int iax2_reload(int fd, int argc, char *argv[])
9176 return reload_config();
9179 static int reload(void)
9181 return reload_config();
9184 static int cache_get_callno_locked(const char *data)
9186 struct sockaddr_in sin;
9187 int x;
9188 int callno;
9189 struct iax_ie_data ied;
9190 struct create_addr_info cai;
9191 struct parsed_dial_string pds;
9192 char *tmpstr;
9194 for (x=0; x<IAX_MAX_CALLS; x++) {
9195 /* Look for an *exact match* call. Once a call is negotiated, it can only
9196 look up entries for a single context */
9197 if (!ast_mutex_trylock(&iaxsl[x])) {
9198 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
9199 return x;
9200 ast_mutex_unlock(&iaxsl[x]);
9204 /* No match found, we need to create a new one */
9206 memset(&cai, 0, sizeof(cai));
9207 memset(&ied, 0, sizeof(ied));
9208 memset(&pds, 0, sizeof(pds));
9210 tmpstr = ast_strdupa(data);
9211 parse_dial_string(tmpstr, &pds);
9213 /* Populate our address from the given */
9214 if (create_addr(pds.peer, &sin, &cai))
9215 return -1;
9217 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
9218 pds.peer, pds.username, pds.password, pds.context);
9220 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
9221 if (callno < 1) {
9222 ast_log(LOG_WARNING, "Unable to create call\n");
9223 return -1;
9226 ast_mutex_lock(&iaxsl[callno]);
9227 ast_string_field_set(iaxs[callno], dproot, data);
9228 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
9230 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
9231 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
9232 /* the string format is slightly different from a standard dial string,
9233 because the context appears in the 'exten' position
9235 if (pds.exten)
9236 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
9237 if (pds.username)
9238 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
9239 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
9240 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
9241 /* Keep password handy */
9242 if (pds.password)
9243 ast_string_field_set(iaxs[callno], secret, pds.password);
9244 if (pds.key)
9245 ast_string_field_set(iaxs[callno], outkey, pds.key);
9246 /* Start the call going */
9247 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
9249 return callno;
9252 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
9254 struct iax2_dpcache *dp, *prev = NULL, *next;
9255 struct timeval tv;
9256 int x;
9257 int com[2];
9258 int timeout;
9259 int old=0;
9260 int outfd;
9261 int abort;
9262 int callno;
9263 struct ast_channel *c;
9264 struct ast_frame *f;
9265 gettimeofday(&tv, NULL);
9266 dp = dpcache;
9267 while(dp) {
9268 next = dp->next;
9269 /* Expire old caches */
9270 if (ast_tvcmp(tv, dp->expiry) > 0) {
9271 /* It's expired, let it disappear */
9272 if (prev)
9273 prev->next = dp->next;
9274 else
9275 dpcache = dp->next;
9276 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
9277 /* Free memory and go again */
9278 free(dp);
9279 } else {
9280 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
9282 dp = next;
9283 continue;
9285 /* We found an entry that matches us! */
9286 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
9287 break;
9288 prev = dp;
9289 dp = next;
9291 if (!dp) {
9292 /* No matching entry. Create a new one. */
9293 /* First, can we make a callno? */
9294 callno = cache_get_callno_locked(data);
9295 if (callno < 0) {
9296 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
9297 return NULL;
9299 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
9300 ast_mutex_unlock(&iaxsl[callno]);
9301 return NULL;
9303 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
9304 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
9305 gettimeofday(&dp->expiry, NULL);
9306 dp->orig = dp->expiry;
9307 /* Expires in 30 mins by default */
9308 dp->expiry.tv_sec += iaxdefaultdpcache;
9309 dp->next = dpcache;
9310 dp->flags = CACHE_FLAG_PENDING;
9311 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
9312 dp->waiters[x] = -1;
9313 dpcache = dp;
9314 dp->peer = iaxs[callno]->dpentries;
9315 iaxs[callno]->dpentries = dp;
9316 /* Send the request if we're already up */
9317 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
9318 iax2_dprequest(dp, callno);
9319 ast_mutex_unlock(&iaxsl[callno]);
9321 /* By here we must have a dp */
9322 if (dp->flags & CACHE_FLAG_PENDING) {
9323 /* Okay, here it starts to get nasty. We need a pipe now to wait
9324 for a reply to come back so long as it's pending */
9325 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
9326 /* Find an empty slot */
9327 if (dp->waiters[x] < 0)
9328 break;
9330 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
9331 ast_log(LOG_WARNING, "No more waiter positions available\n");
9332 return NULL;
9334 if (pipe(com)) {
9335 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
9336 return NULL;
9338 dp->waiters[x] = com[1];
9339 /* Okay, now we wait */
9340 timeout = iaxdefaulttimeout * 1000;
9341 /* Temporarily unlock */
9342 ast_mutex_unlock(&dpcache_lock);
9343 /* Defer any dtmf */
9344 if (chan)
9345 old = ast_channel_defer_dtmf(chan);
9346 abort = 0;
9347 while(timeout) {
9348 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
9349 if (outfd > -1) {
9350 break;
9352 if (c) {
9353 f = ast_read(c);
9354 if (f)
9355 ast_frfree(f);
9356 else {
9357 /* Got hung up on, abort! */
9358 break;
9359 abort = 1;
9363 if (!timeout) {
9364 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
9366 ast_mutex_lock(&dpcache_lock);
9367 dp->waiters[x] = -1;
9368 close(com[1]);
9369 close(com[0]);
9370 if (abort) {
9371 /* Don't interpret anything, just abort. Not sure what th epoint
9372 of undeferring dtmf on a hung up channel is but hey whatever */
9373 if (!old && chan)
9374 ast_channel_undefer_dtmf(chan);
9375 return NULL;
9377 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
9378 /* Now to do non-independent analysis the results of our wait */
9379 if (dp->flags & CACHE_FLAG_PENDING) {
9380 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer
9381 pending. Don't let it take as long to timeout. */
9382 dp->flags &= ~CACHE_FLAG_PENDING;
9383 dp->flags |= CACHE_FLAG_TIMEOUT;
9384 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded
9385 systems without leaving it unavailable once the server comes back online */
9386 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
9387 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
9388 if (dp->waiters[x] > -1)
9389 write(dp->waiters[x], "asdf", 4);
9392 /* Our caller will obtain the rest */
9393 if (!old && chan)
9394 ast_channel_undefer_dtmf(chan);
9396 return dp;
9399 /*! \brief Part of the IAX2 switch interface */
9400 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
9402 struct iax2_dpcache *dp;
9403 int res = 0;
9404 #if 0
9405 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
9406 #endif
9407 if ((priority != 1) && (priority != 2))
9408 return 0;
9409 ast_mutex_lock(&dpcache_lock);
9410 dp = find_cache(chan, data, context, exten, priority);
9411 if (dp) {
9412 if (dp->flags & CACHE_FLAG_EXISTS)
9413 res= 1;
9415 ast_mutex_unlock(&dpcache_lock);
9416 if (!dp) {
9417 ast_log(LOG_WARNING, "Unable to make DP cache\n");
9419 return res;
9422 /*! \brief part of the IAX2 dial plan switch interface */
9423 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
9425 int res = 0;
9426 struct iax2_dpcache *dp;
9427 #if 0
9428 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
9429 #endif
9430 if ((priority != 1) && (priority != 2))
9431 return 0;
9432 ast_mutex_lock(&dpcache_lock);
9433 dp = find_cache(chan, data, context, exten, priority);
9434 if (dp) {
9435 if (dp->flags & CACHE_FLAG_CANEXIST)
9436 res= 1;
9438 ast_mutex_unlock(&dpcache_lock);
9439 if (!dp) {
9440 ast_log(LOG_WARNING, "Unable to make DP cache\n");
9442 return res;
9445 /*! \brief Part of the IAX2 Switch interface */
9446 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
9448 int res = 0;
9449 struct iax2_dpcache *dp;
9450 #if 0
9451 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
9452 #endif
9453 if ((priority != 1) && (priority != 2))
9454 return 0;
9455 ast_mutex_lock(&dpcache_lock);
9456 dp = find_cache(chan, data, context, exten, priority);
9457 if (dp) {
9458 if (dp->flags & CACHE_FLAG_MATCHMORE)
9459 res= 1;
9461 ast_mutex_unlock(&dpcache_lock);
9462 if (!dp) {
9463 ast_log(LOG_WARNING, "Unable to make DP cache\n");
9465 return res;
9468 /*! \brief Execute IAX2 dialplan switch */
9469 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
9471 char odata[256];
9472 char req[256];
9473 char *ncontext;
9474 struct iax2_dpcache *dp;
9475 struct ast_app *dial;
9476 #if 0
9477 ast_log(LOG_NOTICE, "iax2_exec: con: %s, exten: %s, pri: %d, cid: %s, data: %s, newstack: %d\n", context, exten, priority, callerid ? callerid : "<unknown>", data, newstack);
9478 #endif
9479 if (priority == 2) {
9480 /* Indicate status, can be overridden in dialplan */
9481 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
9482 if (dialstatus) {
9483 dial = pbx_findapp(dialstatus);
9484 if (dial)
9485 pbx_exec(chan, dial, "");
9487 return -1;
9488 } else if (priority != 1)
9489 return -1;
9490 ast_mutex_lock(&dpcache_lock);
9491 dp = find_cache(chan, data, context, exten, priority);
9492 if (dp) {
9493 if (dp->flags & CACHE_FLAG_EXISTS) {
9494 ast_copy_string(odata, data, sizeof(odata));
9495 ncontext = strchr(odata, '/');
9496 if (ncontext) {
9497 *ncontext = '\0';
9498 ncontext++;
9499 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
9500 } else {
9501 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
9503 if (option_verbose > 2)
9504 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
9505 } else {
9506 ast_mutex_unlock(&dpcache_lock);
9507 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
9508 return -1;
9511 ast_mutex_unlock(&dpcache_lock);
9512 dial = pbx_findapp("Dial");
9513 if (dial) {
9514 return pbx_exec(chan, dial, req);
9515 } else {
9516 ast_log(LOG_WARNING, "No dial application registered\n");
9518 return -1;
9521 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
9523 struct iax2_peer *peer;
9524 char *peername, *colname;
9526 if (!(peername = ast_strdupa(data)))
9527 return -1;
9529 /* if our channel, return the IP address of the endpoint of current channel */
9530 if (!strcmp(peername,"CURRENTCHANNEL")) {
9531 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
9532 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
9533 return 0;
9536 if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
9537 *colname++ = '\0';
9538 else if ((colname = strchr(peername, '|')))
9539 *colname++ = '\0';
9540 else
9541 colname = "ip";
9543 if (!(peer = find_peer(peername, 1)))
9544 return -1;
9546 if (!strcasecmp(colname, "ip")) {
9547 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
9548 } else if (!strcasecmp(colname, "status")) {
9549 peer_status(peer, buf, len);
9550 } else if (!strcasecmp(colname, "mailbox")) {
9551 ast_copy_string(buf, peer->mailbox, len);
9552 } else if (!strcasecmp(colname, "context")) {
9553 ast_copy_string(buf, peer->context, len);
9554 } else if (!strcasecmp(colname, "expire")) {
9555 snprintf(buf, len, "%d", peer->expire);
9556 } else if (!strcasecmp(colname, "dynamic")) {
9557 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
9558 } else if (!strcasecmp(colname, "callerid_name")) {
9559 ast_copy_string(buf, peer->cid_name, len);
9560 } else if (!strcasecmp(colname, "callerid_num")) {
9561 ast_copy_string(buf, peer->cid_num, len);
9562 } else if (!strcasecmp(colname, "codecs")) {
9563 ast_getformatname_multiple(buf, len -1, peer->capability);
9564 } else if (!strncasecmp(colname, "codec[", 6)) {
9565 char *codecnum, *ptr;
9566 int index = 0, codec = 0;
9568 codecnum = strchr(colname, '[');
9569 *codecnum = '\0';
9570 codecnum++;
9571 if ((ptr = strchr(codecnum, ']'))) {
9572 *ptr = '\0';
9574 index = atoi(codecnum);
9575 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
9576 ast_copy_string(buf, ast_getformatname(codec), len);
9580 return 0;
9583 struct ast_custom_function iaxpeer_function = {
9584 .name = "IAXPEER",
9585 .synopsis = "Gets IAX peer information",
9586 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
9587 .read = function_iaxpeer,
9588 .desc = "If peername specified, valid items are:\n"
9589 "- ip (default) The IP address.\n"
9590 "- status The peer's status (if qualify=yes)\n"
9591 "- mailbox The configured mailbox.\n"
9592 "- context The configured context.\n"
9593 "- expire The epoch time of the next expire.\n"
9594 "- dynamic Is it dynamic? (yes/no).\n"
9595 "- callerid_name The configured Caller ID name.\n"
9596 "- callerid_num The configured Caller ID number.\n"
9597 "- codecs The configured codecs.\n"
9598 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
9599 "\n"
9600 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
9601 "\n"
9605 /*! \brief Part of the device state notification system ---*/
9606 static int iax2_devicestate(void *data)
9608 struct parsed_dial_string pds;
9609 char *tmp = ast_strdupa(data);
9610 struct iax2_peer *p;
9611 int res = AST_DEVICE_INVALID;
9613 memset(&pds, 0, sizeof(pds));
9614 parse_dial_string(tmp, &pds);
9615 if (ast_strlen_zero(pds.peer))
9616 return res;
9618 if (option_debug > 2)
9619 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
9621 /* SLD: FIXME: second call to find_peer during registration */
9622 if (!(p = find_peer(pds.peer, 1)))
9623 return res;
9625 res = AST_DEVICE_UNAVAILABLE;
9626 if (option_debug > 2)
9627 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
9628 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
9630 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
9631 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
9632 /* Peer is registered, or have default IP address
9633 and a valid registration */
9634 if (p->historicms == 0 || p->historicms <= p->maxms)
9635 /* let the core figure out whether it is in use or not */
9636 res = AST_DEVICE_UNKNOWN;
9639 if (ast_test_flag(p, IAX_TEMPONLY))
9640 destroy_peer(p);
9642 return res;
9645 static struct ast_switch iax2_switch =
9647 name: "IAX2",
9648 description: "IAX Remote Dialplan Switch",
9649 exists: iax2_exists,
9650 canmatch: iax2_canmatch,
9651 exec: iax2_exec,
9652 matchmore: iax2_matchmore,
9655 static char show_stats_usage[] =
9656 "Usage: iax2 list stats\n"
9657 " Display statistics on IAX channel driver.\n";
9659 static char show_cache_usage[] =
9660 "Usage: iax2 list cache\n"
9661 " Display currently cached IAX Dialplan results.\n";
9663 static char show_peer_usage[] =
9664 "Usage: iax2 show peer <name>\n"
9665 " Display details on specific IAX peer\n";
9667 static char prune_realtime_usage[] =
9668 "Usage: iax2 prune realtime [<peername>|all]\n"
9669 " Prunes object(s) from the cache\n";
9671 static char iax2_reload_usage[] =
9672 "Usage: iax2 reload\n"
9673 " Reloads IAX configuration from iax.conf\n";
9675 static char show_prov_usage[] =
9676 "Usage: iax2 provision <host> <template> [forced]\n"
9677 " Provisions the given peer or IP address using a template\n"
9678 " matching either 'template' or '*' if the template is not\n"
9679 " found. If 'forced' is specified, even empty provisioning\n"
9680 " fields will be provisioned as empty fields.\n";
9682 static char show_users_usage[] =
9683 "Usage: iax2 list users [like <pattern>]\n"
9684 " Lists all known IAX2 users.\n"
9685 " Optional regular expression pattern is used to filter the user list.\n";
9687 static char show_channels_usage[] =
9688 "Usage: iax2 list channels\n"
9689 " Lists all currently active IAX channels.\n";
9691 static char show_netstats_usage[] =
9692 "Usage: iax2 list netstats\n"
9693 " Lists network status for all currently active IAX channels.\n";
9695 static char show_threads_usage[] =
9696 "Usage: iax2 list threads\n"
9697 " Lists status of IAX helper threads\n";
9699 static char show_peers_usage[] =
9700 "Usage: iax2 list peers [registered] [like <pattern>]\n"
9701 " Lists all known IAX2 peers.\n"
9702 " Optional 'registered' argument lists only peers with known addresses.\n"
9703 " Optional regular expression pattern is used to filter the peer list.\n";
9705 static char show_firmware_usage[] =
9706 "Usage: iax2 list firmware\n"
9707 " Lists all known IAX firmware images.\n";
9709 static char show_reg_usage[] =
9710 "Usage: iax2 list registry\n"
9711 " Lists all registration requests and status.\n";
9713 static char debug_usage[] =
9714 "Usage: iax2 debug\n"
9715 " Enables dumping of IAX packets for debugging purposes\n";
9717 static char no_debug_usage[] =
9718 "Usage: iax2 nodebug\n"
9719 " Disables dumping of IAX packets for debugging purposes\n";
9721 static char debug_trunk_usage[] =
9722 "Usage: iax2 debug trunk\n"
9723 " Requests current status of IAX trunking\n";
9725 static char no_debug_trunk_usage[] =
9726 "Usage: iax2 nodebug trunk\n"
9727 " Requests current status of IAX trunking\n";
9729 static char debug_jb_usage[] =
9730 "Usage: iax2 debug jb\n"
9731 " Enables jitterbuffer debugging information\n";
9733 static char no_debug_jb_usage[] =
9734 "Usage: iax2 nodebug jb\n"
9735 " Disables jitterbuffer debugging information\n";
9737 static char iax2_test_losspct_usage[] =
9738 "Usage: iax2 test losspct <percentage>\n"
9739 " For testing, throws away <percentage> percent of incoming packets\n";
9741 #ifdef IAXTESTS
9742 static char iax2_test_late_usage[] =
9743 "Usage: iax2 test late <ms>\n"
9744 " For testing, count the next frame as <ms> ms late\n";
9746 static char iax2_test_resync_usage[] =
9747 "Usage: iax2 test resync <ms>\n"
9748 " For testing, adjust all future frames by <ms> ms\n";
9750 static char iax2_test_jitter_usage[] =
9751 "Usage: iax2 test jitter <ms> <pct>\n"
9752 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
9753 #endif /* IAXTESTS */
9755 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
9756 { "iax2", "trunk", "debug", NULL },
9757 iax2_do_trunk_debug, NULL,
9758 NULL };
9760 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
9761 { "iax2", "jb", "debug", NULL },
9762 iax2_do_jb_debug, NULL,
9763 NULL };
9765 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
9766 { "iax2", "no", "debug", NULL },
9767 iax2_no_debug_deprecated, NULL,
9768 NULL };
9770 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
9771 { "iax2", "no", "trunk", "debug", NULL },
9772 iax2_no_trunk_debug_deprecated, NULL,
9773 NULL };
9775 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
9776 { "iax2", "no", "jb", "debug", NULL },
9777 iax2_no_jb_debug_deprecated, NULL,
9778 NULL };
9780 static struct ast_cli_entry cli_iax2_show_cache_deprecated = {
9781 { "iax2", "show", "cache", NULL },
9782 iax2_show_cache, NULL,
9783 NULL };
9785 static struct ast_cli_entry cli_iax2_show_peers_deprecated = {
9786 { "iax2", "show", "peers", NULL },
9787 iax2_show_peers, NULL,
9788 NULL };
9790 static struct ast_cli_entry cli_iax2_show_stats_deprecated = {
9791 { "iax2", "show", "stats", NULL },
9792 iax2_show_stats, NULL };
9794 static struct ast_cli_entry cli_iax2_show_firmware_deprecated = {
9795 { "iax2", "show", "firmware", NULL },
9796 iax2_show_firmware, NULL,
9797 NULL };
9799 static struct ast_cli_entry cli_iax2_show_channels_deprecated = {
9800 { "iax2", "show", "channels", NULL },
9801 iax2_show_channels, NULL,
9802 NULL };
9804 static struct ast_cli_entry cli_iax2_show_netstats_deprecated = {
9805 { "iax2", "show", "netstats", NULL },
9806 iax2_show_netstats, NULL,
9807 NULL };
9809 static struct ast_cli_entry cli_iax2_show_users_deprecated = {
9810 { "iax2", "show", "users", NULL },
9811 iax2_show_users, NULL,
9812 NULL };
9814 static struct ast_cli_entry cli_iax2_show_threads_deprecated = {
9815 { "iax2", "show", "threads", NULL },
9816 iax2_show_threads, NULL,
9817 NULL };
9819 static struct ast_cli_entry cli_iax2_show_registry_deprecated = {
9820 { "iax2", "show", "registry", NULL },
9821 iax2_show_registry, "Show IAX registration status",
9822 show_reg_usage };
9824 static struct ast_cli_entry cli_iax2[] = {
9825 { { "iax2", "list", "cache", NULL },
9826 iax2_show_cache, "Display IAX cached dialplan",
9827 show_cache_usage, NULL, &cli_iax2_show_cache_deprecated },
9829 { { "iax2", "list", "channels", NULL },
9830 iax2_show_channels, "List active IAX channels",
9831 show_channels_usage, NULL, &cli_iax2_show_channels_deprecated },
9833 { { "iax2", "list", "firmware", NULL },
9834 iax2_show_firmware, "List available IAX firmwares",
9835 show_firmware_usage, NULL, &cli_iax2_show_firmware_deprecated },
9837 { { "iax2", "list", "netstats", NULL },
9838 iax2_show_netstats, "List active IAX channel netstats",
9839 show_netstats_usage, NULL, &cli_iax2_show_netstats_deprecated },
9841 { { "iax2", "list", "peers", NULL },
9842 iax2_show_peers, "List defined IAX peers",
9843 show_peers_usage, NULL, &cli_iax2_show_peers_deprecated },
9845 { { "iax2", "list", "registry", NULL },
9846 iax2_show_registry, "Display IAX registration status",
9847 show_reg_usage, NULL, &cli_iax2_show_registry_deprecated },
9849 { { "iax2", "list", "stats", NULL },
9850 iax2_show_stats, "Display IAX statistics",
9851 show_stats_usage, NULL, &cli_iax2_show_stats_deprecated },
9853 { { "iax2", "list", "threads", NULL },
9854 iax2_show_threads, "Display IAX helper thread info",
9855 show_threads_usage, NULL, &cli_iax2_show_threads_deprecated },
9857 { { "iax2", "list", "users", NULL },
9858 iax2_show_users, "List defined IAX users",
9859 show_users_usage, NULL, &cli_iax2_show_users_deprecated },
9861 { { "iax2", "prune", "realtime", NULL },
9862 iax2_prune_realtime, "Prune a cached realtime lookup",
9863 prune_realtime_usage, complete_iax2_show_peer },
9865 { { "iax2", "reload", NULL },
9866 iax2_reload, "Reload IAX configuration",
9867 iax2_reload_usage },
9869 { { "iax2", "show", "peer", NULL },
9870 iax2_show_peer, "Show details on specific IAX peer",
9871 show_peer_usage, complete_iax2_show_peer },
9873 { { "iax2", "debug", NULL },
9874 iax2_do_debug, "Enable IAX debugging",
9875 debug_usage },
9877 { { "iax2", "debug", "trunk", NULL },
9878 iax2_do_trunk_debug, "Enable IAX trunk debugging",
9879 debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
9881 { { "iax2", "debug", "jb", NULL },
9882 iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
9883 debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
9885 { { "iax2", "nodebug", NULL },
9886 iax2_no_debug, "Disable IAX debugging",
9887 no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
9889 { { "iax2", "nodebug", "trunk", NULL },
9890 iax2_no_trunk_debug, "Disable IAX trunk debugging",
9891 no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
9893 { { "iax2", "nodebug", "jb", NULL },
9894 iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
9895 no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
9897 { { "iax2", "test", "losspct", NULL },
9898 iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
9899 iax2_test_losspct_usage },
9901 { { "iax2", "provision", NULL },
9902 iax2_prov_cmd, "Provision an IAX device",
9903 show_prov_usage, iax2_prov_complete_template_3rd },
9905 #ifdef IAXTESTS
9906 { { "iax2", "test", "late", NULL },
9907 iax2_test_late, "Test the receipt of a late frame",
9908 iax2_test_late_usage },
9910 { { "iax2", "test", "resync", NULL },
9911 iax2_test_resync, "Test a resync in received timestamps",
9912 iax2_test_resync_usage },
9914 { { "iax2", "test", "jitter", NULL },
9915 iax2_test_jitter, "Simulates jitter for testing",
9916 iax2_test_jitter_usage },
9917 #endif /* IAXTESTS */
9920 static int __unload_module(void)
9922 pthread_t threadid = AST_PTHREADT_NULL;
9923 struct iax2_thread *thread = NULL;
9924 int x;
9926 /* Cancel the network thread, close the net socket */
9927 if (netthreadid != AST_PTHREADT_NULL) {
9928 pthread_cancel(netthreadid);
9929 pthread_join(netthreadid, NULL);
9931 if (schedthreadid != AST_PTHREADT_NULL) {
9932 pthread_cancel(schedthreadid);
9933 ast_mutex_lock(&sched_lock);
9934 sched_halt = 1;
9935 ast_cond_signal(&sched_cond);
9936 ast_mutex_unlock(&sched_lock);
9937 pthread_join(schedthreadid, NULL);
9940 /* Call for all threads to halt */
9941 AST_LIST_LOCK(&idle_list);
9942 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
9943 AST_LIST_REMOVE_CURRENT(&idle_list, list);
9944 threadid = thread->threadid;
9945 thread->halt = 1;
9946 signal_condition(&thread->lock, &thread->cond);
9947 pthread_join(threadid, NULL);
9949 AST_LIST_TRAVERSE_SAFE_END
9950 AST_LIST_UNLOCK(&idle_list);
9952 AST_LIST_LOCK(&active_list);
9953 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
9954 AST_LIST_REMOVE_CURRENT(&active_list, list);
9955 threadid = thread->threadid;
9956 thread->halt = 1;
9957 signal_condition(&thread->lock, &thread->cond);
9958 pthread_join(threadid, NULL);
9960 AST_LIST_TRAVERSE_SAFE_END
9961 AST_LIST_UNLOCK(&active_list);
9963 AST_LIST_LOCK(&dynamic_list);
9964 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
9965 AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
9966 threadid = thread->threadid;
9967 thread->halt = 1;
9968 signal_condition(&thread->lock, &thread->cond);
9969 pthread_join(threadid, NULL);
9971 AST_LIST_TRAVERSE_SAFE_END
9972 AST_LIST_UNLOCK(&dynamic_list);
9974 ast_netsock_release(netsock);
9975 for (x=0;x<IAX_MAX_CALLS;x++)
9976 if (iaxs[x])
9977 iax2_destroy(x);
9978 ast_manager_unregister( "IAXpeers" );
9979 ast_manager_unregister( "IAXnetstats" );
9980 ast_unregister_application(papp);
9981 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
9982 ast_unregister_switch(&iax2_switch);
9983 ast_channel_unregister(&iax2_tech);
9984 delete_users();
9985 iax_provision_unload();
9986 sched_context_destroy(sched);
9987 return 0;
9990 static int unload_module(void)
9992 ast_mutex_destroy(&waresl.lock);
9993 ast_custom_function_unregister(&iaxpeer_function);
9994 return __unload_module();
9998 /*! \brief Load IAX2 module, load configuraiton ---*/
9999 static int load_module(void)
10001 char *config = "iax.conf";
10002 int res = 0;
10003 int x;
10004 struct iax2_registry *reg = NULL;
10005 struct iax2_peer *peer = NULL;
10007 ast_custom_function_register(&iaxpeer_function);
10009 iax_set_output(iax_debug_output);
10010 iax_set_error(iax_error_output);
10011 jb_setoutput(jb_error_output, jb_warning_output, NULL);
10013 #ifdef HAVE_ZAPTEL
10014 #ifdef ZT_TIMERACK
10015 timingfd = open("/dev/zap/timer", O_RDWR);
10016 if (timingfd < 0)
10017 #endif
10018 timingfd = open("/dev/zap/pseudo", O_RDWR);
10019 if (timingfd < 0)
10020 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10021 #endif
10023 memset(iaxs, 0, sizeof(iaxs));
10025 for (x=0;x<IAX_MAX_CALLS;x++)
10026 ast_mutex_init(&iaxsl[x]);
10028 io = io_context_create();
10029 sched = sched_context_create();
10031 if (!io || !sched) {
10032 ast_log(LOG_ERROR, "Out of memory\n");
10033 return -1;
10036 netsock = ast_netsock_list_alloc();
10037 if (!netsock) {
10038 ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10039 return -1;
10041 ast_netsock_init(netsock);
10043 ast_mutex_init(&waresl.lock);
10045 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10047 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10049 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10050 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10052 if(set_config(config, 0) == -1)
10053 return AST_MODULE_LOAD_DECLINE;
10055 if (ast_channel_register(&iax2_tech)) {
10056 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10057 __unload_module();
10058 return -1;
10061 if (ast_register_switch(&iax2_switch))
10062 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10064 res = start_network_thread();
10065 if (!res) {
10066 if (option_verbose > 1)
10067 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10068 } else {
10069 ast_log(LOG_ERROR, "Unable to start network thread\n");
10070 ast_netsock_release(netsock);
10073 for (reg = registrations; reg; reg = reg->next)
10074 iax2_do_register(reg);
10075 AST_LIST_LOCK(&peers);
10076 AST_LIST_TRAVERSE(&peers, peer, entry) {
10077 if (peer->sockfd < 0)
10078 peer->sockfd = defaultsockfd;
10079 iax2_poke_peer(peer, 0);
10081 AST_LIST_UNLOCK(&peers);
10082 reload_firmware();
10083 iax_provision_reload();
10084 return res;
10087 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10088 .load = load_module,
10089 .unload = unload_module,
10090 .reload = reload,