Thu Oct 8 21:57:21 2009

Asterisk developer's documentation


chan_iax2.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * Hangup cause signalling implementation by
00015  * Levent Guendogdu <levon@feature-it.com>
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Implementation of Inter-Asterisk eXchange Version 2
00025  *
00026  * \author Mark Spencer <markster@digium.com>
00027  *
00028  * \par See also
00029  * \arg \ref Config_iax
00030  *
00031  * \ingroup channel_drivers
00032  */
00033 
00034 /*** MODULEINFO
00035    <use>zaptel</use>
00036         <depend>res_features</depend>
00037  ***/
00038 
00039 #include "asterisk.h"
00040 
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 132783 $")
00042 
00043 #include <stdlib.h>
00044 #include <stdio.h>
00045 #include <sys/types.h>
00046 #include <sys/mman.h>
00047 #include <dirent.h>
00048 #include <sys/socket.h>
00049 #include <netinet/in.h>
00050 #include <arpa/inet.h>
00051 #include <netinet/in_systm.h>
00052 #include <netinet/ip.h>
00053 #include <sys/time.h>
00054 #include <sys/signal.h>
00055 #include <signal.h>
00056 #include <string.h>
00057 #include <strings.h>
00058 #include <errno.h>
00059 #include <unistd.h>
00060 #include <netdb.h>
00061 #include <fcntl.h>
00062 #include <sys/stat.h>
00063 #include <regex.h>
00064 
00065 #ifdef HAVE_ZAPTEL
00066 #include <sys/ioctl.h>
00067 #include <zaptel/zaptel.h>
00068 #endif
00069 
00070 #include "asterisk/lock.h"
00071 #include "asterisk/frame.h" 
00072 #include "asterisk/channel.h"
00073 #include "asterisk/logger.h"
00074 #include "asterisk/module.h"
00075 #include "asterisk/pbx.h"
00076 #include "asterisk/sched.h"
00077 #include "asterisk/io.h"
00078 #include "asterisk/config.h"
00079 #include "asterisk/options.h"
00080 #include "asterisk/cli.h"
00081 #include "asterisk/translate.h"
00082 #include "asterisk/md5.h"
00083 #include "asterisk/cdr.h"
00084 #include "asterisk/crypto.h"
00085 #include "asterisk/acl.h"
00086 #include "asterisk/manager.h"
00087 #include "asterisk/callerid.h"
00088 #include "asterisk/app.h"
00089 #include "asterisk/astdb.h"
00090 #include "asterisk/musiconhold.h"
00091 #include "asterisk/features.h"
00092 #include "asterisk/utils.h"
00093 #include "asterisk/causes.h"
00094 #include "asterisk/localtime.h"
00095 #include "asterisk/aes.h"
00096 #include "asterisk/dnsmgr.h"
00097 #include "asterisk/devicestate.h"
00098 #include "asterisk/netsock.h"
00099 #include "asterisk/stringfields.h"
00100 #include "asterisk/linkedlists.h"
00101 #include "asterisk/astobj2.h"
00102 
00103 #include "iax2.h"
00104 #include "iax2-parser.h"
00105 #include "iax2-provision.h"
00106 #include "jitterbuf.h"
00107 
00108 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00109    multithreaded mode. */
00110 #define SCHED_MULTITHREADED
00111 
00112 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00113    thread is actually doing. */
00114 #define DEBUG_SCHED_MULTITHREAD
00115 
00116 #ifndef IPTOS_MINCOST
00117 #define IPTOS_MINCOST 0x02
00118 #endif
00119 
00120 #ifdef SO_NO_CHECK
00121 static int nochecksums = 0;
00122 #endif
00123 
00124 
00125 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00126 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00127 
00128 #define DEFAULT_THREAD_COUNT 10
00129 #define DEFAULT_MAX_THREAD_COUNT 100
00130 #define DEFAULT_RETRY_TIME 1000
00131 #define MEMORY_SIZE 100
00132 #define DEFAULT_DROP 3
00133 
00134 #define DEBUG_SUPPORT
00135 
00136 #define MIN_REUSE_TIME     60 /* Don't reuse a call number within 60 seconds */
00137 
00138 /* Sample over last 100 units to determine historic jitter */
00139 #define GAMMA (0.01)
00140 
00141 static struct ast_codec_pref prefs;
00142 
00143 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00144 
00145 static char context[80] = "default";
00146 
00147 static char language[MAX_LANGUAGE] = "";
00148 static char regcontext[AST_MAX_CONTEXT] = "";
00149 
00150 static int maxauthreq = 3;
00151 static int max_retries = 4;
00152 static int ping_time = 21;
00153 static int lagrq_time = 10;
00154 static int maxjitterbuffer=1000;
00155 static int resyncthreshold=1000;
00156 static int maxjitterinterps=10;
00157 static int trunkfreq = 20;
00158 static int authdebug = 1;
00159 static int autokill = 0;
00160 static int iaxcompat = 0;
00161 static int last_authmethod = 0;
00162 
00163 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00164 
00165 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00166 
00167 static unsigned int tos = 0;
00168 
00169 static int min_reg_expire;
00170 static int max_reg_expire;
00171 
00172 static int timingfd = -1;           /* Timing file descriptor */
00173 
00174 static struct ast_netsock_list *netsock;
00175 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00176 static int defaultsockfd = -1;
00177 
00178 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00179 
00180 /* Ethernet, etc */
00181 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00182 /* T1, maybe ISDN */
00183 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00184                 ~AST_FORMAT_SLINEAR &        \
00185                 ~AST_FORMAT_ULAW &        \
00186                 ~AST_FORMAT_ALAW &        \
00187                 ~AST_FORMAT_G722) 
00188 /* A modem */
00189 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00190                 ~AST_FORMAT_G726 &        \
00191                 ~AST_FORMAT_G726_AAL2 &      \
00192                 ~AST_FORMAT_ADPCM)
00193 
00194 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00195                 ~AST_FORMAT_G723_1)
00196 
00197 
00198 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00199 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00200 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00201 
00202 static   struct io_context *io;
00203 static   struct sched_context *sched;
00204 
00205 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00206 
00207 static int iaxdebug = 0;
00208 
00209 static int iaxtrunkdebug = 0;
00210 
00211 static int test_losspct = 0;
00212 #ifdef IAXTESTS
00213 static int test_late = 0;
00214 static int test_resync = 0;
00215 static int test_jit = 0;
00216 static int test_jitpct = 0;
00217 #endif /* IAXTESTS */
00218 
00219 static char accountcode[AST_MAX_ACCOUNT_CODE];
00220 static char mohinterpret[MAX_MUSICCLASS];
00221 static char mohsuggest[MAX_MUSICCLASS];
00222 static int amaflags = 0;
00223 static int adsi = 0;
00224 static int delayreject = 0;
00225 static int iax2_encryption = 0;
00226 
00227 static struct ast_flags globalflags = { 0 };
00228 
00229 static pthread_t netthreadid = AST_PTHREADT_NULL;
00230 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00231 AST_MUTEX_DEFINE_STATIC(sched_lock);
00232 static ast_cond_t sched_cond;
00233 
00234 enum {
00235    IAX_STATE_STARTED =        (1 << 0),
00236    IAX_STATE_AUTHENTICATED =  (1 << 1),
00237    IAX_STATE_TBD =            (1 << 2),
00238 } iax2_state;
00239 
00240 struct iax2_context {
00241    char context[AST_MAX_CONTEXT];
00242    struct iax2_context *next;
00243 };
00244 
00245 enum {
00246    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00247    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00248    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00249    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00250    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00251    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00252    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00253    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00254         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00255    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00256    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00257    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00258    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00259    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00260    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00261    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00262    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00263    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00264    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00265    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00266    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00267    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00268    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00269    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00270    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00271    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00272                        response, so that we've achieved a three-way handshake with
00273                        them before sending voice or anything else*/
00274    IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */
00275 } iax2_flags;
00276 
00277 static int global_rtautoclear = 120;
00278 
00279 static int reload_config(void);
00280 static int iax2_reload(int fd, int argc, char *argv[]);
00281 
00282 
00283 struct iax2_user {
00284    AST_DECLARE_STRING_FIELDS(
00285       AST_STRING_FIELD(name);
00286       AST_STRING_FIELD(secret);
00287       AST_STRING_FIELD(dbsecret);
00288       AST_STRING_FIELD(accountcode);
00289       AST_STRING_FIELD(mohinterpret);
00290       AST_STRING_FIELD(mohsuggest);
00291       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00292       AST_STRING_FIELD(language);
00293       AST_STRING_FIELD(cid_num);
00294       AST_STRING_FIELD(cid_name);
00295    );
00296    
00297    int authmethods;
00298    int encmethods;
00299    int amaflags;
00300    int adsi;
00301    unsigned int flags;
00302    int capability;
00303    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00304    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00305    struct ast_codec_pref prefs;
00306    struct ast_ha *ha;
00307    struct iax2_context *contexts;
00308    struct ast_variable *vars;
00309 };
00310 
00311 struct iax2_peer {
00312    AST_DECLARE_STRING_FIELDS(
00313       AST_STRING_FIELD(name);
00314       AST_STRING_FIELD(username);
00315       AST_STRING_FIELD(secret);
00316       AST_STRING_FIELD(dbsecret);
00317       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00318 
00319       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00320       AST_STRING_FIELD(context);      /*!< For transfers only */
00321       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00322       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00323       AST_STRING_FIELD(mohinterpret);
00324       AST_STRING_FIELD(mohsuggest);
00325       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00326       /* Suggested caller id if registering */
00327       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00328       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00330    );
00331    struct ast_codec_pref prefs;
00332    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00333    struct sockaddr_in addr;
00334    int formats;
00335    int sockfd;             /*!< Socket to use for transmission */
00336    struct in_addr mask;
00337    int adsi;
00338    unsigned int flags;
00339 
00340    /* Dynamic Registration fields */
00341    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00342    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00343    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00344 
00345    int expire;             /*!< Schedule entry for expiry */
00346    int expiry;             /*!< How soon to expire */
00347    int capability;               /*!< Capability */
00348 
00349    /* Qualification */
00350    int callno;             /*!< Call number of POKE request */
00351    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00352    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00353    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00354 
00355    int pokefreqok;               /*!< How often to check if the host is up */
00356    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00357    int historicms;               /*!< How long recent average responses took */
00358    int smoothing;             /*!< Sample over how many units to determine historic ms */
00359    
00360    struct ast_ha *ha;
00361 };
00362 
00363 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00364 
00365 static struct iax2_trunk_peer {
00366    ast_mutex_t lock;
00367    int sockfd;
00368    struct sockaddr_in addr;
00369    struct timeval txtrunktime;      /*!< Transmit trunktime */
00370    struct timeval rxtrunktime;      /*!< Receive trunktime */
00371    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00372    struct timeval trunkact;      /*!< Last trunk activity */
00373    unsigned int lastsent;        /*!< Last sent time */
00374    /* Trunk data and length */
00375    unsigned char *trunkdata;
00376    unsigned int trunkdatalen;
00377    unsigned int trunkdataalloc;
00378    struct iax2_trunk_peer *next;
00379    int trunkerror;
00380    int calls;
00381 } *tpeers = NULL;
00382 
00383 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00384 
00385 struct iax_firmware {
00386    struct iax_firmware *next;
00387    int fd;
00388    int mmaplen;
00389    int dead;
00390    struct ast_iax2_firmware_header *fwh;
00391    unsigned char *buf;
00392 };
00393 
00394 enum iax_reg_state {
00395    REG_STATE_UNREGISTERED = 0,
00396    REG_STATE_REGSENT,
00397    REG_STATE_AUTHSENT,
00398    REG_STATE_REGISTERED,
00399    REG_STATE_REJECTED,
00400    REG_STATE_TIMEOUT,
00401    REG_STATE_NOAUTH
00402 };
00403 
00404 enum iax_transfer_state {
00405    TRANSFER_NONE = 0,
00406    TRANSFER_BEGIN,
00407    TRANSFER_READY,
00408    TRANSFER_RELEASED,
00409    TRANSFER_PASSTHROUGH,
00410    TRANSFER_MBEGIN,
00411    TRANSFER_MREADY,
00412    TRANSFER_MRELEASED,
00413    TRANSFER_MPASSTHROUGH,
00414    TRANSFER_MEDIA,
00415    TRANSFER_MEDIAPASS
00416 };
00417 
00418 struct iax2_registry {
00419    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00420    char username[80];
00421    char secret[80];        /*!< Password or key name in []'s */
00422    char random[80];
00423    int expire;          /*!< Sched ID of expiration */
00424    int refresh;            /*!< How often to refresh */
00425    enum iax_reg_state regstate;
00426    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00427    int callno;          /*!< Associated call number if applicable */
00428    struct sockaddr_in us;        /*!< Who the server thinks we are */
00429    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00430    AST_LIST_ENTRY(iax2_registry) entry;
00431 };
00432 
00433 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00434 
00435 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00436 #define MIN_RETRY_TIME     100
00437 #define MAX_RETRY_TIME     10000
00438 
00439 #define MAX_JITTER_BUFFER  50
00440 #define MIN_JITTER_BUFFER  10
00441 
00442 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00443 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00444 
00445 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00446 
00447 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00448 #define TS_GAP_FOR_JB_RESYNC  5000
00449 
00450 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00451 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00452 static int iaxdynamicthreadcount = 0;
00453 static int iaxactivethreadcount = 0;
00454 
00455 struct iax_rr {
00456    int jitter;
00457    int losspct;
00458    int losscnt;
00459    int packets;
00460    int delay;
00461    int dropped;
00462    int ooo;
00463 };
00464 
00465 struct chan_iax2_pvt {
00466    /*! Socket to send/receive on for this call */
00467    int sockfd;
00468    /*! Last received voice format */
00469    int voiceformat;
00470    /*! Last received video format */
00471    int videoformat;
00472    /*! Last sent voice format */
00473    int svoiceformat;
00474    /*! Last sent video format */
00475    int svideoformat;
00476    /*! What we are capable of sending */
00477    int capability;
00478    /*! Last received timestamp */
00479    unsigned int last;
00480    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00481    unsigned int lastsent;
00482    /*! Timestamp of the last video frame sent */
00483    unsigned int lastvsent;
00484    /*! Next outgoing timestamp if everything is good */
00485    unsigned int nextpred;
00486    /*! True if the last voice we transmitted was not silence/CNG */
00487    int notsilenttx;
00488    /*! Ping time */
00489    unsigned int pingtime;
00490    /*! Max time for initial response */
00491    int maxtime;
00492    /*! Peer Address */
00493    struct sockaddr_in addr;
00494    /*! Actual used codec preferences */
00495    struct ast_codec_pref prefs;
00496    /*! Requested codec preferences */
00497    struct ast_codec_pref rprefs;
00498    /*! Our call number */
00499    unsigned short callno;
00500    /*! Peer callno */
00501    unsigned short peercallno;
00502    /*! Negotiated format, this is only used to remember what format was
00503        chosen for an unauthenticated call so that the channel can get
00504        created later using the right format */
00505    int chosenformat;
00506    /*! Peer selected format */
00507    int peerformat;
00508    /*! Peer capability */
00509    int peercapability;
00510    /*! timeval that we base our transmission on */
00511    struct timeval offset;
00512    /*! timeval that we base our delivery on */
00513    struct timeval rxcore;
00514    /*! The jitterbuffer */
00515         jitterbuf *jb;
00516    /*! active jb read scheduler id */
00517         int jbid;
00518    /*! LAG */
00519    int lag;
00520    /*! Error, as discovered by the manager */
00521    int error;
00522    /*! Owner if we have one */
00523    struct ast_channel *owner;
00524    /*! What's our state? */
00525    struct ast_flags state;
00526    /*! Expiry (optional) */
00527    int expiry;
00528    /*! Next outgoing sequence number */
00529    unsigned char oseqno;
00530    /*! Next sequence number they have not yet acknowledged */
00531    unsigned char rseqno;
00532    /*! Next incoming sequence number */
00533    unsigned char iseqno;
00534    /*! Last incoming sequence number we have acknowledged */
00535    unsigned char aseqno;
00536 
00537    AST_DECLARE_STRING_FIELDS(
00538       /*! Peer name */
00539       AST_STRING_FIELD(peer);
00540       /*! Default Context */
00541       AST_STRING_FIELD(context);
00542       /*! Caller ID if available */
00543       AST_STRING_FIELD(cid_num);
00544       AST_STRING_FIELD(cid_name);
00545       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00546       AST_STRING_FIELD(ani);
00547       /*! DNID */
00548       AST_STRING_FIELD(dnid);
00549       /*! RDNIS */
00550       AST_STRING_FIELD(rdnis);
00551       /*! Requested Extension */
00552       AST_STRING_FIELD(exten);
00553       /*! Expected Username */
00554       AST_STRING_FIELD(username);
00555       /*! Expected Secret */
00556       AST_STRING_FIELD(secret);
00557       /*! MD5 challenge */
00558       AST_STRING_FIELD(challenge);
00559       /*! Public keys permitted keys for incoming authentication */
00560       AST_STRING_FIELD(inkeys);
00561       /*! Private key for outgoing authentication */
00562       AST_STRING_FIELD(outkey);
00563       /*! Preferred language */
00564       AST_STRING_FIELD(language);
00565       /*! Hostname/peername for naming purposes */
00566       AST_STRING_FIELD(host);
00567 
00568       AST_STRING_FIELD(dproot);
00569       AST_STRING_FIELD(accountcode);
00570       AST_STRING_FIELD(mohinterpret);
00571       AST_STRING_FIELD(mohsuggest);
00572    );
00573    /*! AUTHREJ all AUTHREP frames */
00574    int authrej;
00575    /*! permitted authentication methods */
00576    int authmethods;
00577    /*! permitted encryption methods */
00578    int encmethods;
00579    /*! Encryption AES-128 Key */
00580    aes_encrypt_ctx ecx;
00581    /*! Decryption AES-128 Key corresponding to ecx */
00582    aes_decrypt_ctx mydcx;
00583    /*! Decryption AES-128 Key used to decrypt peer frames */
00584    aes_decrypt_ctx dcx;
00585    /*! 32 bytes of semi-random data */
00586    unsigned char semirand[32];
00587    /*! Associated registry */
00588    struct iax2_registry *reg;
00589    /*! Associated peer for poking */
00590    struct iax2_peer *peerpoke;
00591    /*! IAX_ flags */
00592    unsigned int flags;
00593    int adsi;
00594 
00595    /*! Transferring status */
00596    enum iax_transfer_state transferring;
00597    /*! Transfer identifier */
00598    int transferid;
00599    /*! Who we are IAX transfering to */
00600    struct sockaddr_in transfer;
00601    /*! What's the new call number for the transfer */
00602    unsigned short transfercallno;
00603    /*! Transfer decrypt AES-128 Key */
00604    aes_encrypt_ctx tdcx;
00605 
00606    /*! Status of knowledge of peer ADSI capability */
00607    int peeradsicpe;
00608 
00609    /*! Who we are bridged to */
00610    unsigned short bridgecallno;
00611    
00612    int pingid;       /*!< Transmit PING request */
00613    int lagid;        /*!< Retransmit lag request */
00614    int autoid;       /*!< Auto hangup for Dialplan requestor */
00615    int authid;       /*!< Authentication rejection ID */
00616    int authfail;        /*!< Reason to report failure */
00617    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00618    int calling_ton;
00619    int calling_tns;
00620    int calling_pres;
00621    int amaflags;
00622    struct iax2_dpcache *dpentries;
00623    struct ast_variable *vars;
00624    /*! last received remote rr */
00625    struct iax_rr remote_rr;
00626    /*! Current base time: (just for stats) */
00627    int min;
00628    /*! Dropped frame count: (just for stats) */
00629    int frames_dropped;
00630    /*! received frame count: (just for stats) */
00631    int frames_received;
00632 };
00633 
00634 static struct ast_iax2_queue {
00635    AST_LIST_HEAD(, iax_frame) queue;
00636    int count;
00637 } iaxq;
00638 
00639 /*!
00640  * This module will get much higher performance when doing a lot of
00641  * user and peer lookups if the number of buckets is increased from 1.
00642  * However, to maintain old behavior for Asterisk 1.4, these are set to
00643  * 1 by default.  When using multiple buckets, search order through these
00644  * containers is considered random, so you will not be able to depend on
00645  * the order the entires are specified in iax.conf for matching order. */
00646 #ifdef LOW_MEMORY
00647 #define MAX_PEER_BUCKETS 1
00648 /* #define MAX_PEER_BUCKETS 17 */
00649 #else
00650 #define MAX_PEER_BUCKETS 1
00651 /* #define MAX_PEER_BUCKETS 563 */
00652 #endif
00653 static struct ao2_container *peers;
00654 
00655 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00656 static struct ao2_container *users;
00657 
00658 static struct ast_firmware_list {
00659    struct iax_firmware *wares;
00660    ast_mutex_t lock;
00661 } waresl;
00662 
00663 /*! Extension exists */
00664 #define CACHE_FLAG_EXISTS     (1 << 0)
00665 /*! Extension is nonexistent */
00666 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00667 /*! Extension can exist */
00668 #define CACHE_FLAG_CANEXIST      (1 << 2)
00669 /*! Waiting to hear back response */
00670 #define CACHE_FLAG_PENDING    (1 << 3)
00671 /*! Timed out */
00672 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00673 /*! Request transmitted */
00674 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00675 /*! Timeout */
00676 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00677 /*! Matchmore */
00678 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00679 
00680 static struct iax2_dpcache {
00681    char peercontext[AST_MAX_CONTEXT];
00682    char exten[AST_MAX_EXTENSION];
00683    struct timeval orig;
00684    struct timeval expiry;
00685    int flags;
00686    unsigned short callno;
00687    int waiters[256];
00688    struct iax2_dpcache *next;
00689    struct iax2_dpcache *peer; /*!< For linking in peers */
00690 } *dpcache;
00691 
00692 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00693 
00694 static void reg_source_db(struct iax2_peer *p);
00695 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00696 
00697 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00698 
00699 #define IAX_IOSTATE_IDLE      0
00700 #define IAX_IOSTATE_READY     1
00701 #define IAX_IOSTATE_PROCESSING   2
00702 #define IAX_IOSTATE_SCHEDREADY   3
00703 
00704 #define IAX_TYPE_POOL    1
00705 #define IAX_TYPE_DYNAMIC 2
00706 
00707 struct iax2_pkt_buf {
00708    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00709    size_t len;
00710    unsigned char buf[1];
00711 };
00712 
00713 struct iax2_thread {
00714    AST_LIST_ENTRY(iax2_thread) list;
00715    int type;
00716    int iostate;
00717 #ifdef SCHED_MULTITHREADED
00718    void (*schedfunc)(const void *);
00719    const void *scheddata;
00720 #endif
00721 #ifdef DEBUG_SCHED_MULTITHREAD
00722    char curfunc[80];
00723 #endif   
00724    int actions;
00725    pthread_t threadid;
00726    int threadnum;
00727    struct sockaddr_in iosin;
00728    unsigned char readbuf[4096]; 
00729    unsigned char *buf;
00730    ssize_t buf_len;
00731    size_t buf_size;
00732    int iofd;
00733    time_t checktime;
00734    ast_mutex_t lock;
00735    ast_cond_t cond;
00736    unsigned int ready_for_signal:1;
00737    /*! if this thread is processing a full frame,
00738      some information about that frame will be stored
00739      here, so we can avoid dispatching any more full
00740      frames for that callno to other threads */
00741    struct {
00742       unsigned short callno;
00743       struct sockaddr_in sin;
00744       unsigned char type;
00745       unsigned char csub;
00746    } ffinfo;
00747    /*! Queued up full frames for processing.  If more full frames arrive for
00748     *  a call which this thread is already processing a full frame for, they
00749     *  are queued up here. */
00750    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00751 };
00752 
00753 /* Thread lists */
00754 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00755 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00756 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00757 
00758 static void *iax2_process_thread(void *data);
00759 
00760 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00761 {
00762    ast_mutex_lock(lock);
00763    ast_cond_signal(cond);
00764    ast_mutex_unlock(lock);
00765 }
00766 
00767 static void iax_debug_output(const char *data)
00768 {
00769    if (iaxdebug)
00770       ast_verbose("%s", data);
00771 }
00772 
00773 static void iax_error_output(const char *data)
00774 {
00775    ast_log(LOG_WARNING, "%s", data);
00776 }
00777 
00778 static void jb_error_output(const char *fmt, ...)
00779 {
00780    va_list args;
00781    char buf[1024];
00782 
00783    va_start(args, fmt);
00784    vsnprintf(buf, 1024, fmt, args);
00785    va_end(args);
00786 
00787    ast_log(LOG_ERROR, buf);
00788 }
00789 
00790 static void jb_warning_output(const char *fmt, ...)
00791 {
00792    va_list args;
00793    char buf[1024];
00794 
00795    va_start(args, fmt);
00796    vsnprintf(buf, 1024, fmt, args);
00797    va_end(args);
00798 
00799    ast_log(LOG_WARNING, buf);
00800 }
00801 
00802 static void jb_debug_output(const char *fmt, ...)
00803 {
00804    va_list args;
00805    char buf[1024];
00806 
00807    va_start(args, fmt);
00808    vsnprintf(buf, 1024, fmt, args);
00809    va_end(args);
00810 
00811    ast_verbose(buf);
00812 }
00813 
00814 /* XXX We probably should use a mutex when working with this XXX */
00815 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00816 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00817 static struct timeval lastused[ARRAY_LEN(iaxs)];
00818 
00819 /*!
00820  * \brief Another container of iax2_pvt structures
00821  *
00822  * Active IAX2 pvt structs are also stored in this container, if they are a part
00823  * of an active call where we know the remote side's call number.  The reason
00824  * for this is that incoming media frames do not contain our call number.  So,
00825  * instead of having to iterate the entire iaxs array, we use this container to
00826  * look up calls where the remote side is using a given call number.
00827  */
00828 static struct ao2_container *iax_peercallno_pvts;
00829 
00830 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00831    but keeps the division between trunked and non-trunked better. */
00832 #define TRUNK_CALL_START   ARRAY_LEN(iaxs) / 2
00833 
00834 static int maxtrunkcall = TRUNK_CALL_START;
00835 static int maxnontrunkcall = 1;
00836 
00837 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);
00838 static int expire_registry(const void *data);
00839 static int iax2_answer(struct ast_channel *c);
00840 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00841 static int iax2_devicestate(void *data);
00842 static int iax2_digit_begin(struct ast_channel *c, char digit);
00843 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00844 static int iax2_do_register(struct iax2_registry *reg);
00845 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00846 static int iax2_hangup(struct ast_channel *c);
00847 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00848 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00849 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00850 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00851 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00852 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00853 static int iax2_sendtext(struct ast_channel *c, const char *text);
00854 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00855 static int iax2_transfer(struct ast_channel *c, const char *dest);
00856 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00857 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00858 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00859 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00860 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00861 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00862 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00863 static struct ast_frame *iax2_read(struct ast_channel *c);
00864 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00865 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00866 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00867 static void prune_peers(void);
00868 
00869 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00870 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00871 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00872   
00873 static const struct ast_channel_tech iax2_tech = {
00874    .type = "IAX2",
00875    .description = tdesc,
00876    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00877    .properties = AST_CHAN_TP_WANTSJITTER,
00878    .requester = iax2_request,
00879    .devicestate = iax2_devicestate,
00880    .send_digit_begin = iax2_digit_begin,
00881    .send_digit_end = iax2_digit_end,
00882    .send_text = iax2_sendtext,
00883    .send_image = iax2_sendimage,
00884    .send_html = iax2_sendhtml,
00885    .call = iax2_call,
00886    .hangup = iax2_hangup,
00887    .answer = iax2_answer,
00888    .read = iax2_read,
00889    .write = iax2_write,
00890    .write_video = iax2_write,
00891    .indicate = iax2_indicate,
00892    .setoption = iax2_setoption,
00893    .bridge = iax2_bridge,
00894    .transfer = iax2_transfer,
00895    .fixup = iax2_fixup,
00896 };
00897 
00898 /* WARNING: insert_idle_thread should only ever be called within the
00899  * context of an iax2_process_thread() thread.
00900  */
00901 static void insert_idle_thread(struct iax2_thread *thread)
00902 {
00903    if (thread->type == IAX_TYPE_DYNAMIC) {
00904       AST_LIST_LOCK(&dynamic_list);
00905       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00906       AST_LIST_UNLOCK(&dynamic_list);
00907    } else {
00908       AST_LIST_LOCK(&idle_list);
00909       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00910       AST_LIST_UNLOCK(&idle_list);
00911    }
00912 
00913    return;
00914 }
00915 
00916 static struct iax2_thread *find_idle_thread(void)
00917 {
00918    pthread_attr_t attr;
00919    struct iax2_thread *thread = NULL;
00920 
00921    /* Pop the head of the list off */
00922    AST_LIST_LOCK(&idle_list);
00923    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00924    AST_LIST_UNLOCK(&idle_list);
00925 
00926    /* If no idle thread is available from the regular list, try dynamic */
00927    if (thread == NULL) {
00928       AST_LIST_LOCK(&dynamic_list);
00929       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00930       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00931       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00932          /* We need to MAKE a thread! */
00933          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00934             thread->threadnum = iaxdynamicthreadcount;
00935             thread->type = IAX_TYPE_DYNAMIC;
00936             ast_mutex_init(&thread->lock);
00937             ast_cond_init(&thread->cond, NULL);
00938             pthread_attr_init(&attr);
00939             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00940             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00941                free(thread);
00942                thread = NULL;
00943             } else {
00944                /* All went well and the thread is up, so increment our count */
00945                iaxdynamicthreadcount++;
00946                
00947                /* Wait for the thread to be ready before returning it to the caller */
00948                while (!thread->ready_for_signal)
00949                   usleep(1);
00950             }
00951          }
00952       }
00953       AST_LIST_UNLOCK(&dynamic_list);
00954    }
00955 
00956    /* this thread is not processing a full frame (since it is idle),
00957       so ensure that the field for the full frame call number is empty */
00958    if (thread)
00959       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00960 
00961    return thread;
00962 }
00963 
00964 #ifdef SCHED_MULTITHREADED
00965 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00966 {
00967    struct iax2_thread *thread = NULL;
00968    static time_t lasterror;
00969    static time_t t;
00970 
00971    thread = find_idle_thread();
00972 
00973    if (thread != NULL) {
00974       thread->schedfunc = func;
00975       thread->scheddata = data;
00976       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00977 #ifdef DEBUG_SCHED_MULTITHREAD
00978       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00979 #endif
00980       signal_condition(&thread->lock, &thread->cond);
00981       return 0;
00982    }
00983    time(&t);
00984    if (t != lasterror && option_debug) 
00985       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00986    lasterror = t;
00987 
00988    return -1;
00989 }
00990 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00991 #endif
00992 
00993 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00994 {
00995    int res;
00996 
00997    res = ast_sched_add(con, when, callback, data);
00998    signal_condition(&sched_lock, &sched_cond);
00999 
01000    return res;
01001 }
01002 
01003 static int send_ping(const void *data);
01004 
01005 static void __send_ping(const void *data)
01006 {
01007    int callno = (long) data;
01008 
01009    ast_mutex_lock(&iaxsl[callno]);
01010 
01011    while (iaxs[callno] && iaxs[callno]->pingid != -1) {
01012       if (iaxs[callno]->peercallno) {
01013          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01014       }
01015       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01016       break;
01017    }
01018 
01019    ast_mutex_unlock(&iaxsl[callno]);
01020 }
01021 
01022 static int send_ping(const void *data)
01023 {
01024 #ifdef SCHED_MULTITHREADED
01025    if (schedule_action(__send_ping, data))
01026 #endif      
01027       __send_ping(data);
01028    return 0;
01029 }
01030 
01031 static int get_encrypt_methods(const char *s)
01032 {
01033    int e;
01034    if (!strcasecmp(s, "aes128"))
01035       e = IAX_ENCRYPT_AES128;
01036    else if (ast_true(s))
01037       e = IAX_ENCRYPT_AES128;
01038    else
01039       e = 0;
01040    return e;
01041 }
01042 
01043 static int send_lagrq(const void *data);
01044 
01045 static void __send_lagrq(const void *data)
01046 {
01047    int callno = (long) data;
01048 
01049    ast_mutex_lock(&iaxsl[callno]);
01050 
01051    while (iaxs[callno] && iaxs[callno]->lagid > -1) {
01052       if (iaxs[callno]->peercallno) {
01053          send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01054       }
01055       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01056       break;
01057    }
01058 
01059    ast_mutex_unlock(&iaxsl[callno]);
01060 }
01061 
01062 static int send_lagrq(const void *data)
01063 {
01064 #ifdef SCHED_MULTITHREADED
01065    if (schedule_action(__send_lagrq, data))
01066 #endif      
01067       __send_lagrq(data);
01068    return 0;
01069 }
01070 
01071 static unsigned char compress_subclass(int subclass)
01072 {
01073    int x;
01074    int power=-1;
01075    /* If it's 128 or smaller, just return it */
01076    if (subclass < IAX_FLAG_SC_LOG)
01077       return subclass;
01078    /* Otherwise find its power */
01079    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01080       if (subclass & (1 << x)) {
01081          if (power > -1) {
01082             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01083             return 0;
01084          } else
01085             power = x;
01086       }
01087    }
01088    return power | IAX_FLAG_SC_LOG;
01089 }
01090 
01091 static int uncompress_subclass(unsigned char csub)
01092 {
01093    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01094    if (csub & IAX_FLAG_SC_LOG) {
01095       /* special case for 'compressed' -1 */
01096       if (csub == 0xff)
01097          return -1;
01098       else
01099          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01100    }
01101    else
01102       return csub;
01103 }
01104 
01105 /*!
01106  * \note The only member of the peer passed here guaranteed to be set is the name field
01107  */
01108 static int peer_hash_cb(const void *obj, const int flags)
01109 {
01110    const struct iax2_peer *peer = obj;
01111 
01112    return ast_str_hash(peer->name);
01113 }
01114 
01115 /*!
01116  * \note The only member of the peer passed here guaranteed to be set is the name field
01117  */
01118 static int peer_cmp_cb(void *obj, void *arg, int flags)
01119 {
01120    struct iax2_peer *peer = obj, *peer2 = arg;
01121 
01122    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01123 }
01124 
01125 /*!
01126  * \note The only member of the user passed here guaranteed to be set is the name field
01127  */
01128 static int user_hash_cb(const void *obj, const int flags)
01129 {
01130    const struct iax2_user *user = obj;
01131 
01132    return ast_str_hash(user->name);
01133 }
01134 
01135 /*!
01136  * \note The only member of the user passed here guaranteed to be set is the name field
01137  */
01138 static int user_cmp_cb(void *obj, void *arg, int flags)
01139 {
01140    struct iax2_user *user = obj, *user2 = arg;
01141 
01142    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01143 }
01144 
01145 /*!
01146  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01147  *       so do not call it with a pvt lock held.
01148  */
01149 static struct iax2_peer *find_peer(const char *name, int realtime) 
01150 {
01151    struct iax2_peer *peer = NULL;
01152    struct iax2_peer tmp_peer = {
01153       .name = name,
01154    };
01155 
01156    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01157 
01158    /* Now go for realtime if applicable */
01159    if(!peer && realtime)
01160       peer = realtime_peer(name, NULL);
01161 
01162    return peer;
01163 }
01164 
01165 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01166 {
01167    ao2_ref(peer, +1);
01168    return peer;
01169 }
01170 
01171 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01172 {
01173    ao2_ref(peer, -1);
01174    return NULL;
01175 }
01176 
01177 static inline struct iax2_user *user_ref(struct iax2_user *user)
01178 {
01179    ao2_ref(user, +1);
01180    return user;
01181 }
01182 
01183 static inline struct iax2_user *user_unref(struct iax2_user *user)
01184 {
01185    ao2_ref(user, -1);
01186    return NULL;
01187 }
01188 
01189 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01190 {
01191    struct iax2_peer *peer = NULL;
01192    int res = 0;
01193    struct ao2_iterator i;
01194 
01195    i = ao2_iterator_init(peers, 0);
01196    while ((peer = ao2_iterator_next(&i))) {
01197       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01198           (peer->addr.sin_port == sin.sin_port)) {
01199          ast_copy_string(host, peer->name, len);
01200          peer_unref(peer);
01201          res = 1;
01202          break;
01203       }
01204       peer_unref(peer);
01205    }
01206 
01207    if (!peer) {
01208       peer = realtime_peer(NULL, &sin);
01209       if (peer) {
01210          ast_copy_string(host, peer->name, len);
01211          peer_unref(peer);
01212          res = 1;
01213       }
01214    }
01215 
01216    return res;
01217 }
01218 
01219 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01220 {
01221    /* Decrement AUTHREQ count if needed */
01222    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01223       struct iax2_user *user;
01224       struct iax2_user tmp_user = {
01225          .name = pvt->username,
01226       };
01227 
01228       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01229       if (user) {
01230          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01231          user = user_unref(user);       
01232       }
01233 
01234       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01235    }
01236 
01237    /* No more pings or lagrq's */
01238    AST_SCHED_DEL(sched, pvt->pingid);
01239    AST_SCHED_DEL(sched, pvt->lagid);
01240    AST_SCHED_DEL(sched, pvt->autoid);
01241    AST_SCHED_DEL(sched, pvt->authid);
01242    AST_SCHED_DEL(sched, pvt->initid);
01243    AST_SCHED_DEL(sched, pvt->jbid);
01244 }
01245 
01246 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01247 {
01248    if (!pvt->peercallno) {
01249       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01250       return;
01251    }
01252 
01253    ao2_link(iax_peercallno_pvts, pvt);
01254 }
01255 
01256 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01257 {
01258    if (!pvt->peercallno) {
01259       ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01260       return;
01261    }
01262 
01263    ao2_unlink(iax_peercallno_pvts, pvt);
01264 }
01265 
01266 static void update_max_trunk(void)
01267 {
01268    int max = TRUNK_CALL_START;
01269    int x;
01270 
01271    /* XXX Prolly don't need locks here XXX */
01272    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01273       if (iaxs[x]) {
01274          max = x + 1;
01275       }
01276    }
01277 
01278    maxtrunkcall = max;
01279    if (option_debug && iaxdebug)
01280       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01281 }
01282 
01283 static void iax2_frame_free(struct iax_frame *fr)
01284 {
01285    AST_SCHED_DEL(sched, fr->retrans);
01286    iax_frame_free(fr);
01287 }
01288 
01289 static void iax2_destroy(int callno)
01290 {
01291    struct chan_iax2_pvt *pvt;
01292    struct ast_channel *owner;
01293 
01294 retry:
01295    pvt = iaxs[callno];
01296    gettimeofday(&lastused[callno], NULL);
01297    
01298    owner = pvt ? pvt->owner : NULL;
01299 
01300    if (owner) {
01301       if (ast_mutex_trylock(&owner->lock)) {
01302          if (option_debug > 2)
01303             ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01304          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01305          goto retry;
01306       }
01307    }
01308    if (!owner) {
01309       iaxs[callno] = NULL;
01310    }
01311 
01312    if (pvt) {
01313       if (!owner) {
01314          pvt->owner = NULL;
01315       } else {
01316          /* If there's an owner, prod it to give up */
01317          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01318           * because we already hold the owner channel lock. */
01319          ast_queue_hangup(owner);
01320       }
01321 
01322       if (pvt->peercallno) {
01323          remove_by_peercallno(pvt);
01324       }
01325 
01326       if (!owner) {
01327          ao2_ref(pvt, -1);
01328          pvt = NULL;
01329       }
01330    }
01331 
01332    if (owner) {
01333       ast_mutex_unlock(&owner->lock);
01334    }
01335 
01336    if (callno & 0x4000) {
01337       update_max_trunk();
01338    }
01339 }
01340 
01341 static void pvt_destructor(void *obj)
01342 {
01343    struct chan_iax2_pvt *pvt = obj;
01344    struct iax_frame *cur = NULL;
01345 
01346    iax2_destroy_helper(pvt);
01347 
01348    /* Already gone */
01349    ast_set_flag(pvt, IAX_ALREADYGONE); 
01350 
01351    AST_LIST_LOCK(&iaxq.queue);
01352    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01353       /* Cancel any pending transmissions */
01354       if (cur->callno == pvt->callno) { 
01355          cur->retries = -1;
01356       }
01357    }
01358    AST_LIST_UNLOCK(&iaxq.queue);
01359 
01360    if (pvt->reg) {
01361       pvt->reg->callno = 0;
01362    }
01363 
01364    if (!pvt->owner) {
01365       jb_frame frame;
01366       if (pvt->vars) {
01367           ast_variables_destroy(pvt->vars);
01368           pvt->vars = NULL;
01369       }
01370 
01371       while (jb_getall(pvt->jb, &frame) == JB_OK) {
01372          iax2_frame_free(frame.data);
01373       }
01374 
01375       jb_destroy(pvt->jb);
01376       ast_string_field_free_memory(pvt);
01377    }
01378 }
01379 
01380 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01381 {
01382    struct chan_iax2_pvt *tmp;
01383    jb_conf jbconf;
01384 
01385    if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01386       return NULL;
01387    }
01388 
01389    if (ast_string_field_init(tmp, 32)) {
01390       ao2_ref(tmp, -1);
01391       tmp = NULL;
01392       return NULL;
01393    }
01394       
01395    tmp->prefs = prefs;
01396    tmp->callno = 0;
01397    tmp->peercallno = 0;
01398    tmp->transfercallno = 0;
01399    tmp->bridgecallno = 0;
01400    tmp->pingid = -1;
01401    tmp->lagid = -1;
01402    tmp->autoid = -1;
01403    tmp->authid = -1;
01404    tmp->initid = -1;
01405 
01406    ast_string_field_set(tmp,exten, "s");
01407    ast_string_field_set(tmp,host, host);
01408 
01409    tmp->jb = jb_new();
01410    tmp->jbid = -1;
01411    jbconf.max_jitterbuf = maxjitterbuffer;
01412    jbconf.resync_threshold = resyncthreshold;
01413    jbconf.max_contig_interp = maxjitterinterps;
01414    jb_setconf(tmp->jb,&jbconf);
01415 
01416    return tmp;
01417 }
01418 
01419 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01420 {
01421    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01422    if (new) {
01423       size_t afdatalen = new->afdatalen;
01424       memcpy(new, fr, sizeof(*new));
01425       iax_frame_wrap(new, &fr->af);
01426       new->afdatalen = afdatalen;
01427       new->data = NULL;
01428       new->datalen = 0;
01429       new->direction = DIRECTION_INGRESS;
01430       new->retrans = -1;
01431    }
01432    return new;
01433 }
01434 
01435 #define NEW_PREVENT  0
01436 #define NEW_ALLOW    1
01437 #define NEW_FORCE    2
01438 
01439 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01440 {
01441    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01442       (cur->addr.sin_port == sin->sin_port)) {
01443       /* This is the main host */
01444       if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01445           (check_dcallno ? dcallno == cur->callno : 1) ) {
01446          /* That's us.  Be sure we keep track of the peer call number */
01447          return 1;
01448       }
01449    }
01450    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01451        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01452       /* We're transferring */
01453       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01454          return 1;
01455    }
01456    return 0;
01457 }
01458 
01459 static void update_max_nontrunk(void)
01460 {
01461    int max = 1;
01462    int x;
01463    /* XXX Prolly don't need locks here XXX */
01464    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01465       if (iaxs[x])
01466          max = x + 1;
01467    }
01468    maxnontrunkcall = max;
01469    if (option_debug && iaxdebug)
01470       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01471 }
01472 
01473 static int make_trunk(unsigned short callno, int locked)
01474 {
01475    int x;
01476    int res= 0;
01477    struct timeval now;
01478    if (iaxs[callno]->oseqno) {
01479       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01480       return -1;
01481    }
01482    if (callno & TRUNK_CALL_START) {
01483       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01484       return -1;
01485    }
01486    gettimeofday(&now, NULL);
01487    for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01488       ast_mutex_lock(&iaxsl[x]);
01489       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01490          iaxs[x] = iaxs[callno];
01491          iaxs[x]->callno = x;
01492          iaxs[callno] = NULL;
01493          /* Update the two timers that should have been started */
01494          AST_SCHED_DEL(sched, iaxs[x]->pingid);
01495          AST_SCHED_DEL(sched, iaxs[x]->lagid);
01496          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01497          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01498          if (locked)
01499             ast_mutex_unlock(&iaxsl[callno]);
01500          res = x;
01501          if (!locked)
01502             ast_mutex_unlock(&iaxsl[x]);
01503          break;
01504       }
01505       ast_mutex_unlock(&iaxsl[x]);
01506    }
01507    if (x >= ARRAY_LEN(iaxs) - 1) {
01508       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01509       return -1;
01510    }
01511    if (option_debug)
01512       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01513    /* We move this call from a non-trunked to a trunked call */
01514    update_max_trunk();
01515    update_max_nontrunk();
01516    return res;
01517 }
01518 
01519 /*!
01520  * \note Calling this function while holding another pvt lock can cause a deadlock.
01521  */
01522 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01523 {
01524    int res = 0;
01525    int x;
01526    struct timeval now;
01527    char host[80];
01528 
01529    if (new <= NEW_ALLOW) {
01530       if (callno) {
01531          struct chan_iax2_pvt *pvt;
01532          struct chan_iax2_pvt tmp_pvt = {
01533             .callno = dcallno,
01534             .peercallno = callno,
01535             /* hack!! */
01536             .frames_received = check_dcallno,
01537          };
01538  
01539          memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01540  
01541          if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01542             if (return_locked) {
01543                ast_mutex_lock(&iaxsl[pvt->callno]);
01544             }
01545             res = pvt->callno;
01546             ao2_ref(pvt, -1);
01547             pvt = NULL;
01548             return res;
01549          }
01550       }
01551 
01552       /* Look for an existing connection first */
01553       for (x = 1; !res && x < maxnontrunkcall; x++) {
01554          ast_mutex_lock(&iaxsl[x]);
01555          if (iaxs[x]) {
01556             /* Look for an exact match */
01557             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01558                res = x;
01559             }
01560          }
01561          if (!res || !return_locked)
01562             ast_mutex_unlock(&iaxsl[x]);
01563       }
01564       for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01565          ast_mutex_lock(&iaxsl[x]);
01566          if (iaxs[x]) {
01567             /* Look for an exact match */
01568             if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01569                res = x;
01570             }
01571          }
01572          if (!res || !return_locked)
01573             ast_mutex_unlock(&iaxsl[x]);
01574       }
01575    }
01576    if (!res && (new >= NEW_ALLOW)) {
01577       int start, found = 0;
01578 
01579       /* It may seem odd that we look through the peer list for a name for
01580        * this *incoming* call.  Well, it is weird.  However, users don't
01581        * have an IP address/port number that we can match against.  So,
01582        * this is just checking for a peer that has that IP/port and
01583        * assuming that we have a user of the same name.  This isn't always
01584        * correct, but it will be changed if needed after authentication. */
01585       if (!iax2_getpeername(*sin, host, sizeof(host)))
01586          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01587 
01588       now = ast_tvnow();
01589       start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01590       for (x = start; 1; x++) {
01591          if (x == TRUNK_CALL_START) {
01592             x = 1;
01593             continue;
01594          }
01595 
01596          /* Find first unused call number that hasn't been used in a while */
01597          ast_mutex_lock(&iaxsl[x]);
01598          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01599             found = 1;
01600             break;
01601          }
01602          ast_mutex_unlock(&iaxsl[x]);
01603          
01604          if (x == start - 1) {
01605             break;
01606          }
01607       }
01608       /* We've still got lock held if we found a spot */
01609       if (x == start - 1 && !found) {
01610          ast_log(LOG_WARNING, "No more space\n");
01611          return 0;
01612       }
01613       iaxs[x] = new_iax(sin, host);
01614       update_max_nontrunk();
01615       if (iaxs[x]) {
01616          if (option_debug && iaxdebug)
01617             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01618          iaxs[x]->sockfd = sockfd;
01619          iaxs[x]->addr.sin_port = sin->sin_port;
01620          iaxs[x]->addr.sin_family = sin->sin_family;
01621          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01622          iaxs[x]->peercallno = callno;
01623          iaxs[x]->callno = x;
01624          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01625          iaxs[x]->expiry = min_reg_expire;
01626          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01627          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01628          iaxs[x]->amaflags = amaflags;
01629          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01630          
01631          ast_string_field_set(iaxs[x], accountcode, accountcode);
01632          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01633          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01634 
01635          if (iaxs[x]->peercallno) {
01636             store_by_peercallno(iaxs[x]);
01637          }
01638       } else {
01639          ast_log(LOG_WARNING, "Out of resources\n");
01640          ast_mutex_unlock(&iaxsl[x]);
01641          return 0;
01642       }
01643       if (!return_locked)
01644          ast_mutex_unlock(&iaxsl[x]);
01645       res = x;
01646    }
01647    return res;
01648 }
01649 
01650 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01651 
01652    return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01653 }
01654 
01655 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01656 
01657    return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01658 }
01659 
01660 /*!
01661  * \brief Queue a frame to a call's owning asterisk channel
01662  *
01663  * \pre This function assumes that iaxsl[callno] is locked when called.
01664  *
01665  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01666  * was valid before calling it, it may no longer be valid after calling it.
01667  * This function may unlock and lock the mutex associated with this callno,
01668  * meaning that another thread may grab it and destroy the call.
01669  */
01670 static int iax2_queue_frame(int callno, struct ast_frame *f)
01671 {
01672    for (;;) {
01673       if (iaxs[callno] && iaxs[callno]->owner) {
01674          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01675             /* Avoid deadlock by pausing and trying again */
01676             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01677          } else {
01678             ast_queue_frame(iaxs[callno]->owner, f);
01679             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01680             break;
01681          }
01682       } else
01683          break;
01684    }
01685    return 0;
01686 }
01687 
01688 /*!
01689  * \brief Queue a hangup frame on the ast_channel owner
01690  *
01691  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01692  * is active for the given call number.
01693  *
01694  * \pre Assumes lock for callno is already held.
01695  *
01696  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01697  * was valid before calling it, it may no longer be valid after calling it.
01698  * This function may unlock and lock the mutex associated with this callno,
01699  * meaning that another thread may grab it and destroy the call.
01700  */
01701 static int iax2_queue_hangup(int callno)
01702 {
01703    for (;;) {
01704       if (iaxs[callno] && iaxs[callno]->owner) {
01705          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01706             /* Avoid deadlock by pausing and trying again */
01707             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01708          } else {
01709             ast_queue_hangup(iaxs[callno]->owner);
01710             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01711             break;
01712          }
01713       } else
01714          break;
01715    }
01716    return 0;
01717 }
01718 
01719 /*!
01720  * \brief Queue a control frame on the ast_channel owner
01721  *
01722  * This function queues a control frame on the owner of the IAX2 pvt struct that
01723  * is active for the given call number.
01724  *
01725  * \pre Assumes lock for callno is already held.
01726  *
01727  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01728  * was valid before calling it, it may no longer be valid after calling it.
01729  * This function may unlock and lock the mutex associated with this callno,
01730  * meaning that another thread may grab it and destroy the call.
01731  */
01732 static int iax2_queue_control_data(int callno, 
01733    enum ast_control_frame_type control, const void *data, size_t datalen)
01734 {
01735    for (;;) {
01736       if (iaxs[callno] && iaxs[callno]->owner) {
01737          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01738             /* Avoid deadlock by pausing and trying again */
01739             DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01740          } else {
01741             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01742             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01743             break;
01744          }
01745       } else
01746          break;
01747    }
01748    return 0;
01749 }
01750 static void destroy_firmware(struct iax_firmware *cur)
01751 {
01752    /* Close firmware */
01753    if (cur->fwh) {
01754       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01755    }
01756    close(cur->fd);
01757    free(cur);
01758 }
01759 
01760 static int try_firmware(char *s)
01761 {
01762    struct stat stbuf;
01763    struct iax_firmware *cur;
01764    int ifd;
01765    int fd;
01766    int res;
01767    
01768    struct ast_iax2_firmware_header *fwh, fwh2;
01769    struct MD5Context md5;
01770    unsigned char sum[16];
01771    unsigned char buf[1024];
01772    int len, chunk;
01773    char *s2;
01774    char *last;
01775    s2 = alloca(strlen(s) + 100);
01776    if (!s2) {
01777       ast_log(LOG_WARNING, "Alloca failed!\n");
01778       return -1;
01779    }
01780    last = strrchr(s, '/');
01781    if (last)
01782       last++;
01783    else
01784       last = s;
01785    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01786    res = stat(s, &stbuf);
01787    if (res < 0) {
01788       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01789       return -1;
01790    }
01791    /* Make sure it's not a directory */
01792    if (S_ISDIR(stbuf.st_mode))
01793       return -1;
01794    ifd = open(s, O_RDONLY);
01795    if (ifd < 0) {
01796       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01797       return -1;
01798    }
01799    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01800    if (fd < 0) {
01801       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01802       close(ifd);
01803       return -1;
01804    }
01805    /* Unlink our newly created file */
01806    unlink(s2);
01807    
01808    /* Now copy the firmware into it */
01809    len = stbuf.st_size;
01810    while(len) {
01811       chunk = len;
01812       if (chunk > sizeof(buf))
01813          chunk = sizeof(buf);
01814       res = read(ifd, buf, chunk);
01815       if (res != chunk) {
01816          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01817          close(ifd);
01818          close(fd);
01819          return -1;
01820       }
01821       res = write(fd, buf, chunk);
01822       if (res != chunk) {
01823          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01824          close(ifd);
01825          close(fd);
01826          return -1;
01827       }
01828       len -= chunk;
01829    }
01830    close(ifd);
01831    /* Return to the beginning */
01832    lseek(fd, 0, SEEK_SET);
01833    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01834       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01835       close(fd);
01836       return -1;
01837    }
01838    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01839       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01840       close(fd);
01841       return -1;
01842    }
01843    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01844       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01845       close(fd);
01846       return -1;
01847    }
01848    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01849       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01850       close(fd);
01851       return -1;
01852    }
01853    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01854    if (fwh == (void *) -1) {
01855       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01856       close(fd);
01857       return -1;
01858    }
01859    MD5Init(&md5);
01860    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01861    MD5Final(sum, &md5);
01862    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01863       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01864       munmap((void*)fwh, stbuf.st_size);
01865       close(fd);
01866       return -1;
01867    }
01868    cur = waresl.wares;
01869    while(cur) {
01870       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01871          /* Found a candidate */
01872          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01873             /* The version we have on loaded is older, load this one instead */
01874             break;
01875          /* This version is no newer than what we have.  Don't worry about it.
01876             We'll consider it a proper load anyhow though */
01877          munmap((void*)fwh, stbuf.st_size);
01878          close(fd);
01879          return 0;
01880       }
01881       cur = cur->next;
01882    }
01883    if (!cur) {
01884       /* Allocate a new one and link it */
01885       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01886          cur->fd = -1;
01887          cur->next = waresl.wares;
01888          waresl.wares = cur;
01889       }
01890    }
01891    if (cur) {
01892       if (cur->fwh) {
01893          munmap((void*)cur->fwh, cur->mmaplen);
01894       }
01895       if (cur->fd > -1)
01896          close(cur->fd);
01897       cur->fwh = fwh;
01898       cur->fd = fd;
01899       cur->mmaplen = stbuf.st_size;
01900       cur->dead = 0;
01901    }
01902    return 0;
01903 }
01904 
01905 static int iax_check_version(char *dev)
01906 {
01907    int res = 0;
01908    struct iax_firmware *cur;
01909    if (!ast_strlen_zero(dev)) {
01910       ast_mutex_lock(&waresl.lock);
01911       cur = waresl.wares;
01912       while(cur) {
01913          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01914             res = ntohs(cur->fwh->version);
01915             break;
01916          }
01917          cur = cur->next;
01918       }
01919       ast_mutex_unlock(&waresl.lock);
01920    }
01921    return res;
01922 }
01923 
01924 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01925 {
01926    int res = -1;
01927    unsigned int bs = desc & 0xff;
01928    unsigned int start = (desc >> 8) & 0xffffff;
01929    unsigned int bytes;
01930    struct iax_firmware *cur;
01931    if (!ast_strlen_zero((char *)dev) && bs) {
01932       start *= bs;
01933       ast_mutex_lock(&waresl.lock);
01934       cur = waresl.wares;
01935       while(cur) {
01936          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01937             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01938             if (start < ntohl(cur->fwh->datalen)) {
01939                bytes = ntohl(cur->fwh->datalen) - start;
01940                if (bytes > bs)
01941                   bytes = bs;
01942                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01943             } else {
01944                bytes = 0;
01945                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01946             }
01947             if (bytes == bs)
01948                res = 0;
01949             else
01950                res = 1;
01951             break;
01952          }
01953          cur = cur->next;
01954       }
01955       ast_mutex_unlock(&waresl.lock);
01956    }
01957    return res;
01958 }
01959 
01960 
01961 static void reload_firmware(int unload)
01962 {
01963    struct iax_firmware *cur, *curl, *curp;
01964    DIR *fwd;
01965    struct dirent *de;
01966    char dir[256];
01967    char fn[256];
01968    /* Mark all as dead */
01969    ast_mutex_lock(&waresl.lock);
01970    cur = waresl.wares;
01971    while(cur) {
01972       cur->dead = 1;
01973       cur = cur->next;
01974    }
01975 
01976    /* Now that we've freed them, load the new ones */
01977    if (!unload) {
01978       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01979       fwd = opendir(dir);
01980       if (fwd) {
01981          while((de = readdir(fwd))) {
01982             if (de->d_name[0] != '.') {
01983                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01984                if (!try_firmware(fn)) {
01985                   if (option_verbose > 1)
01986                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01987                }
01988             }
01989          }
01990          closedir(fwd);
01991       } else 
01992          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01993    }
01994 
01995    /* Clean up leftovers */
01996    cur = waresl.wares;
01997    curp = NULL;
01998    while(cur) {
01999       curl = cur;
02000       cur = cur->next;
02001       if (curl->dead) {
02002          if (curp) {
02003             curp->next = cur;
02004          } else {
02005             waresl.wares = cur;
02006          }
02007          destroy_firmware(curl);
02008       } else {
02009          curp = cur;
02010       }
02011    }
02012    ast_mutex_unlock(&waresl.lock);
02013 }
02014 
02015 /*!
02016  * \note This function assumes that iaxsl[callno] is locked when called.
02017  *
02018  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02019  * was valid before calling it, it may no longer be valid after calling it.
02020  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
02021  * associated with this callno, meaning that another thread may grab it and destroy the call.
02022  */
02023 static int __do_deliver(void *data)
02024 {
02025    /* Just deliver the packet by using queueing.  This is called by
02026      the IAX thread with the iaxsl lock held. */
02027    struct iax_frame *fr = data;
02028    fr->retrans = -1;
02029    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02030    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02031       iax2_queue_frame(fr->callno, &fr->af);
02032    /* Free our iax frame */
02033    iax2_frame_free(fr);
02034    /* And don't run again */
02035    return 0;
02036 }
02037 
02038 static int handle_error(void)
02039 {
02040    /* XXX Ideally we should figure out why an error occured and then abort those
02041       rather than continuing to try.  Unfortunately, the published interface does
02042       not seem to work XXX */
02043 #if 0
02044    struct sockaddr_in *sin;
02045    int res;
02046    struct msghdr m;
02047    struct sock_extended_err e;
02048    m.msg_name = NULL;
02049    m.msg_namelen = 0;
02050    m.msg_iov = NULL;
02051    m.msg_control = &e;
02052    m.msg_controllen = sizeof(e);
02053    m.msg_flags = 0;
02054    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02055    if (res < 0)
02056       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02057    else {
02058       if (m.msg_controllen) {
02059          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02060          if (sin) 
02061             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02062          else
02063             ast_log(LOG_WARNING, "No address detected??\n");
02064       } else {
02065          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02066       }
02067    }
02068 #endif
02069    return 0;
02070 }
02071 
02072 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02073 {
02074    int res;
02075    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02076                sizeof(*sin));
02077    if (res < 0) {
02078       if (option_debug)
02079          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02080       handle_error();
02081    } else
02082       res = 0;
02083    return res;
02084 }
02085 
02086 static int send_packet(struct iax_frame *f)
02087 {
02088    int res;
02089    int callno = f->callno;
02090 
02091    /* Don't send if there was an error, but return error instead */
02092    if (!callno || !iaxs[callno] || iaxs[callno]->error)
02093        return -1;
02094    
02095    /* Called with iaxsl held */
02096    if (option_debug > 2 && iaxdebug)
02097       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));
02098    if (f->transfer) {
02099       if (iaxdebug)
02100          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02101       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02102                sizeof(iaxs[callno]->transfer));
02103    } else {
02104       if (iaxdebug)
02105          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02106       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02107                sizeof(iaxs[callno]->addr));
02108    }
02109    if (res < 0) {
02110       if (option_debug && iaxdebug)
02111          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02112       handle_error();
02113    } else
02114       res = 0;
02115    return res;
02116 }
02117 
02118 /*!
02119  * \note Since this function calls iax2_queue_hangup(), the pvt struct
02120  *       for the given call number may disappear during its execution.
02121  */
02122 static int iax2_predestroy(int callno)
02123 {
02124    struct ast_channel *c;
02125    struct chan_iax2_pvt *pvt = iaxs[callno];
02126 
02127    if (!pvt)
02128       return -1;
02129    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02130       iax2_destroy_helper(pvt);
02131       ast_set_flag(pvt, IAX_ALREADYGONE); 
02132    }
02133    c = pvt->owner;
02134    if (c) {
02135       c->tech_pvt = NULL;
02136       iax2_queue_hangup(callno);
02137       pvt->owner = NULL;
02138       ast_module_unref(ast_module_info->self);
02139    }
02140    return 0;
02141 }
02142 
02143 static int update_packet(struct iax_frame *f)
02144 {
02145    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02146    struct ast_iax2_full_hdr *fh = f->data;
02147    struct ast_frame af;
02148 
02149    /* if frame is encrypted. decrypt before updating it. */
02150    if (f->encmethods) {
02151       decode_frame(&f->mydcx, fh, &af, &f->datalen);
02152    }
02153    /* Mark this as a retransmission */
02154    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02155    /* Update iseqno */
02156    f->iseqno = iaxs[f->callno]->iseqno;
02157    fh->iseqno = f->iseqno;
02158 
02159    /* Now re-encrypt the frame */
02160    if (f->encmethods) {
02161       encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02162    }
02163    return 0;
02164 }
02165 
02166 static int attempt_transmit(const void *data);
02167 static void __attempt_transmit(const void *data)
02168 {
02169    /* Attempt to transmit the frame to the remote peer...
02170       Called without iaxsl held. */
02171    struct iax_frame *f = (struct iax_frame *)data;
02172    int freeme=0;
02173    int callno = f->callno;
02174    /* Make sure this call is still active */
02175    if (callno) 
02176       ast_mutex_lock(&iaxsl[callno]);
02177    if (callno && iaxs[callno]) {
02178       if ((f->retries < 0) /* Already ACK'd */ ||
02179           (f->retries >= max_retries) /* Too many attempts */) {
02180             /* Record an error if we've transmitted too many times */
02181             if (f->retries >= max_retries) {
02182                if (f->transfer) {
02183                   /* Transfer timeout */
02184                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02185                } else if (f->final) {
02186                   if (f->final) 
02187                      iax2_destroy(callno);
02188                } else {
02189                   if (iaxs[callno]->owner)
02190                      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);
02191                   iaxs[callno]->error = ETIMEDOUT;
02192                   if (iaxs[callno]->owner) {
02193                      struct ast_frame fr = { 0, };
02194                      /* Hangup the fd */
02195                      fr.frametype = AST_FRAME_CONTROL;
02196                      fr.subclass = AST_CONTROL_HANGUP;
02197                      iax2_queue_frame(callno, &fr); // XXX
02198                      /* Remember, owner could disappear */
02199                      if (iaxs[callno] && iaxs[callno]->owner)
02200                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02201                   } else {
02202                      if (iaxs[callno]->reg) {
02203                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02204                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02205                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02206                      }
02207                      iax2_destroy(callno);
02208                   }
02209                }
02210 
02211             }
02212             freeme++;
02213       } else {
02214          /* Update it if it needs it */
02215          update_packet(f);
02216          /* Attempt transmission */
02217          send_packet(f);
02218          f->retries++;
02219          /* Try again later after 10 times as long */
02220          f->retrytime *= 10;
02221          if (f->retrytime > MAX_RETRY_TIME)
02222             f->retrytime = MAX_RETRY_TIME;
02223          /* Transfer messages max out at one second */
02224          if (f->transfer && (f->retrytime > 1000))
02225             f->retrytime = 1000;
02226          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02227       }
02228    } else {
02229       /* Make sure it gets freed */
02230       f->retries = -1;
02231       freeme++;
02232    }
02233    if (callno)
02234       ast_mutex_unlock(&iaxsl[callno]);
02235    /* Do not try again */
02236    if (freeme) {
02237       /* Don't attempt delivery, just remove it from the queue */
02238       AST_LIST_LOCK(&iaxq.queue);
02239       AST_LIST_REMOVE(&iaxq.queue, f, list);
02240       iaxq.count--;
02241       AST_LIST_UNLOCK(&iaxq.queue);
02242       f->retrans = -1;
02243       /* Free the IAX frame */
02244       iax2_frame_free(f);
02245    }
02246 }
02247 
02248 static int attempt_transmit(const void *data)
02249 {
02250 #ifdef SCHED_MULTITHREADED
02251    if (schedule_action(__attempt_transmit, data))
02252 #endif      
02253       __attempt_transmit(data);
02254    return 0;
02255 }
02256 
02257 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02258 {
02259    struct iax2_peer *peer;
02260 
02261    if (argc != 4)
02262         return RESULT_SHOWUSAGE;
02263    if (!strcmp(argv[3],"all")) {
02264       reload_config();
02265       ast_cli(fd, "OK cache is flushed.\n");
02266    } else if ((peer = find_peer(argv[3], 0))) {
02267       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02268          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02269          expire_registry(peer_ref(peer));
02270          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02271       } else {
02272          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02273       }
02274       peer_unref(peer);
02275    } else {
02276       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02277    }
02278    
02279    return RESULT_SUCCESS;
02280 }
02281 
02282 static int iax2_test_losspct(int fd, int argc, char *argv[])
02283 {
02284        if (argc != 4)
02285                return RESULT_SHOWUSAGE;
02286 
02287        test_losspct = atoi(argv[3]);
02288 
02289        return RESULT_SUCCESS;
02290 }
02291 
02292 #ifdef IAXTESTS
02293 static int iax2_test_late(int fd, int argc, char *argv[])
02294 {
02295    if (argc != 4)
02296       return RESULT_SHOWUSAGE;
02297 
02298    test_late = atoi(argv[3]);
02299 
02300    return RESULT_SUCCESS;
02301 }
02302 
02303 static int iax2_test_resync(int fd, int argc, char *argv[])
02304 {
02305    if (argc != 4)
02306       return RESULT_SHOWUSAGE;
02307 
02308    test_resync = atoi(argv[3]);
02309 
02310    return RESULT_SUCCESS;
02311 }
02312 
02313 static int iax2_test_jitter(int fd, int argc, char *argv[])
02314 {
02315    if (argc < 4 || argc > 5)
02316       return RESULT_SHOWUSAGE;
02317 
02318    test_jit = atoi(argv[3]);
02319    if (argc == 5) 
02320       test_jitpct = atoi(argv[4]);
02321 
02322    return RESULT_SUCCESS;
02323 }
02324 #endif /* IAXTESTS */
02325 
02326 /*! \brief  peer_status: Report Peer status in character string */
02327 /*    returns 1 if peer is online, -1 if unmonitored */
02328 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02329 {
02330    int res = 0;
02331    if (peer->maxms) {
02332       if (peer->lastms < 0) {
02333          ast_copy_string(status, "UNREACHABLE", statuslen);
02334       } else if (peer->lastms > peer->maxms) {
02335          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02336          res = 1;
02337       } else if (peer->lastms) {
02338          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02339          res = 1;
02340       } else {
02341          ast_copy_string(status, "UNKNOWN", statuslen);
02342       }
02343    } else { 
02344       ast_copy_string(status, "Unmonitored", statuslen);
02345       res = -1;
02346    }
02347    return res;
02348 }
02349 
02350 /*! \brief Show one peer in detail */
02351 static int iax2_show_peer(int fd, int argc, char *argv[])
02352 {
02353    char status[30];
02354    char cbuf[256];
02355    struct iax2_peer *peer;
02356    char codec_buf[512];
02357    int x = 0, codec = 0, load_realtime = 0;
02358 
02359    if (argc < 4)
02360       return RESULT_SHOWUSAGE;
02361 
02362    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02363 
02364    peer = find_peer(argv[3], load_realtime);
02365    if (peer) {
02366       ast_cli(fd,"\n\n");
02367       ast_cli(fd, "  * Name       : %s\n", peer->name);
02368       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02369       ast_cli(fd, "  Context      : %s\n", peer->context);
02370       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02371       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02372       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02373       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02374       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02375       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));
02376       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02377       ast_cli(fd, "  Username     : %s\n", peer->username);
02378       ast_cli(fd, "  Codecs       : ");
02379       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02380       ast_cli(fd, "%s\n", codec_buf);
02381 
02382       ast_cli(fd, "  Codec Order  : (");
02383       for(x = 0; x < 32 ; x++) {
02384          codec = ast_codec_pref_index(&peer->prefs,x);
02385          if(!codec)
02386             break;
02387          ast_cli(fd, "%s", ast_getformatname(codec));
02388          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02389             ast_cli(fd, "|");
02390       }
02391 
02392       if (!x)
02393          ast_cli(fd, "none");
02394       ast_cli(fd, ")\n");
02395 
02396       ast_cli(fd, "  Status       : ");
02397       peer_status(peer, status, sizeof(status));   
02398       ast_cli(fd, "%s\n",status);
02399       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02400       ast_cli(fd,"\n");
02401       peer_unref(peer);
02402    } else {
02403       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02404       ast_cli(fd,"\n");
02405    }
02406 
02407    return RESULT_SUCCESS;
02408 }
02409 
02410 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02411 {
02412    int which = 0;
02413    struct iax2_peer *peer;
02414    char *res = NULL;
02415    int wordlen = strlen(word);
02416    struct ao2_iterator i;
02417 
02418    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02419    if (pos != 3)
02420       return NULL;
02421 
02422    i = ao2_iterator_init(peers, 0);
02423    while ((peer = ao2_iterator_next(&i))) {
02424       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02425          res = ast_strdup(peer->name);
02426          peer_unref(peer);
02427          break;
02428       }
02429       peer_unref(peer);
02430    }
02431 
02432    return res;
02433 }
02434 
02435 static int iax2_show_stats(int fd, int argc, char *argv[])
02436 {
02437    struct iax_frame *cur;
02438    int cnt = 0, dead=0, final=0;
02439 
02440    if (argc != 3)
02441       return RESULT_SHOWUSAGE;
02442 
02443    AST_LIST_LOCK(&iaxq.queue);
02444    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02445       if (cur->retries < 0)
02446          dead++;
02447       if (cur->final)
02448          final++;
02449       cnt++;
02450    }
02451    AST_LIST_UNLOCK(&iaxq.queue);
02452 
02453    ast_cli(fd, "    IAX Statistics\n");
02454    ast_cli(fd, "---------------------\n");
02455    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02456    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02457    
02458    return RESULT_SUCCESS;
02459 }
02460 
02461 static int iax2_show_cache(int fd, int argc, char *argv[])
02462 {
02463    struct iax2_dpcache *dp;
02464    char tmp[1024], *pc;
02465    int s;
02466    int x,y;
02467    struct timeval tv;
02468    gettimeofday(&tv, NULL);
02469    ast_mutex_lock(&dpcache_lock);
02470    dp = dpcache;
02471    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02472    while(dp) {
02473       s = dp->expiry.tv_sec - tv.tv_sec;
02474       tmp[0] = '\0';
02475       if (dp->flags & CACHE_FLAG_EXISTS)
02476          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02477       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02478          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02479       if (dp->flags & CACHE_FLAG_CANEXIST)
02480          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02481       if (dp->flags & CACHE_FLAG_PENDING)
02482          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02483       if (dp->flags & CACHE_FLAG_TIMEOUT)
02484          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02485       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02486          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02487       if (dp->flags & CACHE_FLAG_MATCHMORE)
02488          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02489       if (dp->flags & CACHE_FLAG_UNKNOWN)
02490          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02491       /* Trim trailing pipe */
02492       if (!ast_strlen_zero(tmp))
02493          tmp[strlen(tmp) - 1] = '\0';
02494       else
02495          ast_copy_string(tmp, "(none)", sizeof(tmp));
02496       y=0;
02497       pc = strchr(dp->peercontext, '@');
02498       if (!pc)
02499          pc = dp->peercontext;
02500       else
02501          pc++;
02502       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02503          if (dp->waiters[x] > -1)
02504             y++;
02505       if (s > 0)
02506          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02507       else
02508          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02509       dp = dp->next;
02510    }
02511    ast_mutex_unlock(&dpcache_lock);
02512    return RESULT_SUCCESS;
02513 }
02514 
02515 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02516 
02517 static void unwrap_timestamp(struct iax_frame *fr)
02518 {
02519    int x;
02520 
02521    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02522       x = fr->ts - iaxs[fr->callno]->last;
02523       if (x < -50000) {
02524          /* Sudden big jump backwards in timestamp:
02525             What likely happened here is that miniframe timestamp has circled but we haven't
02526             gotten the update from the main packet.  We'll just pretend that we did, and
02527             update the timestamp appropriately. */
02528          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02529          if (option_debug && iaxdebug)
02530             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02531       }
02532       if (x > 50000) {
02533          /* Sudden apparent big jump forwards in timestamp:
02534             What's likely happened is this is an old miniframe belonging to the previous
02535             top-16-bit timestamp that has turned up out of order.
02536             Adjust the timestamp appropriately. */
02537          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02538          if (option_debug && iaxdebug)
02539             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02540       }
02541    }
02542 }
02543 
02544 static int get_from_jb(const void *p);
02545 
02546 static void update_jbsched(struct chan_iax2_pvt *pvt)
02547 {
02548    int when;
02549    
02550    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02551    
02552    when = jb_next(pvt->jb) - when;
02553 
02554    AST_SCHED_DEL(sched, pvt->jbid);
02555 
02556    if(when <= 0) {
02557       /* XXX should really just empty until when > 0.. */
02558       when = 1;
02559    }
02560    
02561    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02562 }
02563 
02564 static void __get_from_jb(const void *p) 
02565 {
02566    int callno = PTR_TO_CALLNO(p);
02567    struct chan_iax2_pvt *pvt = NULL;
02568    struct iax_frame *fr;
02569    jb_frame frame;
02570    int ret;
02571    long now;
02572    long next;
02573    struct timeval tv;
02574    
02575    /* Make sure we have a valid private structure before going on */
02576    ast_mutex_lock(&iaxsl[callno]);
02577    pvt = iaxs[callno];
02578    if (!pvt) {
02579       /* No go! */
02580       ast_mutex_unlock(&iaxsl[callno]);
02581       return;
02582    }
02583 
02584    pvt->jbid = -1;
02585    
02586    gettimeofday(&tv,NULL);
02587    /* round up a millisecond since ast_sched_runq does; */
02588    /* prevents us from spinning while waiting for our now */
02589    /* to catch up with runq's now */
02590    tv.tv_usec += 1000;
02591    
02592    now = ast_tvdiff_ms(tv, pvt->rxcore);
02593    
02594    if(now >= (next = jb_next(pvt->jb))) {
02595       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02596       switch(ret) {
02597       case JB_OK:
02598          fr = frame.data;
02599          __do_deliver(fr);
02600          /* __do_deliver() can cause the call to disappear */
02601          pvt = iaxs[callno];
02602          break;
02603       case JB_INTERP:
02604       {
02605          struct ast_frame af = { 0, };
02606          
02607          /* create an interpolation frame */
02608          af.frametype = AST_FRAME_VOICE;
02609          af.subclass = pvt->voiceformat;
02610          af.samples  = frame.ms * 8;
02611          af.src  = "IAX2 JB interpolation";
02612          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02613          af.offset = AST_FRIENDLY_OFFSET;
02614          
02615          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02616           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02617          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02618             iax2_queue_frame(callno, &af);
02619             /* iax2_queue_frame() could cause the call to disappear */
02620             pvt = iaxs[callno];
02621          }
02622       }
02623          break;
02624       case JB_DROP:
02625          iax2_frame_free(frame.data);
02626          break;
02627       case JB_NOFRAME:
02628       case JB_EMPTY:
02629          /* do nothing */
02630          break;
02631       default:
02632          /* shouldn't happen */
02633          break;
02634       }
02635    }
02636    if (pvt)
02637       update_jbsched(pvt);
02638    ast_mutex_unlock(&iaxsl[callno]);
02639 }
02640 
02641 static int get_from_jb(const void *data)
02642 {
02643 #ifdef SCHED_MULTITHREADED
02644    if (schedule_action(__get_from_jb, data))
02645 #endif      
02646       __get_from_jb(data);
02647    return 0;
02648 }
02649 
02650 /*!
02651  * \note This function assumes fr->callno is locked
02652  *
02653  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02654  * was valid before calling it, it may no longer be valid after calling it.
02655  */
02656 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02657 {
02658    int type, len;
02659    int ret;
02660    int needfree = 0;
02661    struct ast_channel *owner = NULL;
02662    struct ast_channel *bridge = NULL;
02663    
02664    /* Attempt to recover wrapped timestamps */
02665    unwrap_timestamp(fr);
02666 
02667    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02668    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02669       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02670    else {
02671 #if 0
02672       if (option_debug)
02673          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02674 #endif
02675       fr->af.delivery = ast_tv(0,0);
02676    }
02677 
02678    type = JB_TYPE_CONTROL;
02679    len = 0;
02680 
02681    if(fr->af.frametype == AST_FRAME_VOICE) {
02682       type = JB_TYPE_VOICE;
02683       len = ast_codec_get_samples(&fr->af) / 8;
02684    } else if(fr->af.frametype == AST_FRAME_CNG) {
02685       type = JB_TYPE_SILENCE;
02686    }
02687 
02688    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02689       if (tsout)
02690          *tsout = fr->ts;
02691       __do_deliver(fr);
02692       return -1;
02693    }
02694 
02695    if ((owner = iaxs[fr->callno]->owner))
02696       bridge = ast_bridged_channel(owner);
02697 
02698    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02699     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02700    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02701       jb_frame frame;
02702 
02703       /* deliver any frames in the jb */
02704       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02705          __do_deliver(frame.data);
02706          /* __do_deliver() can make the call disappear */
02707          if (!iaxs[fr->callno])
02708             return -1;
02709       }
02710 
02711       jb_reset(iaxs[fr->callno]->jb);
02712 
02713       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02714 
02715       /* deliver this frame now */
02716       if (tsout)
02717          *tsout = fr->ts;
02718       __do_deliver(fr);
02719       return -1;
02720    }
02721 
02722    /* insert into jitterbuffer */
02723    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02724    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02725          calc_rxstamp(iaxs[fr->callno],fr->ts));
02726    if (ret == JB_DROP) {
02727       needfree++;
02728    } else if (ret == JB_SCHED) {
02729       update_jbsched(iaxs[fr->callno]);
02730    }
02731    if (tsout)
02732       *tsout = fr->ts;
02733    if (needfree) {
02734       /* Free our iax frame */
02735       iax2_frame_free(fr);
02736       return -1;
02737    }
02738    return 0;
02739 }
02740 
02741 static int iax2_transmit(struct iax_frame *fr)
02742 {
02743    /* Lock the queue and place this packet at the end */
02744    /* By setting this to 0, the network thread will send it for us, and
02745       queue retransmission if necessary */
02746    fr->sentyet = 0;
02747    AST_LIST_LOCK(&iaxq.queue);
02748    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02749    iaxq.count++;
02750    AST_LIST_UNLOCK(&iaxq.queue);
02751    /* Wake up the network and scheduler thread */
02752    if (netthreadid != AST_PTHREADT_NULL)
02753       pthread_kill(netthreadid, SIGURG);
02754    signal_condition(&sched_lock, &sched_cond);
02755    return 0;
02756 }
02757 
02758 
02759 
02760 static int iax2_digit_begin(struct ast_channel *c, char digit)
02761 {
02762    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02763 }
02764 
02765 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02766 {
02767    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02768 }
02769 
02770 static int iax2_sendtext(struct ast_channel *c, const char *text)
02771 {
02772    
02773    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02774       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02775 }
02776 
02777 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02778 {
02779    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02780 }
02781 
02782 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02783 {
02784    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02785 }
02786 
02787 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02788 {
02789    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02790    ast_mutex_lock(&iaxsl[callno]);
02791    if (iaxs[callno])
02792       iaxs[callno]->owner = newchan;
02793    else
02794       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02795    ast_mutex_unlock(&iaxsl[callno]);
02796    return 0;
02797 }
02798 
02799 /*!
02800  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02801  *       so do not call this with a pvt lock held.
02802  */
02803 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02804 {
02805    struct ast_variable *var = NULL;
02806    struct ast_variable *tmp;
02807    struct iax2_peer *peer=NULL;
02808    time_t regseconds = 0, nowtime;
02809    int dynamic=0;
02810 
02811    if (peername) {
02812       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02813       if (!var && sin)
02814          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02815    } else if (sin) {
02816       char porta[25];
02817       sprintf(porta, "%d", ntohs(sin->sin_port));
02818       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02819       if (var) {
02820          /* We'll need the peer name in order to build the structure! */
02821          for (tmp = var; tmp; tmp = tmp->next) {
02822             if (!strcasecmp(tmp->name, "name"))
02823                peername = tmp->value;
02824          }
02825       }
02826    }
02827    if (!var && peername) { /* Last ditch effort */
02828       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02829       /*!\note
02830        * If this one loaded something, then we need to ensure that the host
02831        * field matched.  The only reason why we can't have this as a criteria
02832        * is because we only have the IP address and the host field might be
02833        * set as a name (and the reverse PTR might not match).
02834        */
02835       if (var && sin) {
02836          for (tmp = var; tmp; tmp = tmp->next) {
02837             if (!strcasecmp(tmp->name, "host")) {
02838                struct ast_hostent ahp;
02839                struct hostent *hp;
02840                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02841                   /* No match */
02842                   ast_variables_destroy(var);
02843                   var = NULL;
02844                }
02845                break;
02846             }
02847          }
02848       }
02849    }
02850    if (!var)
02851       return NULL;
02852 
02853    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02854    
02855    if (!peer) {
02856       ast_variables_destroy(var);
02857       return NULL;
02858    }
02859 
02860    for (tmp = var; tmp; tmp = tmp->next) {
02861       /* Make sure it's not a user only... */
02862       if (!strcasecmp(tmp->name, "type")) {
02863          if (strcasecmp(tmp->value, "friend") &&
02864              strcasecmp(tmp->value, "peer")) {
02865             /* Whoops, we weren't supposed to exist! */
02866             peer = peer_unref(peer);
02867             break;
02868          } 
02869       } else if (!strcasecmp(tmp->name, "regseconds")) {
02870          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02871       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02872          inet_aton(tmp->value, &(peer->addr.sin_addr));
02873       } else if (!strcasecmp(tmp->name, "port")) {
02874          peer->addr.sin_port = htons(atoi(tmp->value));
02875       } else if (!strcasecmp(tmp->name, "host")) {
02876          if (!strcasecmp(tmp->value, "dynamic"))
02877             dynamic = 1;
02878       }
02879    }
02880 
02881    ast_variables_destroy(var);
02882 
02883    if (!peer)
02884       return NULL;
02885 
02886    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02887       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02888       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02889          if (peer->expire > -1) {
02890             if (!ast_sched_del(sched, peer->expire)) {
02891                peer->expire = -1;
02892                peer_unref(peer);
02893             }
02894          }
02895          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02896          if (peer->expire == -1)
02897             peer_unref(peer);
02898       }
02899       ao2_link(peers, peer);
02900       if (ast_test_flag(peer, IAX_DYNAMIC))
02901          reg_source_db(peer);
02902    } else {
02903       ast_set_flag(peer, IAX_TEMPONLY);   
02904    }
02905 
02906    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02907       time(&nowtime);
02908       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02909          memset(&peer->addr, 0, sizeof(peer->addr));
02910          realtime_update_peer(peer->name, &peer->addr, 0);
02911          if (option_debug)
02912             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02913                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02914       }
02915       else {
02916          if (option_debug)
02917             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02918                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02919       }
02920    }
02921 
02922    return peer;
02923 }
02924 
02925 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02926 {
02927    struct ast_variable *var;
02928    struct ast_variable *tmp;
02929    struct iax2_user *user=NULL;
02930 
02931    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02932    if (!var)
02933       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02934    if (!var && sin) {
02935       char porta[6];
02936       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02937       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02938       if (!var)
02939          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02940    }
02941    if (!var) { /* Last ditch effort */
02942       var = ast_load_realtime("iaxusers", "name", username, NULL);
02943       /*!\note
02944        * If this one loaded something, then we need to ensure that the host
02945        * field matched.  The only reason why we can't have this as a criteria
02946        * is because we only have the IP address and the host field might be
02947        * set as a name (and the reverse PTR might not match).
02948        */
02949       if (var) {
02950          for (tmp = var; tmp; tmp = tmp->next) {
02951             if (!strcasecmp(tmp->name, "host")) {
02952                struct ast_hostent ahp;
02953                struct hostent *hp;
02954                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02955                   /* No match */
02956                   ast_variables_destroy(var);
02957                   var = NULL;
02958                }
02959                break;
02960             }
02961          }
02962       }
02963    }
02964    if (!var)
02965       return NULL;
02966 
02967    tmp = var;
02968    while(tmp) {
02969       /* Make sure it's not a peer only... */
02970       if (!strcasecmp(tmp->name, "type")) {
02971          if (strcasecmp(tmp->value, "friend") &&
02972              strcasecmp(tmp->value, "user")) {
02973             return NULL;
02974          } 
02975       }
02976       tmp = tmp->next;
02977    }
02978 
02979    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02980 
02981    ast_variables_destroy(var);
02982 
02983    if (!user)
02984       return NULL;
02985 
02986    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02987       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02988       ao2_link(users, user);
02989    } else {
02990       ast_set_flag(user, IAX_TEMPONLY);   
02991    }
02992 
02993    return user;
02994 }
02995 
02996 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02997 {
02998    char port[10];
02999    char regseconds[20];
03000    
03001    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03002    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03003    ast_update_realtime("iaxpeers", "name", peername, 
03004       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
03005       "regseconds", regseconds, NULL);
03006 }
03007 
03008 struct create_addr_info {
03009    int capability;
03010    unsigned int flags;
03011    int maxtime;
03012    int encmethods;
03013    int found;
03014    int sockfd;
03015    int adsi;
03016    char username[80];
03017    char secret[80];
03018    char outkey[80];
03019    char timezone[80];
03020    char prefs[32];
03021    char context[AST_MAX_CONTEXT];
03022    char peercontext[AST_MAX_CONTEXT];
03023    char mohinterpret[MAX_MUSICCLASS];
03024    char mohsuggest[MAX_MUSICCLASS];
03025 };
03026 
03027 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03028 {
03029    struct ast_hostent ahp;
03030    struct hostent *hp;
03031    struct iax2_peer *peer;
03032    int res = -1;
03033    struct ast_codec_pref ourprefs;
03034 
03035    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03036    cai->sockfd = defaultsockfd;
03037    cai->maxtime = 0;
03038    sin->sin_family = AF_INET;
03039 
03040    if (!(peer = find_peer(peername, 1))) {
03041       cai->found = 0;
03042 
03043       hp = ast_gethostbyname(peername, &ahp);
03044       if (hp) {
03045          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03046          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03047          /* use global iax prefs for unknown peer/user */
03048          /* But move the calling channel's native codec to the top of the preference list */
03049          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03050          if (c)
03051             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03052          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03053          return 0;
03054       } else {
03055          ast_log(LOG_WARNING, "No such host: %s\n", peername);
03056          return -1;
03057       }
03058    }
03059 
03060    cai->found = 1;
03061    
03062    /* if the peer has no address (current or default), return failure */
03063    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03064       goto return_unref;
03065 
03066    /* if the peer is being monitored and is currently unreachable, return failure */
03067    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03068       goto return_unref;
03069 
03070    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03071    cai->maxtime = peer->maxms;
03072    cai->capability = peer->capability;
03073    cai->encmethods = peer->encmethods;
03074    cai->sockfd = peer->sockfd;
03075    cai->adsi = peer->adsi;
03076    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03077    /* Move the calling channel's native codec to the top of the preference list */
03078    if (c) {
03079       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03080       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03081    }
03082    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03083    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03084    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03085    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03086    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03087    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03088    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03089    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03090    if (ast_strlen_zero(peer->dbsecret)) {
03091       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03092    } else {
03093       char *family;
03094       char *key = NULL;
03095 
03096       family = ast_strdupa(peer->dbsecret);
03097       key = strchr(family, '/');
03098       if (key)
03099          *key++ = '\0';
03100       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03101          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03102          goto return_unref;
03103       }
03104    }
03105 
03106    if (peer->addr.sin_addr.s_addr) {
03107       sin->sin_addr = peer->addr.sin_addr;
03108       sin->sin_port = peer->addr.sin_port;
03109    } else {
03110       sin->sin_addr = peer->defaddr.sin_addr;
03111       sin->sin_port = peer->defaddr.sin_port;
03112    }
03113 
03114    res = 0;
03115 
03116 return_unref:
03117    peer_unref(peer);
03118 
03119    return res;
03120 }
03121 
03122 static void __auto_congest(const void *nothing)
03123 {
03124    int callno = PTR_TO_CALLNO(nothing);
03125    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03126    ast_mutex_lock(&iaxsl[callno]);
03127    if (iaxs[callno]) {
03128       iaxs[callno]->initid = -1;
03129       iax2_queue_frame(callno, &f);
03130       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03131    }
03132    ast_mutex_unlock(&iaxsl[callno]);
03133 }
03134 
03135 static int auto_congest(const void *data)
03136 {
03137 #ifdef SCHED_MULTITHREADED
03138    if (schedule_action(__auto_congest, data))
03139 #endif      
03140       __auto_congest(data);
03141    return 0;
03142 }
03143 
03144 static unsigned int iax2_datetime(const char *tz)
03145 {
03146    time_t t;
03147    struct tm tm;
03148    unsigned int tmp;
03149    time(&t);
03150    if (!ast_strlen_zero(tz))
03151       ast_localtime(&t, &tm, tz);
03152    else
03153       ast_localtime(&t, &tm, NULL);
03154    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03155    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03156    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03157    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03158    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03159    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03160    return tmp;
03161 }
03162 
03163 struct parsed_dial_string {
03164    char *username;
03165    char *password;
03166    char *key;
03167    char *peer;
03168    char *port;
03169    char *exten;
03170    char *context;
03171    char *options;
03172 };
03173 
03174 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03175 {
03176    struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03177       .ts = htonl(ts), .iseqno = seqno, .oseqno = seqno, .type = AST_FRAME_IAX,
03178       .csub = compress_subclass(command) };
03179 
03180    return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03181 }
03182 
03183 /*!
03184  * \brief Parses an IAX dial string into its component parts.
03185  * \param data the string to be parsed
03186  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03187  * \return nothing
03188  *
03189  * This function parses the string and fills the structure
03190  * with pointers to its component parts. The input string
03191  * will be modified.
03192  *
03193  * \note This function supports both plaintext passwords and RSA
03194  * key names; if the password string is formatted as '[keyname]',
03195  * then the keyname will be placed into the key field, and the
03196  * password field will be set to NULL.
03197  *
03198  * \note The dial string format is:
03199  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03200  */
03201 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03202 {
03203    if (ast_strlen_zero(data))
03204       return;
03205 
03206    pds->peer = strsep(&data, "/");
03207    pds->exten = strsep(&data, "/");
03208    pds->options = data;
03209 
03210    if (pds->exten) {
03211       data = pds->exten;
03212       pds->exten = strsep(&data, "@");
03213       pds->context = data;
03214    }
03215 
03216    if (strchr(pds->peer, '@')) {
03217       data = pds->peer;
03218       pds->username = strsep(&data, "@");
03219       pds->peer = data;
03220    }
03221 
03222    if (pds->username) {
03223       data = pds->username;
03224       pds->username = strsep(&data, ":");
03225       pds->password = data;
03226    }
03227 
03228    data = pds->peer;
03229    pds->peer = strsep(&data, ":");
03230    pds->port = data;
03231 
03232    /* check for a key name wrapped in [] in the secret position, if found,
03233       move it to the key field instead
03234    */
03235    if (pds->password && (pds->password[0] == '[')) {
03236       pds->key = ast_strip_quoted(pds->password, "[", "]");
03237       pds->password = NULL;
03238    }
03239 }
03240 
03241 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03242 {
03243    struct sockaddr_in sin;
03244    char *l=NULL, *n=NULL, *tmpstr;
03245    struct iax_ie_data ied;
03246    char *defaultrdest = "s";
03247    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03248    struct parsed_dial_string pds;
03249    struct create_addr_info cai;
03250 
03251    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03252       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03253       return -1;
03254    }
03255 
03256    memset(&cai, 0, sizeof(cai));
03257    cai.encmethods = iax2_encryption;
03258 
03259    memset(&pds, 0, sizeof(pds));
03260    tmpstr = ast_strdupa(dest);
03261    parse_dial_string(tmpstr, &pds);
03262 
03263    if (ast_strlen_zero(pds.peer)) {
03264       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03265       return -1;
03266    }
03267 
03268    if (!pds.exten) {
03269       pds.exten = defaultrdest;
03270    }
03271 
03272    if (create_addr(pds.peer, c, &sin, &cai)) {
03273       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03274       return -1;
03275    }
03276 
03277    if (!pds.username && !ast_strlen_zero(cai.username))
03278       pds.username = cai.username;
03279    if (!pds.password && !ast_strlen_zero(cai.secret))
03280       pds.password = cai.secret;
03281    if (!pds.key && !ast_strlen_zero(cai.outkey))
03282       pds.key = cai.outkey;
03283    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03284       pds.context = cai.peercontext;
03285 
03286    /* Keep track of the context for outgoing calls too */
03287    ast_copy_string(c->context, cai.context, sizeof(c->context));
03288 
03289    if (pds.port)
03290       sin.sin_port = htons(atoi(pds.port));
03291 
03292    l = c->cid.cid_num;
03293    n = c->cid.cid_name;
03294 
03295    /* Now build request */ 
03296    memset(&ied, 0, sizeof(ied));
03297 
03298    /* On new call, first IE MUST be IAX version of caller */
03299    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03300    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03301    if (pds.options && strchr(pds.options, 'a')) {
03302       /* Request auto answer */
03303       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03304    }
03305 
03306    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03307 
03308    if (l) {
03309       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03310       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03311    } else {
03312       if (n)
03313          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03314       else
03315          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03316    }
03317 
03318    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03319    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03320 
03321    if (n)
03322       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03323    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03324       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03325 
03326    if (!ast_strlen_zero(c->language))
03327       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03328    if (!ast_strlen_zero(c->cid.cid_dnid))
03329       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03330    if (!ast_strlen_zero(c->cid.cid_rdnis))
03331       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03332 
03333    if (pds.context)
03334       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03335 
03336    if (pds.username)
03337       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03338 
03339    if (cai.encmethods)
03340       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03341 
03342    ast_mutex_lock(&iaxsl[callno]);
03343 
03344    if (!ast_strlen_zero(c->context))
03345       ast_string_field_set(iaxs[callno], context, c->context);
03346 
03347    if (pds.username)
03348       ast_string_field_set(iaxs[callno], username, pds.username);
03349 
03350    iaxs[callno]->encmethods = cai.encmethods;
03351 
03352    iaxs[callno]->adsi = cai.adsi;
03353    
03354    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03355    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03356 
03357    if (pds.key)
03358       ast_string_field_set(iaxs[callno], outkey, pds.key);
03359    if (pds.password)
03360       ast_string_field_set(iaxs[callno], secret, pds.password);
03361 
03362    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03363    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03364    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03365    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03366 
03367    if (iaxs[callno]->maxtime) {
03368       /* Initialize pingtime and auto-congest time */
03369       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03370       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03371    } else if (autokill) {
03372       iaxs[callno]->pingtime = autokill / 2;
03373       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03374    }
03375 
03376    /* send the command using the appropriate socket for this peer */
03377    iaxs[callno]->sockfd = cai.sockfd;
03378 
03379    /* Transmit the string in a "NEW" request */
03380    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03381 
03382    ast_mutex_unlock(&iaxsl[callno]);
03383    ast_setstate(c, AST_STATE_RINGING);
03384    
03385    return 0;
03386 }
03387 
03388 static int iax2_hangup(struct ast_channel *c) 
03389 {
03390    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03391    int alreadygone;
03392    struct iax_ie_data ied;
03393    memset(&ied, 0, sizeof(ied));
03394    ast_mutex_lock(&iaxsl[callno]);
03395    if (callno && iaxs[callno]) {
03396       if (option_debug)
03397          ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03398       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03399       /* Send the hangup unless we have had a transmission error or are already gone */
03400       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03401       if (!iaxs[callno]->error && !alreadygone) {
03402          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03403          if (!iaxs[callno]) {
03404             ast_mutex_unlock(&iaxsl[callno]);
03405             return 0;
03406          }
03407       }
03408       /* Explicitly predestroy it */
03409       iax2_predestroy(callno);
03410       /* If we were already gone to begin with, destroy us now */
03411       if (alreadygone && iaxs[callno]) {
03412          if (option_debug)
03413             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03414          iax2_destroy(callno);
03415       }
03416    }
03417    ast_mutex_unlock(&iaxsl[callno]);
03418    if (option_verbose > 2) 
03419       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03420    return 0;
03421 }
03422 
03423 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03424 {
03425    struct ast_option_header *h;
03426    int res;
03427 
03428    switch (option) {
03429    case AST_OPTION_TXGAIN:
03430    case AST_OPTION_RXGAIN:
03431       /* these two cannot be sent, because they require a result */
03432       errno = ENOSYS;
03433       return -1;
03434    default:
03435       if (!(h = ast_malloc(datalen + sizeof(*h))))
03436          return -1;
03437 
03438       h->flag = AST_OPTION_FLAG_REQUEST;
03439       h->option = htons(option);
03440       memcpy(h->data, data, datalen);
03441       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03442                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03443                  datalen + sizeof(*h), -1);
03444       free(h);
03445       return res;
03446    }
03447 }
03448 
03449 static struct ast_frame *iax2_read(struct ast_channel *c) 
03450 {
03451    if (option_verbose > 3)
03452        ast_log(LOG_NOTICE, "I should never be called!\n");
03453    return &ast_null_frame;
03454 }
03455 
03456 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03457 {
03458    int res;
03459    struct iax_ie_data ied0;
03460    struct iax_ie_data ied1;
03461    unsigned int transferid = (unsigned int)ast_random();
03462    memset(&ied0, 0, sizeof(ied0));
03463    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03464    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03465    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03466 
03467    memset(&ied1, 0, sizeof(ied1));
03468    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03469    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03470    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03471    
03472    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03473    if (res)
03474       return -1;
03475    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03476    if (res)
03477       return -1;
03478    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03479    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03480    return 0;
03481 }
03482 
03483 static void lock_both(unsigned short callno0, unsigned short callno1)
03484 {
03485    ast_mutex_lock(&iaxsl[callno0]);
03486    while (ast_mutex_trylock(&iaxsl[callno1])) {
03487       DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03488    }
03489 }
03490 
03491 static void unlock_both(unsigned short callno0, unsigned short callno1)
03492 {
03493    ast_mutex_unlock(&iaxsl[callno1]);
03494    ast_mutex_unlock(&iaxsl[callno0]);
03495 }
03496 
03497 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)
03498 {
03499    struct ast_channel *cs[3];
03500    struct ast_channel *who, *other;
03501    int to = -1;
03502    int res = -1;
03503    int transferstarted=0;
03504    struct ast_frame *f;
03505    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03506    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03507    struct timeval waittimer = {0, 0}, tv;
03508 
03509    lock_both(callno0, callno1);
03510    if (!iaxs[callno0] || !iaxs[callno1]) {
03511       unlock_both(callno0, callno1);
03512       return AST_BRIDGE_FAILED;
03513    }
03514    /* Put them in native bridge mode */
03515    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03516       iaxs[callno0]->bridgecallno = callno1;
03517       iaxs[callno1]->bridgecallno = callno0;
03518    }
03519    unlock_both(callno0, callno1);
03520 
03521    /* If not, try to bridge until we can execute a transfer, if we can */
03522    cs[0] = c0;
03523    cs[1] = c1;
03524    for (/* ever */;;) {
03525       /* Check in case we got masqueraded into */
03526       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03527          if (option_verbose > 2)
03528             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03529          /* Remove from native mode */
03530          if (c0->tech == &iax2_tech) {
03531             ast_mutex_lock(&iaxsl[callno0]);
03532             iaxs[callno0]->bridgecallno = 0;
03533             ast_mutex_unlock(&iaxsl[callno0]);
03534          }
03535          if (c1->tech == &iax2_tech) {
03536             ast_mutex_lock(&iaxsl[callno1]);
03537             iaxs[callno1]->bridgecallno = 0;
03538             ast_mutex_unlock(&iaxsl[callno1]);
03539          }
03540          return AST_BRIDGE_FAILED_NOWARN;
03541       }
03542       if (c0->nativeformats != c1->nativeformats) {
03543          if (option_verbose > 2) {
03544             char buf0[255];
03545             char buf1[255];
03546             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03547             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03548             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03549          }
03550          /* Remove from native mode */
03551          lock_both(callno0, callno1);
03552          if (iaxs[callno0])
03553             iaxs[callno0]->bridgecallno = 0;
03554          if (iaxs[callno1])
03555             iaxs[callno1]->bridgecallno = 0;
03556          unlock_both(callno0, callno1);
03557          return AST_BRIDGE_FAILED_NOWARN;
03558       }
03559       /* check if transfered and if we really want native bridging */
03560       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03561          /* Try the transfer */
03562          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03563                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03564             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03565          transferstarted = 1;
03566       }
03567       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03568          /* Call has been transferred.  We're no longer involved */
03569          gettimeofday(&tv, NULL);
03570          if (ast_tvzero(waittimer)) {
03571             waittimer = tv;
03572          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03573             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03574             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03575             *fo = NULL;
03576             *rc = c0;
03577             res = AST_BRIDGE_COMPLETE;
03578             break;
03579          }
03580       }
03581       to = 1000;
03582       who = ast_waitfor_n(cs, 2, &to);
03583       if (timeoutms > -1) {
03584          timeoutms -= (1000 - to);
03585          if (timeoutms < 0)
03586             timeoutms = 0;
03587       }
03588       if (!who) {
03589          if (!timeoutms) {
03590             res = AST_BRIDGE_RETRY;
03591             break;
03592          }
03593          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03594             res = AST_BRIDGE_FAILED;
03595             break;
03596          }
03597          continue;
03598       }
03599       f = ast_read(who);
03600       if (!f) {
03601          *fo = NULL;
03602          *rc = who;
03603          res = AST_BRIDGE_COMPLETE;
03604          break;
03605       }
03606       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03607          *fo = f;
03608          *rc = who;
03609          res =  AST_BRIDGE_COMPLETE;
03610          break;
03611       }
03612       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03613       if ((f->frametype == AST_FRAME_VOICE) ||
03614           (f->frametype == AST_FRAME_TEXT) ||
03615           (f->frametype == AST_FRAME_VIDEO) || 
03616           (f->frametype == AST_FRAME_IMAGE) ||
03617           (f->frametype == AST_FRAME_DTMF)) {
03618          /* monitored dtmf take out of the bridge.
03619           * check if we monitor the specific source.
03620           */
03621          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03622          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03623             *rc = who;
03624             *fo = f;
03625             res = AST_BRIDGE_COMPLETE;
03626             /* Remove from native mode */
03627             break;
03628          }
03629          /* everything else goes to the other side */
03630          ast_write(other, f);
03631       }
03632       ast_frfree(f);
03633       /* Swap who gets priority */
03634       cs[2] = cs[0];
03635       cs[0] = cs[1];
03636       cs[1] = cs[2];
03637    }
03638    lock_both(callno0, callno1);
03639    if(iaxs[callno0])
03640       iaxs[callno0]->bridgecallno = 0;
03641    if(iaxs[callno1])
03642       iaxs[callno1]->bridgecallno = 0;
03643    unlock_both(callno0, callno1);
03644    return res;
03645 }
03646 
03647 static int iax2_answer(struct ast_channel *c)
03648 {
03649    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03650    if (option_debug)
03651       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03652    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03653 }
03654 
03655 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03656 {
03657    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03658    struct chan_iax2_pvt *pvt;
03659    int res = 0;
03660 
03661    if (option_debug && iaxdebug)
03662       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03663 
03664    ast_mutex_lock(&iaxsl[callno]);
03665    pvt = iaxs[callno];
03666 
03667    if (!pvt->peercallno) {
03668       /* We don't know the remote side's call number, yet.  :( */
03669       int count = 10;
03670       while (count-- && pvt && !pvt->peercallno) {
03671          DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03672          pvt = iaxs[callno];
03673       }
03674       if (!pvt->peercallno) {
03675          res = -1;
03676          goto done;
03677       }
03678    }
03679 
03680    switch (condition) {
03681    case AST_CONTROL_HOLD:
03682       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03683          ast_moh_start(c, data, pvt->mohinterpret);
03684          goto done;
03685       }
03686       break;
03687    case AST_CONTROL_UNHOLD:
03688       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03689          ast_moh_stop(c);
03690          goto done;
03691       }
03692    }
03693 
03694    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03695 
03696 done:
03697    ast_mutex_unlock(&iaxsl[callno]);
03698 
03699    return res;
03700 }
03701    
03702 static int iax2_transfer(struct ast_channel *c, const char *dest)
03703 {
03704    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03705    struct iax_ie_data ied;
03706    char tmp[256], *context;
03707    ast_copy_string(tmp, dest, sizeof(tmp));
03708    context = strchr(tmp, '@');
03709    if (context) {
03710       *context = '\0';
03711       context++;
03712    }
03713    memset(&ied, 0, sizeof(ied));
03714    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03715    if (context)
03716       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03717    if (option_debug)
03718       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03719    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03720 }
03721    
03722 static int iax2_getpeertrunk(struct sockaddr_in sin)
03723 {
03724    struct iax2_peer *peer;
03725    int res = 0;
03726    struct ao2_iterator i;
03727 
03728    i = ao2_iterator_init(peers, 0);
03729    while ((peer = ao2_iterator_next(&i))) {
03730       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03731           (peer->addr.sin_port == sin.sin_port)) {
03732          res = ast_test_flag(peer, IAX_TRUNK);
03733          peer_unref(peer);
03734          break;
03735       }
03736       peer_unref(peer);
03737    }
03738 
03739    return res;
03740 }
03741 
03742 /*! \brief  Create new call, interface with the PBX core */
03743 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03744 {
03745    struct ast_channel *tmp;
03746    struct chan_iax2_pvt *i;
03747    struct ast_variable *v = NULL;
03748 
03749    if (!(i = iaxs[callno])) {
03750       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03751       return NULL;
03752    }
03753 
03754    /* Don't hold call lock */
03755    ast_mutex_unlock(&iaxsl[callno]);
03756    tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
03757    ast_mutex_lock(&iaxsl[callno]);
03758    if (!iaxs[callno]) {
03759       if (tmp) {
03760          ast_channel_free(tmp);
03761       }
03762       ast_mutex_unlock(&iaxsl[callno]);
03763       return NULL;
03764    }
03765 
03766    if (!tmp)
03767       return NULL;
03768    tmp->tech = &iax2_tech;
03769    /* We can support any format by default, until we get restricted */
03770    tmp->nativeformats = capability;
03771    tmp->readformat = ast_best_codec(capability);
03772    tmp->writeformat = ast_best_codec(capability);
03773    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03774 
03775    /* Don't use ast_set_callerid() here because it will
03776     * generate a NewCallerID event before the NewChannel event */
03777    if (!ast_strlen_zero(i->ani))
03778       tmp->cid.cid_ani = ast_strdup(i->ani);
03779    else
03780       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03781    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03782    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03783    tmp->cid.cid_pres = i->calling_pres;
03784    tmp->cid.cid_ton = i->calling_ton;
03785    tmp->cid.cid_tns = i->calling_tns;
03786    if (!ast_strlen_zero(i->language))
03787       ast_string_field_set(tmp, language, i->language);
03788    if (!ast_strlen_zero(i->accountcode))
03789       ast_string_field_set(tmp, accountcode, i->accountcode);
03790    if (i->amaflags)
03791       tmp->amaflags = i->amaflags;
03792    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03793    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03794    if (i->adsi)
03795       tmp->adsicpe = i->peeradsicpe;
03796    else
03797       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03798    i->owner = tmp;
03799    i->capability = capability;
03800 
03801    for (v = i->vars ; v ; v = v->next)
03802       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03803 
03804    if (state != AST_STATE_DOWN) {
03805       if (ast_pbx_start(tmp)) {
03806          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03807          ast_hangup(tmp);
03808          i->owner = NULL;
03809          return NULL;
03810       }
03811    }
03812 
03813    ast_module_ref(ast_module_info->self);
03814    
03815    return tmp;
03816 }
03817 
03818 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03819 {
03820    unsigned long int mssincetx; /* unsigned to handle overflows */
03821    long int ms, pred;
03822 
03823    tpeer->trunkact = *tv;
03824    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03825    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03826       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03827       tpeer->txtrunktime = *tv;
03828       tpeer->lastsent = 999999;
03829    }
03830    /* Update last transmit time now */
03831    tpeer->lasttxtime = *tv;
03832    
03833    /* Calculate ms offset */
03834    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03835    /* Predict from last value */
03836    pred = tpeer->lastsent + sampms;
03837    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03838       ms = pred;
03839    
03840    /* We never send the same timestamp twice, so fudge a little if we must */
03841    if (ms == tpeer->lastsent)
03842       ms = tpeer->lastsent + 1;
03843    tpeer->lastsent = ms;
03844    return ms;
03845 }
03846 
03847 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03848 {
03849    long ms; /* NOT unsigned */
03850    if (ast_tvzero(iaxs[callno]->rxcore)) {
03851       /* Initialize rxcore time if appropriate */
03852       gettimeofday(&iaxs[callno]->rxcore, NULL);
03853       /* Round to nearest 20ms so traces look pretty */
03854       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03855    }
03856    /* Calculate difference between trunk and channel */
03857    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03858    /* Return as the sum of trunk time and the difference between trunk and real time */
03859    return ms + ts;
03860 }
03861 
03862 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03863 {
03864    int ms;
03865    int voice = 0;
03866    int genuine = 0;
03867    int adjust;
03868    struct timeval *delivery = NULL;
03869 
03870 
03871    /* What sort of frame do we have?: voice is self-explanatory
03872       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03873       non-genuine frames are CONTROL frames [ringing etc], DTMF
03874       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03875       the others need a timestamp slaved to the voice frames so that they go in sequence
03876    */
03877    if (f) {
03878       if (f->frametype == AST_FRAME_VOICE) {
03879          voice = 1;
03880          delivery = &f->delivery;
03881       } else if (f->frametype == AST_FRAME_IAX) {
03882          genuine = 1;
03883       } else if (f->frametype == AST_FRAME_CNG) {
03884          p->notsilenttx = 0;  
03885       }
03886    }
03887    if (ast_tvzero(p->offset)) {
03888       gettimeofday(&p->offset, NULL);
03889       /* Round to nearest 20ms for nice looking traces */
03890       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03891    }
03892    /* If the timestamp is specified, just send it as is */
03893    if (ts)
03894       return ts;
03895    /* If we have a time that the frame arrived, always use it to make our timestamp */
03896    if (delivery && !ast_tvzero(*delivery)) {
03897       ms = ast_tvdiff_ms(*delivery, p->offset);
03898       if (option_debug > 2 && iaxdebug)
03899          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03900    } else {
03901       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03902       if (ms < 0)
03903          ms = 0;
03904       if (voice) {
03905          /* On a voice frame, use predicted values if appropriate */
03906          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03907             /* Adjust our txcore, keeping voice and non-voice synchronized */
03908             /* AN EXPLANATION:
03909                When we send voice, we usually send "calculated" timestamps worked out
03910                on the basis of the number of samples sent. When we send other frames,
03911                we usually send timestamps worked out from the real clock.
03912                The problem is that they can tend to drift out of step because the 
03913                   source channel's clock and our clock may not be exactly at the same rate.
03914                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03915                for this call.  Moving it adjusts timestamps for non-voice frames.
03916                We make the adjustment in the style of a moving average.  Each time we
03917                adjust p->offset by 10% of the difference between our clock-derived
03918                timestamp and the predicted timestamp.  That's why you see "10000"
03919                below even though IAX2 timestamps are in milliseconds.
03920                The use of a moving average avoids offset moving too radically.
03921                Generally, "adjust" roams back and forth around 0, with offset hardly
03922                changing at all.  But if a consistent different starts to develop it
03923                will be eliminated over the course of 10 frames (200-300msecs) 
03924             */
03925             adjust = (ms - p->nextpred);
03926             if (adjust < 0)
03927                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03928             else if (adjust > 0)
03929                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03930 
03931             if (!p->nextpred) {
03932                p->nextpred = ms; /*f->samples / 8;*/
03933                if (p->nextpred <= p->lastsent)
03934                   p->nextpred = p->lastsent + 3;
03935             }
03936             ms = p->nextpred;
03937          } else {
03938                 /* in this case, just use the actual
03939             * time, since we're either way off
03940             * (shouldn't happen), or we're  ending a
03941             * silent period -- and seed the next
03942             * predicted time.  Also, round ms to the
03943             * next multiple of frame size (so our
03944             * silent periods are multiples of
03945             * frame size too) */
03946 
03947             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03948                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03949                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03950 
03951             if (f->samples >= 8) /* check to make sure we dont core dump */
03952             {
03953                int diff = ms % (f->samples / 8);
03954                if (diff)
03955                    ms += f->samples/8 - diff;
03956             }
03957 
03958             p->nextpred = ms;
03959             p->notsilenttx = 1;
03960          }
03961       } else if ( f->frametype == AST_FRAME_VIDEO ) {
03962          /*
03963          * IAX2 draft 03 says that timestamps MUST be in order.
03964          * It does not say anything about several frames having the same timestamp
03965          * When transporting video, we can have a frame that spans multiple iax packets
03966          * (so called slices), so it would make sense to use the same timestamp for all of
03967          * them
03968          * We do want to make sure that frames don't go backwards though
03969          */
03970          if ( (unsigned int)ms < p->lastsent )
03971             ms = p->lastsent;
03972       } else {
03973          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03974             it's a genuine frame */
03975          if (genuine) {
03976             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03977             if (ms <= p->lastsent)
03978                ms = p->lastsent + 3;
03979          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03980             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03981             ms = p->lastsent + 3;
03982          }
03983       }
03984    }
03985    p->lastsent = ms;
03986    if (voice)
03987       p->nextpred = p->nextpred + f->samples / 8;
03988    return ms;
03989 }
03990 
03991 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03992 {
03993    /* Returns where in "receive time" we are.  That is, how many ms
03994       since we received (or would have received) the frame with timestamp 0 */
03995    int ms;
03996 #ifdef IAXTESTS
03997    int jit;
03998 #endif /* IAXTESTS */
03999    /* Setup rxcore if necessary */
04000    if (ast_tvzero(p->rxcore)) {
04001       p->rxcore = ast_tvnow();
04002       if (option_debug && iaxdebug)
04003          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04004                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04005       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04006 #if 1
04007       if (option_debug && iaxdebug)
04008          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04009                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04010 #endif
04011    }
04012 
04013    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04014 #ifdef IAXTESTS
04015    if (test_jit) {
04016       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04017          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04018          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04019             jit = -jit;
04020          ms += jit;
04021       }
04022    }
04023    if (test_late) {
04024       ms += test_late;
04025       test_late = 0;
04026    }
04027 #endif /* IAXTESTS */
04028    return ms;
04029 }
04030 
04031 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04032 {
04033    struct iax2_trunk_peer *tpeer;
04034    
04035    /* Finds and locks trunk peer */
04036    ast_mutex_lock(&tpeerlock);
04037    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04038       /* We don't lock here because tpeer->addr *never* changes */
04039       if (!inaddrcmp(&tpeer->addr, sin)) {
04040          ast_mutex_lock(&tpeer->lock);
04041          break;
04042       }
04043    }
04044    if (!tpeer) {
04045       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04046          ast_mutex_init(&tpeer->lock);
04047          tpeer->lastsent = 9999;
04048          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04049          tpeer->trunkact = ast_tvnow();
04050          ast_mutex_lock(&tpeer->lock);
04051          tpeer->next = tpeers;
04052          tpeer->sockfd = fd;
04053          tpeers = tpeer;
04054 #ifdef SO_NO_CHECK
04055          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04056 #endif
04057          if (option_debug)
04058             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04059       }
04060    }
04061    ast_mutex_unlock(&tpeerlock);
04062    return tpeer;
04063 }
04064 
04065 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04066 {
04067    struct ast_frame *f;
04068    struct iax2_trunk_peer *tpeer;
04069    void *tmp, *ptr;
04070    struct ast_iax2_meta_trunk_entry *met;
04071    struct ast_iax2_meta_trunk_mini *mtm;
04072 
04073    f = &fr->af;
04074    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04075    if (tpeer) {
04076       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04077          /* Need to reallocate space */
04078          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04079             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04080                ast_mutex_unlock(&tpeer->lock);
04081                return -1;
04082             }
04083             
04084             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04085             tpeer->trunkdata = tmp;
04086             if (option_debug)
04087                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);
04088          } else {
04089             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));
04090             ast_mutex_unlock(&tpeer->lock);
04091             return -1;
04092          }
04093       }
04094 
04095       /* Append to meta frame */
04096       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04097       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04098          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04099          mtm->len = htons(f->datalen);
04100          mtm->mini.callno = htons(pvt->callno);
04101          mtm->mini.ts = htons(0xffff & fr->ts);
04102          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04103          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04104       } else {
04105          met = (struct ast_iax2_meta_trunk_entry *)ptr;
04106          /* Store call number and length in meta header */
04107          met->callno = htons(pvt->callno);
04108          met->len = htons(f->datalen);
04109          /* Advance pointers/decrease length past trunk entry header */
04110          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04111          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04112       }
04113       /* Copy actual trunk data */
04114       memcpy(ptr, f->data, f->datalen);
04115       tpeer->trunkdatalen += f->datalen;
04116 
04117       tpeer->calls++;
04118       ast_mutex_unlock(&tpeer->lock);
04119    }
04120    return 0;
04121 }
04122 
04123 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04124 {
04125    build_ecx_key(digest, pvt);
04126    aes_decrypt_key128(digest, &pvt->dcx);
04127 }
04128   
04129 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04130 {
04131    /* it is required to hold the corresponding decrypt key to our encrypt key
04132     * in the pvt struct because queued frames occasionally need to be decrypted and
04133     * re-encrypted when updated for a retransmission */
04134    aes_encrypt_key128(digest, &pvt->ecx);
04135    aes_decrypt_key128(digest, &pvt->mydcx);
04136 }
04137 
04138 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04139 {
04140 #if 0
04141    /* Debug with "fake encryption" */
04142    int x;
04143    if (len % 16)
04144       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04145    for (x=0;x<len;x++)
04146       dst[x] = src[x] ^ 0xff;
04147 #else 
04148    unsigned char lastblock[16] = { 0 };
04149    int x;
04150    while(len > 0) {
04151       aes_decrypt(src, dst, dcx);
04152       for (x=0;x<16;x++)
04153          dst[x] ^= lastblock[x];
04154       memcpy(lastblock, src, sizeof(lastblock));
04155       dst += 16;
04156       src += 16;
04157       len -= 16;
04158    }
04159 #endif
04160 }
04161 
04162 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04163 {
04164 #if 0
04165    /* Debug with "fake encryption" */
04166    int x;
04167    if (len % 16)
04168       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04169    for (x=0;x<len;x++)
04170       dst[x] = src[x] ^ 0xff;
04171 #else
04172    unsigned char curblock[16] = { 0 };
04173    int x;
04174    while(len > 0) {
04175       for (x=0;x<16;x++)
04176          curblock[x] ^= src[x];
04177       aes_encrypt(curblock, dst, ecx);
04178       memcpy(curblock, dst, sizeof(curblock)); 
04179       dst += 16;
04180       src += 16;
04181       len -= 16;
04182    }
04183 #endif
04184 }
04185 
04186 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04187 {
04188    int padding;
04189    unsigned char *workspace;
04190 
04191    workspace = alloca(*datalen);
04192    memset(f, 0, sizeof(*f));
04193    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04194       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04195       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04196          return -1;
04197       /* Decrypt */
04198       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04199 
04200       padding = 16 + (workspace[15] & 0xf);
04201       if (option_debug && iaxdebug)
04202          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04203       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04204          return -1;
04205 
04206       *datalen -= padding;
04207       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04208       f->frametype = fh->type;
04209       if (f->frametype == AST_FRAME_VIDEO) {
04210          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04211       } else {
04212          f->subclass = uncompress_subclass(fh->csub);
04213       }
04214    } else {
04215       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04216       if (option_debug && iaxdebug)
04217          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04218       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04219          return -1;
04220       /* Decrypt */
04221       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04222       padding = 16 + (workspace[15] & 0x0f);
04223       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04224          return -1;
04225       *datalen -= padding;
04226       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04227    }
04228    return 0;
04229 }
04230 
04231 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04232 {
04233    int padding;
04234    unsigned char *workspace;
04235    workspace = alloca(*datalen + 32);
04236    if (!workspace)
04237       return -1;
04238    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04239       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04240       if (option_debug && iaxdebug)
04241          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04242       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04243       padding = 16 + (padding & 0xf);
04244       memcpy(workspace, poo, padding);
04245       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04246       workspace[15] &= 0xf0;
04247       workspace[15] |= (padding & 0xf);
04248       if (option_debug && iaxdebug)
04249          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]);
04250       *datalen += padding;
04251       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04252       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04253          memcpy(poo, workspace + *datalen - 32, 32);
04254    } else {
04255       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04256       if (option_debug && iaxdebug)
04257          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04258       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04259       padding = 16 + (padding & 0xf);
04260       memcpy(workspace, poo, padding);
04261       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04262       workspace[15] &= 0xf0;
04263       workspace[15] |= (padding & 0x0f);
04264       *datalen += padding;
04265       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04266       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04267          memcpy(poo, workspace + *datalen - 32, 32);
04268    }
04269    return 0;
04270 }
04271 
04272 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04273 {
04274    int res=-1;
04275    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04276       /* Search for possible keys, given secrets */
04277       struct MD5Context md5;
04278       unsigned char digest[16];
04279       char *tmppw, *stringp;
04280       
04281       tmppw = ast_strdupa(iaxs[callno]->secret);
04282       stringp = tmppw;
04283       while ((tmppw = strsep(&stringp, ";"))) {
04284          MD5Init(&md5);
04285          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04286          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04287          MD5Final(digest, &md5);
04288          build_encryption_keys(digest, iaxs[callno]);
04289          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04290          if (!res) {
04291             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04292             break;
04293          }
04294       }
04295    } else 
04296       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04297    return res;
04298 }
04299 
04300 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04301 {
04302    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04303       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04304       or delayed, with retransmission */
04305    struct ast_iax2_full_hdr *fh;
04306    struct ast_iax2_mini_hdr *mh;
04307    struct ast_iax2_video_hdr *vh;
04308    struct {
04309       struct iax_frame fr2;
04310       unsigned char buffer[4096];
04311    } frb;
04312    struct iax_frame *fr;
04313    int res;
04314    int sendmini=0;
04315    unsigned int lastsent;
04316    unsigned int fts;
04317 
04318    frb.fr2.afdatalen = sizeof(frb.buffer);
04319 
04320    if (!pvt) {
04321       ast_log(LOG_WARNING, "No private structure for packet?\n");
04322       return -1;
04323    }
04324    
04325    lastsent = pvt->lastsent;
04326 
04327    /* Calculate actual timestamp */
04328    fts = calc_timestamp(pvt, ts, f);
04329 
04330    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04331     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04332     * increment the "predicted timestamps" for voice, if we're predecting */
04333    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04334        return 0;
04335 
04336 
04337    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04338          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04339          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04340       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04341        (f->frametype == AST_FRAME_VOICE) 
04342       /* is a voice frame */ &&
04343       (f->subclass == pvt->svoiceformat) 
04344       /* is the same type */ ) {
04345          /* Force immediate rather than delayed transmission */
04346          now = 1;
04347          /* Mark that mini-style frame is appropriate */
04348          sendmini = 1;
04349    }
04350    if ( f->frametype == AST_FRAME_VIDEO ) {
04351       /*
04352        * If the lower 15 bits of the timestamp roll over, or if
04353        * the video format changed then send a full frame.
04354        * Otherwise send a mini video frame
04355        */
04356       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04357           ((f->subclass & ~0x1) == pvt->svideoformat)
04358          ) {
04359          now = 1;
04360          sendmini = 1;
04361       } else {
04362          now = 0;
04363          sendmini = 0;
04364       }
04365       pvt->lastvsent = fts;
04366    }
04367    /* Allocate an iax_frame */
04368    if (now) {
04369       fr = &frb.fr2;
04370    } else
04371       fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
04372    if (!fr) {
04373       ast_log(LOG_WARNING, "Out of memory\n");
04374       return -1;
04375    }
04376    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04377    iax_frame_wrap(fr, f);
04378 
04379    fr->ts = fts;
04380    fr->callno = pvt->callno;
04381    fr->transfer = transfer;
04382    fr->final = final;
04383    fr->encmethods = 0;
04384    if (!sendmini) {
04385       /* We need a full frame */
04386       if (seqno > -1)
04387          fr->oseqno = seqno;
04388       else
04389          fr->oseqno = pvt->oseqno++;
04390       fr->iseqno = pvt->iseqno;
04391       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04392       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04393       fh->ts = htonl(fr->ts);
04394       fh->oseqno = fr->oseqno;
04395       if (transfer) {
04396          fh->iseqno = 0;
04397       } else
04398          fh->iseqno = fr->iseqno;
04399       /* Keep track of the last thing we've acknowledged */
04400       if (!transfer)
04401          pvt->aseqno = fr->iseqno;
04402       fh->type = fr->af.frametype & 0xFF;
04403       if (fr->af.frametype == AST_FRAME_VIDEO)
04404          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04405       else
04406          fh->csub = compress_subclass(fr->af.subclass);
04407       if (transfer) {
04408          fr->dcallno = pvt->transfercallno;
04409       } else
04410          fr->dcallno = pvt->peercallno;
04411       fh->dcallno = htons(fr->dcallno);
04412       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04413       fr->data = fh;
04414       fr->retries = 0;
04415       /* Retry after 2x the ping time has passed */
04416       fr->retrytime = pvt->pingtime * 2;
04417       if (fr->retrytime < MIN_RETRY_TIME)
04418          fr->retrytime = MIN_RETRY_TIME;
04419       if (fr->retrytime > MAX_RETRY_TIME)
04420          fr->retrytime = MAX_RETRY_TIME;
04421       /* Acks' don't get retried */
04422       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04423          fr->retries = -1;
04424       else if (f->frametype == AST_FRAME_VOICE)
04425          pvt->svoiceformat = f->subclass;
04426       else if (f->frametype == AST_FRAME_VIDEO)
04427          pvt->svideoformat = f->subclass & ~0x1;
04428       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04429          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04430             if (iaxdebug) {
04431                if (fr->transfer)
04432                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04433                else
04434                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04435             }
04436             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04437             fr->encmethods = pvt->encmethods;
04438             fr->ecx = pvt->ecx;
04439             fr->mydcx = pvt->mydcx;
04440             memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
04441          } else
04442             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04443       }
04444    
04445       if (now) {
04446          res = send_packet(fr);
04447       } else
04448          res = iax2_transmit(fr);
04449    } else {
04450       if (ast_test_flag(pvt, IAX_TRUNK)) {
04451          iax2_trunk_queue(pvt, fr);
04452          res = 0;
04453       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04454          /* Video frame have no sequence number */
04455          fr->oseqno = -1;
04456          fr->iseqno = -1;
04457          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04458          vh->zeros = 0;
04459          vh->callno = htons(0x8000 | fr->callno);
04460          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04461          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04462          fr->data = vh;
04463          fr->retries = -1;
04464          res = send_packet(fr);        
04465       } else {
04466          /* Mini-frames have no sequence number */
04467          fr->oseqno = -1;
04468          fr->iseqno = -1;
04469          /* Mini frame will do */
04470          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04471          mh->callno = htons(fr->callno);
04472          mh->ts = htons(fr->ts & 0xFFFF);
04473          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04474          fr->data = mh;
04475          fr->retries = -1;
04476          if (pvt->transferring == TRANSFER_MEDIAPASS)
04477             fr->transfer = 1;
04478          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04479             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04480                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04481             } else
04482                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04483          }
04484          res = send_packet(fr);
04485       }
04486    }
04487    return res;
04488 }
04489 
04490 static int iax2_show_users(int fd, int argc, char *argv[])
04491 {
04492    regex_t regexbuf;
04493    int havepattern = 0;
04494 
04495 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04496 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04497 
04498    struct iax2_user *user = NULL;
04499    char auth[90];
04500    char *pstr = "";
04501    struct ao2_iterator i;
04502 
04503    switch (argc) {
04504    case 5:
04505       if (!strcasecmp(argv[3], "like")) {
04506          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04507             return RESULT_SHOWUSAGE;
04508          havepattern = 1;
04509       } else
04510          return RESULT_SHOWUSAGE;
04511    case 3:
04512       break;
04513    default:
04514       return RESULT_SHOWUSAGE;
04515    }
04516 
04517    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04518    i = ao2_iterator_init(users, 0);
04519    for (user = ao2_iterator_next(&i); user; 
04520       user_unref(user), user = ao2_iterator_next(&i)) {
04521       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04522          continue;
04523       
04524       if (!ast_strlen_zero(user->secret)) {
04525          ast_copy_string(auth,user->secret,sizeof(auth));
04526       } else if (!ast_strlen_zero(user->inkeys)) {
04527          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04528       } else
04529          ast_copy_string(auth, "-no secret-", sizeof(auth));
04530       
04531       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04532          pstr = "REQ Only";
04533       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04534          pstr = "Disabled";
04535       else
04536          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04537       
04538       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04539          user->contexts ? user->contexts->context : context,
04540          user->ha ? "Yes" : "No", pstr);
04541    }
04542 
04543    if (havepattern)
04544       regfree(&regexbuf);
04545 
04546    return RESULT_SUCCESS;
04547 #undef FORMAT
04548 #undef FORMAT2
04549 }
04550 
04551 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04552 {
04553    regex_t regexbuf;
04554    int havepattern = 0;
04555    int total_peers = 0;
04556    int online_peers = 0;
04557    int offline_peers = 0;
04558    int unmonitored_peers = 0;
04559    struct ao2_iterator i;
04560 
04561 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04562 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04563 
04564    struct iax2_peer *peer = NULL;
04565    char name[256];
04566    int registeredonly=0;
04567    char *term = manager ? "\r\n" : "\n";
04568 
04569    switch (argc) {
04570    case 6:
04571       if (!strcasecmp(argv[3], "registered"))
04572          registeredonly = 1;
04573       else
04574          return RESULT_SHOWUSAGE;
04575       if (!strcasecmp(argv[4], "like")) {
04576          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04577             return RESULT_SHOWUSAGE;
04578          havepattern = 1;
04579       } else
04580          return RESULT_SHOWUSAGE;
04581       break;
04582    case 5:
04583       if (!strcasecmp(argv[3], "like")) {
04584          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04585             return RESULT_SHOWUSAGE;
04586          havepattern = 1;
04587       } else
04588          return RESULT_SHOWUSAGE;
04589       break;
04590    case 4:
04591       if (!strcasecmp(argv[3], "registered"))
04592          registeredonly = 1;
04593       else
04594          return RESULT_SHOWUSAGE;
04595       break;
04596    case 3:
04597       break;
04598    default:
04599       return RESULT_SHOWUSAGE;
04600    }
04601 
04602 
04603    if (s)
04604       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04605    else
04606       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04607 
04608    i = ao2_iterator_init(peers, 0);
04609    for (peer = ao2_iterator_next(&i); peer; 
04610       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04611       char nm[20];
04612       char status[20];
04613       char srch[2000];
04614       int retstatus;
04615 
04616       if (registeredonly && !peer->addr.sin_addr.s_addr)
04617          continue;
04618       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04619          continue;
04620 
04621       if (!ast_strlen_zero(peer->username))
04622          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04623       else
04624          ast_copy_string(name, peer->name, sizeof(name));
04625       
04626       retstatus = peer_status(peer, status, sizeof(status));
04627       if (retstatus > 0)
04628          online_peers++;
04629       else if (!retstatus)
04630          offline_peers++;
04631       else
04632          unmonitored_peers++;
04633       
04634       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04635       
04636       snprintf(srch, sizeof(srch), FORMAT, name, 
04637           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04638           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04639           nm,
04640           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04641           peer->encmethods ? "(E)" : "   ", status, term);
04642       
04643       if (s)
04644          astman_append(s, FORMAT, name, 
04645                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04646                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04647                   nm,
04648                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04649                   peer->encmethods ? "(E)" : "   ", status, term);
04650       else
04651          ast_cli(fd, FORMAT, name, 
04652             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04653             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04654             nm,
04655             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04656             peer->encmethods ? "(E)" : "   ", status, term);
04657       total_peers++;
04658    }
04659 
04660    if (s)
04661       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04662    else
04663       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04664 
04665    if (havepattern)
04666       regfree(&regexbuf);
04667 
04668    return RESULT_SUCCESS;
04669 #undef FORMAT
04670 #undef FORMAT2
04671 }
04672 
04673 static int iax2_show_threads(int fd, int argc, char *argv[])
04674 {
04675    struct iax2_thread *thread = NULL;
04676    time_t t;
04677    int threadcount = 0, dynamiccount = 0;
04678    char type;
04679 
04680    if (argc != 3)
04681       return RESULT_SHOWUSAGE;
04682       
04683    ast_cli(fd, "IAX2 Thread Information\n");
04684    time(&t);
04685    ast_cli(fd, "Idle Threads:\n");
04686    AST_LIST_LOCK(&idle_list);
04687    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04688 #ifdef DEBUG_SCHED_MULTITHREAD
04689       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04690          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04691 #else
04692       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04693          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04694 #endif
04695       threadcount++;
04696    }
04697    AST_LIST_UNLOCK(&idle_list);
04698    ast_cli(fd, "Active Threads:\n");
04699    AST_LIST_LOCK(&active_list);
04700    AST_LIST_TRAVERSE(&active_list, thread, list) {
04701       if (thread->type == IAX_TYPE_DYNAMIC)
04702          type = 'D';
04703       else
04704          type = 'P';
04705 #ifdef DEBUG_SCHED_MULTITHREAD
04706       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04707          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04708 #else
04709       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04710          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04711 #endif
04712       threadcount++;
04713    }
04714    AST_LIST_UNLOCK(&active_list);
04715    ast_cli(fd, "Dynamic Threads:\n");
04716         AST_LIST_LOCK(&dynamic_list);
04717         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04718 #ifdef DEBUG_SCHED_MULTITHREAD
04719                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04720                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04721 #else
04722                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04723                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04724 #endif
04725       dynamiccount++;
04726         }
04727         AST_LIST_UNLOCK(&dynamic_list);
04728    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04729    return RESULT_SUCCESS;
04730 }
04731 
04732 static int iax2_show_peers(int fd, int argc, char *argv[])
04733 {
04734    return __iax2_show_peers(0, fd, NULL, argc, argv);
04735 }
04736 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04737 {
04738    ast_cli_netstats(s, -1, 0);
04739    astman_append(s, "\r\n");
04740    return RESULT_SUCCESS;
04741 }
04742 
04743 static int iax2_show_firmware(int fd, int argc, char *argv[])
04744 {
04745 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04746 #if !defined(__FreeBSD__)
04747 #define FORMAT "%-15.15s  %-15d %-15d\n"
04748 #else /* __FreeBSD__ */
04749 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04750 #endif /* __FreeBSD__ */
04751    struct iax_firmware *cur;
04752    if ((argc != 3) && (argc != 4))
04753       return RESULT_SHOWUSAGE;
04754    ast_mutex_lock(&waresl.lock);
04755    
04756    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04757    for (cur = waresl.wares;cur;cur = cur->next) {
04758       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04759          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04760             (int)ntohl(cur->fwh->datalen));
04761    }
04762    ast_mutex_unlock(&waresl.lock);
04763    return RESULT_SUCCESS;
04764 #undef FORMAT
04765 #undef FORMAT2
04766 }
04767 
04768 /* JDG: callback to display iax peers in manager */
04769 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04770 {
04771    char *a[] = { "iax2", "show", "users" };
04772    int ret;
04773    const char *id = astman_get_header(m,"ActionID");
04774 
04775    if (!ast_strlen_zero(id))
04776       astman_append(s, "ActionID: %s\r\n",id);
04777    ret = __iax2_show_peers(1, -1, s, 3, a );
04778    astman_append(s, "\r\n\r\n" );
04779    return ret;
04780 } /* /JDG */
04781 
04782 static char *regstate2str(int regstate)
04783 {
04784    switch(regstate) {
04785    case REG_STATE_UNREGISTERED:
04786       return "Unregistered";
04787    case REG_STATE_REGSENT:
04788       return "Request Sent";
04789    case REG_STATE_AUTHSENT:
04790       return "Auth. Sent";
04791    case REG_STATE_REGISTERED:
04792       return "Registered";
04793    case REG_STATE_REJECTED:
04794       return "Rejected";
04795    case REG_STATE_TIMEOUT:
04796       return "Timeout";
04797    case REG_STATE_NOAUTH:
04798       return "No Authentication";
04799    default:
04800       return "Unknown";
04801    }
04802 }
04803 
04804 static int iax2_show_registry(int fd, int argc, char *argv[])
04805 {
04806 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04807 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04808    struct iax2_registry *reg = NULL;
04809 
04810    char host[80];
04811    char perceived[80];
04812    if (argc != 3)
04813       return RESULT_SHOWUSAGE;
04814    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04815    AST_LIST_LOCK(&registrations);
04816    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04817       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04818       if (reg->us.sin_addr.s_addr) 
04819          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04820       else
04821          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04822       ast_cli(fd, FORMAT, host, 
04823                (reg->dnsmgr) ? "Y" : "N", 
04824                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04825    }
04826    AST_LIST_UNLOCK(&registrations);
04827    return RESULT_SUCCESS;
04828 #undef FORMAT
04829 #undef FORMAT2
04830 }
04831 
04832 static int iax2_show_channels(int fd, int argc, char *argv[])
04833 {
04834 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04835 #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"
04836 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04837    int x;
04838    int numchans = 0;
04839 
04840    if (argc != 3)
04841       return RESULT_SHOWUSAGE;
04842    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04843    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04844       ast_mutex_lock(&iaxsl[x]);
04845       if (iaxs[x]) {
04846          int lag, jitter, localdelay;
04847          jb_info jbinfo;
04848          
04849          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04850             jb_getinfo(iaxs[x]->jb, &jbinfo);
04851             jitter = jbinfo.jitter;
04852             localdelay = jbinfo.current - jbinfo.min;
04853          } else {
04854             jitter = -1;
04855             localdelay = 0;
04856          }
04857          lag = iaxs[x]->remote_rr.delay;
04858          ast_cli(fd, FORMAT,
04859             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04860             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04861             S_OR(iaxs[x]->username, "(None)"),
04862             iaxs[x]->callno, iaxs[x]->peercallno,
04863             iaxs[x]->oseqno, iaxs[x]->iseqno,
04864             lag,
04865             jitter,
04866             localdelay,
04867             ast_getformatname(iaxs[x]->voiceformat) );
04868          numchans++;
04869       }
04870       ast_mutex_unlock(&iaxsl[x]);
04871    }
04872    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04873    return RESULT_SUCCESS;
04874 #undef FORMAT
04875 #undef FORMAT2
04876 #undef FORMATB
04877 }
04878 
04879 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04880 {
04881    int x;
04882    int numchans = 0;
04883    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04884       ast_mutex_lock(&iaxsl[x]);
04885       if (iaxs[x]) {
04886          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04887          char *fmt;
04888          jb_info jbinfo;
04889          
04890          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04891             jb_getinfo(iaxs[x]->jb, &jbinfo);
04892             localjitter = jbinfo.jitter;
04893             localdelay = jbinfo.current - jbinfo.min;
04894             locallost = jbinfo.frames_lost;
04895             locallosspct = jbinfo.losspct/1000;
04896             localdropped = jbinfo.frames_dropped;
04897             localooo = jbinfo.frames_ooo;
04898          } else {
04899             localjitter = -1;
04900             localdelay = 0;
04901             locallost = -1;
04902             locallosspct = -1;
04903             localdropped = 0;
04904             localooo = -1;
04905          }
04906          if (limit_fmt)
04907             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04908          else
04909             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04910          if (s)
04911             
04912             astman_append(s, fmt,
04913                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04914                      iaxs[x]->pingtime,
04915                      localjitter, 
04916                      localdelay,
04917                      locallost,
04918                      locallosspct,
04919                      localdropped,
04920                      localooo,
04921                      iaxs[x]->frames_received/1000,
04922                      iaxs[x]->remote_rr.jitter,
04923                      iaxs[x]->remote_rr.delay,
04924                      iaxs[x]->remote_rr.losscnt,
04925                      iaxs[x]->remote_rr.losspct,
04926                      iaxs[x]->remote_rr.dropped,
04927                      iaxs[x]->remote_rr.ooo,
04928                      iaxs[x]->remote_rr.packets/1000);
04929          else
04930             ast_cli(fd, fmt,
04931                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04932                iaxs[x]->pingtime,
04933                localjitter, 
04934                localdelay,
04935                locallost,
04936                locallosspct,
04937                localdropped,
04938                localooo,
04939                iaxs[x]->frames_received/1000,
04940                iaxs[x]->remote_rr.jitter,
04941                iaxs[x]->remote_rr.delay,
04942                iaxs[x]->remote_rr.losscnt,
04943                iaxs[x]->remote_rr.losspct,
04944                iaxs[x]->remote_rr.dropped,
04945                iaxs[x]->remote_rr.ooo,
04946                iaxs[x]->remote_rr.packets/1000
04947                );
04948          numchans++;
04949       }
04950       ast_mutex_unlock(&iaxsl[x]);
04951    }
04952    return numchans;
04953 }
04954 
04955 static int iax2_show_netstats(int fd, int argc, char *argv[])
04956 {
04957    int numchans = 0;
04958    if (argc != 3)
04959       return RESULT_SHOWUSAGE;
04960    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04961    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04962    numchans = ast_cli_netstats(NULL, fd, 1);
04963    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04964    return RESULT_SUCCESS;
04965 }
04966 
04967 static int iax2_do_debug(int fd, int argc, char *argv[])
04968 {
04969    if (argc < 2 || argc > 3)
04970       return RESULT_SHOWUSAGE;
04971    iaxdebug = 1;
04972    ast_cli(fd, "IAX2 Debugging Enabled\n");
04973    return RESULT_SUCCESS;
04974 }
04975 
04976 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04977 {
04978    if (argc < 3 || argc > 4)
04979       return RESULT_SHOWUSAGE;
04980    iaxtrunkdebug = 1;
04981    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04982    return RESULT_SUCCESS;
04983 }
04984 
04985 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04986 {
04987    if (argc < 3 || argc > 4)
04988       return RESULT_SHOWUSAGE;
04989    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04990    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04991    return RESULT_SUCCESS;
04992 }
04993 
04994 static int iax2_no_debug(int fd, int argc, char *argv[])
04995 {
04996    if (argc < 3 || argc > 4)
04997       return RESULT_SHOWUSAGE;
04998    iaxdebug = 0;
04999    ast_cli(fd, "IAX2 Debugging Disabled\n");
05000    return RESULT_SUCCESS;
05001 }
05002 
05003 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
05004 {
05005    if (argc < 4 || argc > 5)
05006       return RESULT_SHOWUSAGE;
05007    iaxtrunkdebug = 0;
05008    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
05009    return RESULT_SUCCESS;
05010 }
05011 
05012 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
05013 {
05014    if (argc < 4 || argc > 5)
05015       return RESULT_SHOWUSAGE;
05016    jb_setoutput(jb_error_output, jb_warning_output, NULL);
05017    jb_debug_output("\n");
05018    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05019    return RESULT_SUCCESS;
05020 }
05021 
05022 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05023 {
05024    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05025    int res = -1;
05026    ast_mutex_lock(&iaxsl[callno]);
05027    if (iaxs[callno]) {
05028    /* If there's an outstanding error, return failure now */
05029       if (!iaxs[callno]->error) {
05030          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05031             res = 0;
05032             /* Don't waste bandwidth sending null frames */
05033          else if (f->frametype == AST_FRAME_NULL)
05034             res = 0;
05035          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05036             res = 0;
05037          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05038             res = 0;
05039          else
05040          /* Simple, just queue for transmission */
05041             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05042       } else {
05043          if (option_debug)
05044             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05045       }
05046    }
05047    /* If it's already gone, just return */
05048    ast_mutex_unlock(&iaxsl[callno]);
05049    return res;
05050 }
05051 
05052 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
05053       int now, int transfer, int final)
05054 {
05055    struct ast_frame f = { 0, };
05056 
05057    f.frametype = type;
05058    f.subclass = command;
05059    f.datalen = datalen;
05060    f.src = __FUNCTION__;
05061    f.data = (void *) data;
05062 
05063    return iax2_send(i, &f, ts, seqno, now, transfer, final);
05064 }
05065 
05066 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05067 {
05068    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05069 }
05070 
05071 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05072 {
05073    int res;
05074    ast_mutex_lock(&iaxsl[callno]);
05075    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05076    ast_mutex_unlock(&iaxsl[callno]);
05077    return res;
05078 }
05079 
05080 /*!
05081  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
05082  *       the pvt struct for the given call number may disappear during its 
05083  *       execution.
05084  */
05085 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)
05086 {
05087    int call_num = i->callno;
05088    /* It is assumed that the callno has already been locked */
05089    iax2_predestroy(i->callno);
05090    if (!iaxs[call_num])
05091       return -1;
05092    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05093 }
05094 
05095 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)
05096 {
05097    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05098 }
05099 
05100 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05101 {
05102    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05103 }
05104 
05105 static int apply_context(struct iax2_context *con, const char *context)
05106 {
05107    while(con) {
05108       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05109          return -1;
05110       con = con->next;
05111    }
05112    return 0;
05113 }
05114 
05115 
05116 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05117 {
05118    /* Start pessimistic */
05119    int res = -1;
05120    int version = 2;
05121    struct iax2_user *user = NULL, *best = NULL;
05122    int bestscore = 0;
05123    int gotcapability = 0;
05124    struct ast_variable *v = NULL, *tmpvar = NULL;
05125    struct ao2_iterator i;
05126 
05127    if (!iaxs[callno])
05128       return res;
05129    if (ies->called_number)
05130       ast_string_field_set(iaxs[callno], exten, ies->called_number);
05131    if (ies->calling_number) {
05132       ast_shrink_phone_number(ies->calling_number);
05133       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05134    }
05135    if (ies->calling_name)
05136       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05137    if (ies->calling_ani)
05138       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05139    if (ies->dnid)
05140       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05141    if (ies->rdnis)
05142       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05143    if (ies->called_context)
05144       ast_string_field_set(iaxs[callno], context, ies->called_context);
05145    if (ies->language)
05146       ast_string_field_set(iaxs[callno], language, ies->language);
05147    if (ies->username)
05148       ast_string_field_set(iaxs[callno], username, ies->username);
05149    if (ies->calling_ton > -1)
05150       iaxs[callno]->calling_ton = ies->calling_ton;
05151    if (ies->calling_tns > -1)
05152       iaxs[callno]->calling_tns = ies->calling_tns;
05153    if (ies->calling_pres > -1)
05154       iaxs[callno]->calling_pres = ies->calling_pres;
05155    if (ies->format)
05156       iaxs[callno]->peerformat = ies->format;
05157    if (ies->adsicpe)
05158       iaxs[callno]->peeradsicpe = ies->adsicpe;
05159    if (ies->capability) {
05160       gotcapability = 1;
05161       iaxs[callno]->peercapability = ies->capability;
05162    } 
05163    if (ies->version)
05164       version = ies->version;
05165 
05166    /* Use provided preferences until told otherwise for actual preferences */
05167    if(ies->codec_prefs) {
05168       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05169       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05170    }
05171 
05172    if (!gotcapability) 
05173       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05174    if (version > IAX_PROTO_VERSION) {
05175       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05176          ast_inet_ntoa(sin->sin_addr), version);
05177       return res;
05178    }
05179    /* Search the userlist for a compatible entry, and fill in the rest */
05180    i = ao2_iterator_init(users, 0);
05181    while ((user = ao2_iterator_next(&i))) {
05182       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05183          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05184          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05185          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05186               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05187          if (!ast_strlen_zero(iaxs[callno]->username)) {
05188             /* Exact match, stop right now. */
05189             if (best)
05190                user_unref(best);
05191             best = user;
05192             break;
05193          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05194             /* No required authentication */
05195             if (user->ha) {
05196                /* There was host authentication and we passed, bonus! */
05197                if (bestscore < 4) {
05198                   bestscore = 4;
05199                   if (best)
05200                      user_unref(best);
05201                   best = user;
05202                   continue;
05203                }
05204             } else {
05205                /* No host access, but no secret, either, not bad */
05206                if (bestscore < 3) {
05207                   bestscore = 3;
05208                   if (best)
05209                      user_unref(best);
05210                   best = user;
05211                   continue;
05212                }
05213             }
05214          } else {
05215             if (user->ha) {
05216                /* Authentication, but host access too, eh, it's something.. */
05217                if (bestscore < 2) {
05218                   bestscore = 2;
05219                   if (best)
05220                      user_unref(best);
05221                   best = user;
05222                   continue;
05223                }
05224             } else {
05225                /* Authentication and no host access...  This is our baseline */
05226                if (bestscore < 1) {
05227                   bestscore = 1;
05228                   if (best)
05229                      user_unref(best);
05230                   best = user;
05231                   continue;
05232                }
05233             }
05234          }
05235       }
05236       user_unref(user);
05237    }
05238    user = best;
05239    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05240       user = realtime_user(iaxs[callno]->username, sin);
05241       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05242           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05243          user = user_unref(user);
05244       }
05245    }
05246    if (user) {
05247       /* We found our match (use the first) */
05248       /* copy vars */
05249       for (v = user->vars ; v ; v = v->next) {
05250          if((tmpvar = ast_variable_new(v->name, v->value))) {
05251             tmpvar->next = iaxs[callno]->vars; 
05252             iaxs[callno]->vars = tmpvar;
05253          }
05254       }
05255       /* If a max AUTHREQ restriction is in place, activate it */
05256       if (user->maxauthreq > 0)
05257          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05258       iaxs[callno]->prefs = user->prefs;
05259       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05260       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05261       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05262       iaxs[callno]->encmethods = user->encmethods;
05263       /* Store the requested username if not specified */
05264       if (ast_strlen_zero(iaxs[callno]->username))
05265          ast_string_field_set(iaxs[callno], username, user->name);
05266       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05267       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05268       iaxs[callno]->capability = user->capability;
05269       /* And use the default context */
05270       if (ast_strlen_zero(iaxs[callno]->context)) {
05271          if (user->contexts)
05272             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05273          else
05274             ast_string_field_set(iaxs[callno], context, context);
05275       }
05276       /* And any input keys */
05277       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05278       /* And the permitted authentication methods */
05279       iaxs[callno]->authmethods = user->authmethods;
05280       iaxs[callno]->adsi = user->adsi;
05281       /* If they have callerid, override the given caller id.  Always store the ANI */
05282       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05283          if (ast_test_flag(user, IAX_HASCALLERID)) {
05284             iaxs[callno]->calling_tns = 0;
05285             iaxs[callno]->calling_ton = 0;
05286             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05287             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05288             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05289          }
05290          if (ast_strlen_zero(iaxs[callno]->ani))
05291             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05292       } else {
05293          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05294       }
05295       if (!ast_strlen_zero(user->accountcode))
05296          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05297       if (!ast_strlen_zero(user->mohinterpret))
05298          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05299       if (!ast_strlen_zero(user->mohsuggest))
05300          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05301       if (user->amaflags)
05302          iaxs[callno]->amaflags = user->amaflags;
05303       if (!ast_strlen_zero(user->language))
05304          ast_string_field_set(iaxs[callno], language, user->language);
05305       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05306       /* Keep this check last */
05307       if (!ast_strlen_zero(user->dbsecret)) {
05308          char *family, *key=NULL;
05309          char buf[80];
05310          family = ast_strdupa(user->dbsecret);
05311          key = strchr(family, '/');
05312          if (key) {
05313             *key = '\0';
05314             key++;
05315          }
05316          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05317             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05318          else
05319             ast_string_field_set(iaxs[callno], secret, buf);
05320       } else
05321          ast_string_field_set(iaxs[callno], secret, user->secret);
05322       res = 0;
05323       user = user_unref(user);
05324    } else {
05325        /* user was not found, but we should still fake an AUTHREQ.
05326         * Set authmethods to the last known authmethod used by the system
05327         * Set a fake secret, it's not looked at, just required to attempt authentication.
05328         * Set authrej so the AUTHREP is rejected without even looking at its contents */
05329       iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
05330       ast_string_field_set(iaxs[callno], secret, "badsecret");
05331       iaxs[callno]->authrej = 1;
05332       if (!ast_strlen_zero(iaxs[callno]->username)) {
05333          /* only send the AUTHREQ if a username was specified. */
05334          res = 0;
05335       }
05336    }
05337    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05338    return res;
05339 }
05340 
05341 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05342 {
05343    struct ast_iax2_full_hdr fh;
05344    fh.scallno = htons(src | IAX_FLAG_FULL);
05345    fh.dcallno = htons(dst);
05346    fh.ts = 0;
05347    fh.oseqno = 0;
05348    fh.iseqno = 0;
05349    fh.type = AST_FRAME_IAX;
05350    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05351    if (iaxdebug)
05352        iax_showframe(NULL, &fh, 0, sin, 0);
05353    if (option_debug)
05354       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05355          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05356    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05357 }
05358 
05359 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05360 {
05361    /* Select exactly one common encryption if there are any */
05362    p->encmethods &= enc;
05363    if (p->encmethods) {
05364       if (p->encmethods & IAX_ENCRYPT_AES128)
05365          p->encmethods = IAX_ENCRYPT_AES128;
05366       else
05367          p->encmethods = 0;
05368    }
05369 }
05370 
05371 /*!
05372  * \pre iaxsl[call_num] is locked
05373  *
05374  * \note Since this function calls send_command_final(), the pvt struct for the given
05375  *       call number may disappear while executing this function.
05376  */
05377 static int authenticate_request(int call_num)
05378 {
05379    struct iax_ie_data ied;
05380    int res = -1, authreq_restrict = 0;
05381    char challenge[10];
05382    struct chan_iax2_pvt *p = iaxs[call_num];
05383 
05384    memset(&ied, 0, sizeof(ied));
05385 
05386    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05387    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05388       struct iax2_user *user, tmp_user = {
05389          .name = p->username, 
05390       };
05391 
05392       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05393       if (user) {
05394          if (user->curauthreq == user->maxauthreq)
05395             authreq_restrict = 1;
05396          else
05397             user->curauthreq++;
05398          user = user_unref(user);
05399       }
05400    }
05401 
05402    /* If the AUTHREQ limit test failed, send back an error */
05403    if (authreq_restrict) {
05404       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05405       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05406       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05407       return 0;
05408    }
05409 
05410    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05411    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05412       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05413       ast_string_field_set(p, challenge, challenge);
05414       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05415       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05416    }
05417    if (p->encmethods)
05418       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05419 
05420    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05421 
05422    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05423 
05424    if (p->encmethods)
05425       ast_set_flag(p, IAX_ENCRYPTED);
05426 
05427    return res;
05428 }
05429 
05430 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05431 {
05432    char requeststr[256];
05433    char md5secret[256] = "";
05434    char secret[256] = "";
05435    char rsasecret[256] = "";
05436    int res = -1; 
05437    int x;
05438    struct iax2_user *user, tmp_user = {
05439       .name = p->username, 
05440    };
05441 
05442    if (p->authrej) {
05443       return res;
05444    }
05445    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05446    if (user) {
05447       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05448          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05449          ast_clear_flag(p, IAX_MAXAUTHREQ);
05450       }
05451       ast_string_field_set(p, host, user->name);
05452       user = user_unref(user);
05453    }
05454 
05455    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05456       return res;
05457    if (ies->password)
05458       ast_copy_string(secret, ies->password, sizeof(secret));
05459    if (ies->md5_result)
05460       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05461    if (ies->rsa_result)
05462       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05463    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05464       struct ast_key *key;
05465       char *keyn;
05466       char tmpkey[256];
05467       char *stringp=NULL;
05468       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05469       stringp=tmpkey;
05470       keyn = strsep(&stringp, ":");
05471       while(keyn) {
05472          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05473          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05474             res = 0;
05475             break;
05476          } else if (!key)
05477             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05478          keyn = strsep(&stringp, ":");
05479       }
05480    } else if (p->authmethods & IAX_AUTH_MD5) {
05481       struct MD5Context md5;
05482       unsigned char digest[16];
05483       char *tmppw, *stringp;
05484       
05485       tmppw = ast_strdupa(p->secret);
05486       stringp = tmppw;
05487       while((tmppw = strsep(&stringp, ";"))) {
05488          MD5Init(&md5);
05489          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05490          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05491          MD5Final(digest, &md5);
05492          /* If they support md5, authenticate with it.  */
05493          for (x=0;x<16;x++)
05494             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05495          if (!strcasecmp(requeststr, md5secret)) {
05496             res = 0;
05497             break;
05498          }
05499       }
05500    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05501       if (!strcmp(secret, p->secret))
05502          res = 0;
05503    }
05504    return res;
05505 }
05506 
05507 /*! \brief Verify inbound registration */
05508 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05509 {
05510    char requeststr[256] = "";
05511    char peer[256] = "";
05512    char md5secret[256] = "";
05513    char rsasecret[256] = "";
05514    char secret[256] = "";
05515    struct iax2_peer *p = NULL;
05516    struct ast_key *key;
05517    char *keyn;
05518    int x;
05519    int expire = 0;
05520    int res = -1;
05521 
05522    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05523    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05524    if (ies->username)
05525       ast_copy_string(peer, ies->username, sizeof(peer));
05526    if (ies->password)
05527       ast_copy_string(secret, ies->password, sizeof(secret));
05528    if (ies->md5_result)
05529       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05530    if (ies->rsa_result)
05531       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05532    if (ies->refresh)
05533       expire = ies->refresh;
05534 
05535    if (ast_strlen_zero(peer)) {
05536       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05537       return -1;
05538    }
05539 
05540    /* SLD: first call to lookup peer during registration */
05541    ast_mutex_unlock(&iaxsl[callno]);
05542    p = find_peer(peer, 1);
05543    ast_mutex_lock(&iaxsl[callno]);
05544    if (!p || !iaxs[callno]) {
05545       if (iaxs[callno]) {
05546          int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
05547 
05548          ast_string_field_set(iaxs[callno], secret, "badsecret");
05549 
05550          /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless
05551           * 1. A challenge already exists indicating a AUTHREQ was already sent out.
05552           * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it.
05553           * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened
05554           *    to be plaintext, indicating it is an authmethod used by other peers on the system. 
05555           *
05556           * If none of these cases exist, res will be returned as 0 without authentication indicating
05557           * an AUTHREQ needs to be sent out. */
05558 
05559          if (ast_strlen_zero(iaxs[callno]->challenge) &&
05560             !(!ast_strlen_zero(secret) && plaintext)) {
05561             /* by setting res to 0, an REGAUTH will be sent */
05562             res = 0;
05563          }
05564       }
05565       if (authdebug && !p)
05566          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05567 
05568       goto return_unref;
05569    }
05570 
05571    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05572       if (authdebug)
05573          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05574       goto return_unref;
05575    }
05576 
05577    if (!ast_apply_ha(p->ha, sin)) {
05578       if (authdebug)
05579          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05580       goto return_unref;
05581    }
05582    ast_string_field_set(iaxs[callno], secret, p->secret);
05583    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05584    /* Check secret against what we have on file */
05585    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05586       if (!ast_strlen_zero(p->inkeys)) {
05587          char tmpkeys[256];
05588          char *stringp=NULL;
05589          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05590          stringp=tmpkeys;
05591          keyn = strsep(&stringp, ":");
05592          while(keyn) {
05593             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05594             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05595                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05596                break;
05597             } else if (!key)
05598                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05599             keyn = strsep(&stringp, ":");
05600          }
05601          if (!keyn) {
05602             if (authdebug)
05603                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05604             goto return_unref;
05605          }
05606       } else {
05607          if (authdebug)
05608             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05609          goto return_unref;
05610       }
05611    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05612       struct MD5Context md5;
05613       unsigned char digest[16];
05614       char *tmppw, *stringp;
05615 
05616       tmppw = ast_strdupa(p->secret);
05617       stringp = tmppw;
05618       while((tmppw = strsep(&stringp, ";"))) {
05619          MD5Init(&md5);
05620          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05621          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05622          MD5Final(digest, &md5);
05623          for (x=0;x<16;x++)
05624             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05625          if (!strcasecmp(requeststr, md5secret))
05626             break;
05627       }
05628       if (tmppw) {
05629          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05630       } else {
05631          if (authdebug)
05632             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05633          goto return_unref;
05634       }
05635    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05636       /* They've provided a plain text password and we support that */
05637       if (strcmp(secret, p->secret)) {
05638          if (authdebug)
05639             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05640          goto return_unref;
05641       } else
05642          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05643    } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
05644       /* if challenge has been sent, but no challenge response if given, reject. */
05645       goto return_unref;
05646    }
05647    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05648 
05649    /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */
05650    res = 0;
05651 return_unref:
05652    if (iaxs[callno]) {
05653       ast_string_field_set(iaxs[callno], peer, peer);
05654    }
05655    /* Choose lowest expiry number */
05656    if (expire && (expire < iaxs[callno]->expiry)) {
05657       iaxs[callno]->expiry = expire;
05658    }
05659 
05660    if (p)
05661       peer_unref(p);
05662    return res;
05663 }
05664 
05665 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
05666 {
05667    int res = -1;
05668    int x;
05669    if (!ast_strlen_zero(keyn)) {
05670       if (!(authmethods & IAX_AUTH_RSA)) {
05671          if (ast_strlen_zero(secret)) 
05672             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));
05673       } else if (ast_strlen_zero(challenge)) {
05674          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05675       } else {
05676          char sig[256];
05677          struct ast_key *key;
05678          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05679          if (!key) {
05680             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05681          } else {
05682             if (ast_sign(key, (char*)challenge, sig)) {
05683                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05684                res = -1;
05685             } else {
05686                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05687                res = 0;
05688             }
05689          }
05690       }
05691    } 
05692    /* Fall back */
05693    if (res && !ast_strlen_zero(secret)) {
05694       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05695          struct MD5Context md5;
05696          unsigned char digest[16];
05697          char digres[128];
05698          MD5Init(&md5);
05699          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05700          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05701          MD5Final(digest, &md5);
05702          /* If they support md5, authenticate with it.  */
05703          for (x=0;x<16;x++)
05704             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05705          if (pvt) {
05706             build_encryption_keys(digest, pvt);
05707          }
05708          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05709          res = 0;
05710       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05711          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05712          res = 0;
05713       } else
05714          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05715    }
05716    return res;
05717 }
05718 
05719 /*!
05720  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05721  *       so do not call this function with a pvt lock held.
05722  */
05723 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05724 {
05725    struct iax2_peer *peer = NULL;
05726    /* Start pessimistic */
05727    int res = -1;
05728    int authmethods = 0;
05729    struct iax_ie_data ied;
05730    uint16_t callno = p->callno;
05731 
05732    memset(&ied, 0, sizeof(ied));
05733    
05734    if (ies->username)
05735       ast_string_field_set(p, username, ies->username);
05736    if (ies->challenge)
05737       ast_string_field_set(p, challenge, ies->challenge);
05738    if (ies->authmethods)
05739       authmethods = ies->authmethods;
05740    if (authmethods & IAX_AUTH_MD5)
05741       merge_encryption(p, ies->encmethods);
05742    else
05743       p->encmethods = 0;
05744 
05745    /* Check for override RSA authentication first */
05746    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05747       /* Normal password authentication */
05748       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
05749    } else {
05750       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05751       while ((peer = ao2_iterator_next(&i))) {
05752          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05753              /* No peer specified at our end, or this is the peer */
05754              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05755              /* No username specified in peer rule, or this is the right username */
05756              && (!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)))
05757              /* No specified host, or this is our host */
05758             ) {
05759             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
05760             if (!res) {
05761                peer_unref(peer);
05762                break;
05763             }
05764          }
05765          peer_unref(peer);
05766       }
05767       if (!peer) {
05768          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05769             that we're trying to authenticate *to* a realtime peer */
05770          const char *peer_name = ast_strdupa(p->peer);
05771          ast_mutex_unlock(&iaxsl[callno]);
05772          if ((peer = realtime_peer(peer_name, NULL))) {
05773             ast_mutex_lock(&iaxsl[callno]);
05774             if (!(p = iaxs[callno])) {
05775                peer_unref(peer);
05776                return -1;
05777             }
05778             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
05779             peer_unref(peer);
05780          }
05781          if (!peer) {
05782             ast_mutex_lock(&iaxsl[callno]);
05783             if (!(p = iaxs[callno]))
05784                return -1;
05785          }
05786       }
05787    }
05788    if (ies->encmethods)
05789       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05790    if (!res)
05791       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05792    return res;
05793 }
05794 
05795 static int iax2_do_register(struct iax2_registry *reg);
05796 
05797 static void __iax2_do_register_s(const void *data)
05798 {
05799    struct iax2_registry *reg = (struct iax2_registry *)data;
05800    reg->expire = -1;
05801    iax2_do_register(reg);
05802 }
05803 
05804 static int iax2_do_register_s(const void *data)
05805 {
05806 #ifdef SCHED_MULTITHREADED
05807    if (schedule_action(__iax2_do_register_s, data))
05808 #endif      
05809       __iax2_do_register_s(data);
05810    return 0;
05811 }
05812 
05813 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05814 {
05815    int newcall = 0;
05816    char newip[256];
05817    struct iax_ie_data ied;
05818    struct sockaddr_in new;
05819    
05820    
05821    memset(&ied, 0, sizeof(ied));
05822    if (ies->apparent_addr)
05823       bcopy(ies->apparent_addr, &new, sizeof(new));
05824    if (ies->callno)
05825       newcall = ies->callno;
05826    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05827       ast_log(LOG_WARNING, "Invalid transfer request\n");
05828       return -1;
05829    }
05830    pvt->transfercallno = newcall;
05831    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05832    inet_aton(newip, &pvt->transfer.sin_addr);
05833    pvt->transfer.sin_family = AF_INET;
05834    pvt->transferring = TRANSFER_BEGIN;
05835    pvt->transferid = ies->transferid;
05836    if (ies->transferid)
05837       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05838    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05839    return 0; 
05840 }
05841 
05842 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05843 {
05844    char exten[256] = "";
05845    int status = CACHE_FLAG_UNKNOWN;
05846    int expiry = iaxdefaultdpcache;
05847    int x;
05848    int matchmore = 0;
05849    struct iax2_dpcache *dp, *prev;
05850    
05851    if (ies->called_number)
05852       ast_copy_string(exten, ies->called_number, sizeof(exten));
05853 
05854    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05855       status = CACHE_FLAG_EXISTS;
05856    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05857       status = CACHE_FLAG_CANEXIST;
05858    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05859       status = CACHE_FLAG_NONEXISTENT;
05860 
05861    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05862       /* Don't really do anything with this */
05863    }
05864    if (ies->refresh)
05865       expiry = ies->refresh;
05866    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05867       matchmore = CACHE_FLAG_MATCHMORE;
05868    ast_mutex_lock(&dpcache_lock);
05869    prev = NULL;
05870    dp = pvt->dpentries;
05871    while(dp) {
05872       if (!strcmp(dp->exten, exten)) {
05873          /* Let them go */
05874          if (prev)
05875             prev->peer = dp->peer;
05876          else
05877             pvt->dpentries = dp->peer;
05878          dp->peer = NULL;
05879          dp->callno = 0;
05880          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05881          if (dp->flags & CACHE_FLAG_PENDING) {
05882             dp->flags &= ~CACHE_FLAG_PENDING;
05883             dp->flags |= status;
05884             dp->flags |= matchmore;
05885          }
05886          /* Wake up waiters */
05887          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05888             if (dp->waiters[x] > -1)
05889                write(dp->waiters[x], "asdf", 4);
05890       }
05891       prev = dp;
05892       dp = dp->peer;
05893    }
05894    ast_mutex_unlock(&dpcache_lock);
05895    return 0;
05896 }
05897 
05898 static int complete_transfer(int callno, struct iax_ies *ies)
05899 {
05900    int peercallno = 0;
05901    struct chan_iax2_pvt *pvt = iaxs[callno];
05902    struct iax_frame *cur;
05903    jb_frame frame;
05904 
05905    if (ies->callno)
05906       peercallno = ies->callno;
05907 
05908    if (peercallno < 1) {
05909       ast_log(LOG_WARNING, "Invalid transfer request\n");
05910       return -1;
05911    }
05912    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05913    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05914    /* Reset sequence numbers */
05915    pvt->oseqno = 0;
05916    pvt->rseqno = 0;
05917    pvt->iseqno = 0;
05918    pvt->aseqno = 0;
05919 
05920    if (pvt->peercallno) {
05921       remove_by_peercallno(pvt);
05922    }
05923    pvt->peercallno = peercallno;
05924    store_by_peercallno(pvt);
05925 
05926    pvt->transferring = TRANSFER_NONE;
05927    pvt->svoiceformat = -1;
05928    pvt->voiceformat = 0;
05929    pvt->svideoformat = -1;
05930    pvt->videoformat = 0;
05931    pvt->transfercallno = -1;
05932    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05933    memset(&pvt->offset, 0, sizeof(pvt->offset));
05934    /* reset jitterbuffer */
05935    while(jb_getall(pvt->jb,&frame) == JB_OK)
05936       iax2_frame_free(frame.data);
05937    jb_reset(pvt->jb);
05938    pvt->lag = 0;
05939    pvt->last = 0;
05940    pvt->lastsent = 0;
05941    pvt->nextpred = 0;
05942    pvt->pingtime = DEFAULT_RETRY_TIME;
05943    AST_LIST_LOCK(&iaxq.queue);
05944    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05945       /* We must cancel any packets that would have been transmitted
05946          because now we're talking to someone new.  It's okay, they
05947          were transmitted to someone that didn't care anyway. */
05948       if (callno == cur->callno) 
05949          cur->retries = -1;
05950    }
05951    AST_LIST_UNLOCK(&iaxq.queue);
05952    return 0; 
05953 }
05954 
05955 /*! \brief Acknowledgment received for OUR registration */
05956 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05957 {
05958    struct iax2_registry *reg;
05959    /* Start pessimistic */
05960    char peer[256] = "";
05961    char msgstatus[60];
05962    int refresh = 60;
05963    char ourip[256] = "<Unspecified>";
05964    struct sockaddr_in oldus;
05965    struct sockaddr_in us;
05966    int oldmsgs;
05967 
05968    memset(&us, 0, sizeof(us));
05969    if (ies->apparent_addr)
05970       bcopy(ies->apparent_addr, &us, sizeof(us));
05971    if (ies->username)
05972       ast_copy_string(peer, ies->username, sizeof(peer));
05973    if (ies->refresh)
05974       refresh = ies->refresh;
05975    if (ies->calling_number) {
05976       /* We don't do anything with it really, but maybe we should */
05977    }
05978    reg = iaxs[callno]->reg;
05979    if (!reg) {
05980       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05981       return -1;
05982    }
05983    memcpy(&oldus, &reg->us, sizeof(oldus));
05984    oldmsgs = reg->messages;
05985    if (inaddrcmp(&reg->addr, sin)) {
05986       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05987       return -1;
05988    }
05989    memcpy(&reg->us, &us, sizeof(reg->us));
05990    if (ies->msgcount >= 0)
05991       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05992    /* always refresh the registration at the interval requested by the server
05993       we are registering to
05994    */
05995    reg->refresh = refresh;
05996    AST_SCHED_DEL(sched, reg->expire);
05997    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05998    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05999       if (option_verbose > 2) {
06000          if (reg->messages > 255)
06001             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06002          else if (reg->messages > 1)
06003             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06004          else if (reg->messages > 0)
06005             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
06006          else
06007             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
06008          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06009          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06010       }
06011       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06012    }
06013    reg->regstate = REG_STATE_REGISTERED;
06014    return 0;
06015 }
06016 
06017 static int iax2_register(char *value, int lineno)
06018 {
06019    struct iax2_registry *reg;
06020    char copy[256];
06021    char *username, *hostname, *secret;
06022    char *porta;
06023    char *stringp=NULL;
06024    
06025    if (!value)
06026       return -1;
06027    ast_copy_string(copy, value, sizeof(copy));
06028    stringp=copy;
06029    username = strsep(&stringp, "@");
06030    hostname = strsep(&stringp, "@");
06031    if (!hostname) {
06032       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06033       return -1;
06034    }
06035    stringp=username;
06036    username = strsep(&stringp, ":");
06037    secret = strsep(&stringp, ":");
06038    stringp=hostname;
06039    hostname = strsep(&stringp, ":");
06040    porta = strsep(&stringp, ":");
06041    
06042    if (porta && !atoi(porta)) {
06043       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06044       return -1;
06045    }
06046    if (!(reg = ast_calloc(1, sizeof(*reg))))
06047       return -1;
06048    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
06049       free(reg);
06050       return -1;
06051    }
06052    ast_copy_string(reg->username, username, sizeof(reg->username));
06053    if (secret)
06054       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06055    reg->expire = -1;
06056    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06057    reg->addr.sin_family = AF_INET;
06058    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06059    AST_LIST_LOCK(&registrations);
06060    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
06061    AST_LIST_UNLOCK(&registrations);
06062    
06063    return 0;
06064 }
06065 
06066 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06067 {
06068    char multi[256];
06069    char *stringp, *ext;
06070    if (!ast_strlen_zero(regcontext)) {
06071       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06072       stringp = multi;
06073       while((ext = strsep(&stringp, "&"))) {
06074          if (onoff) {
06075             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06076                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06077                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06078          } else
06079             ast_context_remove_extension(regcontext, ext, 1, NULL);
06080       }
06081    }
06082 }
06083 static void prune_peers(void);
06084 
06085 static void unlink_peer(struct iax2_peer *peer)
06086 {
06087    if (peer->expire > -1) {
06088       if (!ast_sched_del(sched, peer->expire)) {
06089          peer->expire = -1;
06090          peer_unref(peer);
06091       }
06092    }
06093 
06094    if (peer->pokeexpire > -1) {
06095       if (!ast_sched_del(sched, peer->pokeexpire)) {
06096          peer->pokeexpire = -1;
06097          peer_unref(peer);
06098       }
06099    }
06100 
06101    ao2_unlink(peers, peer);
06102 }
06103 
06104 static void __expire_registry(const void *data)
06105 {
06106    struct iax2_peer *peer = (struct iax2_peer *) data;
06107 
06108    if (!peer)
06109       return;
06110 
06111    peer->expire = -1;
06112 
06113    if (option_debug)
06114       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06115    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06116       realtime_update_peer(peer->name, &peer->addr, 0);
06117    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06118    /* Reset the address */
06119    memset(&peer->addr, 0, sizeof(peer->addr));
06120    /* Reset expiry value */
06121    peer->expiry = min_reg_expire;
06122    if (!ast_test_flag(peer, IAX_TEMPONLY))
06123       ast_db_del("IAX/Registry", peer->name);
06124    register_peer_exten(peer, 0);
06125    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
06126    if (iax2_regfunk)
06127       iax2_regfunk(peer->name, 0);
06128 
06129    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06130       unlink_peer(peer);
06131 
06132    peer_unref(peer);
06133 }
06134 
06135 static int expire_registry(const void *data)
06136 {
06137 #ifdef SCHED_MULTITHREADED
06138    if (schedule_action(__expire_registry, data))
06139 #endif      
06140       __expire_registry(data);
06141    return 0;
06142 }
06143 
06144 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06145 
06146 static void reg_source_db(struct iax2_peer *p)
06147 {
06148    char data[80];
06149    struct in_addr in;
06150    char *c, *d;
06151    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06152       c = strchr(data, ':');
06153       if (c) {
06154          *c = '\0';
06155          c++;
06156          if (inet_aton(data, &in)) {
06157             d = strchr(c, ':');
06158             if (d) {
06159                *d = '\0';
06160                d++;
06161                if (option_verbose > 2)
06162                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
06163                   ast_inet_ntoa(in), atoi(c), atoi(d));
06164                iax2_poke_peer(p, 0);
06165                p->expiry = atoi(d);
06166                memset(&p->addr, 0, sizeof(p->addr));
06167                p->addr.sin_family = AF_INET;
06168                p->addr.sin_addr = in;
06169                p->addr.sin_port = htons(atoi(c));
06170                if (p->expire > -1) {
06171                   if (!ast_sched_del(sched, p->expire)) {
06172                      p->expire = -1;
06173                      peer_unref(p);
06174                   }
06175                }
06176                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06177                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06178                if (p->expire == -1)
06179                   peer_unref(p);
06180                if (iax2_regfunk)
06181                   iax2_regfunk(p->name, 1);
06182                register_peer_exten(p, 1);
06183             }              
06184                
06185          }
06186       }
06187    }
06188 }
06189 
06190 /*!
06191  * \pre iaxsl[callno] is locked
06192  *
06193  * \note Since this function calls send_command_final(), the pvt struct for
06194  *       the given call number may disappear while executing this function.
06195  */
06196 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06197 {
06198    /* Called from IAX thread only, with proper iaxsl lock */
06199    struct iax_ie_data ied;
06200    struct iax2_peer *p;
06201    int msgcount;
06202    char data[80];
06203    int version;
06204    const char *peer_name;
06205    int res = -1;
06206 
06207    memset(&ied, 0, sizeof(ied));
06208 
06209    peer_name = ast_strdupa(iaxs[callno]->peer);
06210 
06211    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
06212    ast_mutex_unlock(&iaxsl[callno]);
06213    if (!(p = find_peer(peer_name, 1))) {
06214       ast_mutex_lock(&iaxsl[callno]);
06215       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06216       return -1;
06217    }
06218    ast_mutex_lock(&iaxsl[callno]);
06219    if (!iaxs[callno])
06220       goto return_unref;
06221 
06222    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06223       if (sin->sin_addr.s_addr) {
06224          time_t nowtime;
06225          time(&nowtime);
06226          realtime_update_peer(peer_name, sin, nowtime);
06227       } else {
06228          realtime_update_peer(peer_name, sin, 0);
06229       }
06230    }
06231    if (inaddrcmp(&p->addr, sin)) {
06232       if (iax2_regfunk)
06233          iax2_regfunk(p->name, 1);
06234       /* Stash the IP address from which they registered */
06235       memcpy(&p->addr, sin, sizeof(p->addr));
06236       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06237       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06238          ast_db_put("IAX/Registry", p->name, data);
06239          if  (option_verbose > 2)
06240             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06241                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06242          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06243          register_peer_exten(p, 1);
06244          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06245       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06246          if  (option_verbose > 2)
06247             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06248                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06249          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06250          register_peer_exten(p, 0);
06251          ast_db_del("IAX/Registry", p->name);
06252          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06253       }
06254       /* Update the host */
06255       /* Verify that the host is really there */
06256       iax2_poke_peer(p, callno);
06257    }     
06258 
06259    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06260    if (!iaxs[callno]) {
06261       res = 0;
06262       goto return_unref;
06263    }
06264 
06265    /* Store socket fd */
06266    p->sockfd = fd;
06267    /* Setup the expiry */
06268    if (p->expire > -1) {
06269       if (!ast_sched_del(sched, p->expire)) {
06270          p->expire = -1;
06271          peer_unref(p);
06272       }
06273    }
06274    /* treat an unspecified refresh interval as the minimum */
06275    if (!refresh)
06276       refresh = min_reg_expire;
06277    if (refresh > max_reg_expire) {
06278       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06279          p->name, max_reg_expire, refresh);
06280       p->expiry = max_reg_expire;
06281    } else if (refresh < min_reg_expire) {
06282       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06283          p->name, min_reg_expire, refresh);
06284       p->expiry = min_reg_expire;
06285    } else {
06286       p->expiry = refresh;
06287    }
06288    if (p->expiry && sin->sin_addr.s_addr) {
06289       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06290       if (p->expire == -1)
06291          peer_unref(p);
06292    }
06293    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06294    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06295    if (sin->sin_addr.s_addr) {
06296       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06297       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06298       if (!ast_strlen_zero(p->mailbox)) {
06299          int new, old;
06300          ast_app_inboxcount(p->mailbox, &new, &old);
06301          if (new > 255)
06302             new = 255;
06303          if (old > 255)
06304             old = 255;
06305          msgcount = (old << 8) | new;
06306          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06307       }
06308       if (ast_test_flag(p, IAX_HASCALLERID)) {
06309          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06310          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06311       }
06312    }
06313    version = iax_check_version(devtype);
06314    if (version) 
06315       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06316 
06317    res = 0;
06318 
06319 return_unref:
06320    peer_unref(p);
06321 
06322    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06323 }
06324 
06325 static int registry_authrequest(int callno)
06326 {
06327    struct iax_ie_data ied;
06328    struct iax2_peer *p;
06329    char challenge[10];
06330    const char *peer_name;
06331    int sentauthmethod;
06332 
06333    peer_name = ast_strdupa(iaxs[callno]->peer);
06334 
06335    /* SLD: third call to find_peer in registration */
06336    ast_mutex_unlock(&iaxsl[callno]);
06337    if ((p = find_peer(peer_name, 1))) {
06338       last_authmethod = p->authmethods;
06339    }
06340 
06341    ast_mutex_lock(&iaxsl[callno]);
06342    if (!iaxs[callno])
06343       goto return_unref;
06344 
06345    memset(&ied, 0, sizeof(ied));
06346    /* The selection of which delayed reject is sent may leak information,
06347     * if it sets a static response.  For example, if a host is known to only
06348     * use MD5 authentication, then an RSA response would indicate that the
06349     * peer does not exist, and vice-versa.
06350     * Therefore, we use whatever the last peer used (which may vary over the
06351     * course of a server, which should leak minimal information). */
06352    sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06353    if (!p) {
06354       iaxs[callno]->authmethods = sentauthmethod;
06355    }
06356    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06357    if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06358       /* Build the challenge */
06359       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06360       ast_string_field_set(iaxs[callno], challenge, challenge);
06361       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06362    }
06363    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06364 
06365 return_unref:
06366    if (p) {
06367       peer_unref(p);
06368    }
06369 
06370    return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06371 }
06372 
06373 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06374 {
06375    struct iax2_registry *reg;
06376    /* Start pessimistic */
06377    struct iax_ie_data ied;
06378    char peer[256] = "";
06379    char challenge[256] = "";
06380    int res;
06381    int authmethods = 0;
06382    if (ies->authmethods)
06383       authmethods = ies->authmethods;
06384    if (ies->username)
06385       ast_copy_string(peer, ies->username, sizeof(peer));
06386    if (ies->challenge)
06387       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06388    memset(&ied, 0, sizeof(ied));
06389    reg = iaxs[callno]->reg;
06390    if (reg) {
06391          if (inaddrcmp(&reg->addr, sin)) {
06392             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06393             return -1;
06394          }
06395          if (ast_strlen_zero(reg->secret)) {
06396             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06397             reg->regstate = REG_STATE_NOAUTH;
06398             return -1;
06399          }
06400          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06401          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06402          if (reg->secret[0] == '[') {
06403             char tmpkey[256];
06404             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06405             tmpkey[strlen(tmpkey) - 1] = '\0';
06406             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
06407          } else
06408             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
06409          if (!res) {
06410             reg->regstate = REG_STATE_AUTHSENT;
06411             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06412          } else
06413             return -1;
06414          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06415    } else   
06416       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06417    return -1;
06418 }
06419 
06420 static void stop_stuff(int callno)
06421 {
06422    iax2_destroy_helper(iaxs[callno]);
06423 }
06424 
06425 static void __auth_reject(const void *nothing)
06426 {
06427    /* Called from IAX thread only, without iaxs lock */
06428    int callno = (int)(long)(nothing);
06429    struct iax_ie_data ied;
06430    ast_mutex_lock(&iaxsl[callno]);
06431    if (iaxs[callno]) {
06432       memset(&ied, 0, sizeof(ied));
06433       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06434          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06435          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06436       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06437          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06438          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06439       }
06440       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06441    }
06442    ast_mutex_unlock(&iaxsl[callno]);
06443 }
06444 
06445 static int auth_reject(const void *data)
06446 {
06447    int callno = (int)(long)(data);
06448    ast_mutex_lock(&iaxsl[callno]);
06449    if (iaxs[callno])
06450       iaxs[callno]->authid = -1;
06451    ast_mutex_unlock(&iaxsl[callno]);
06452 #ifdef SCHED_MULTITHREADED
06453    if (schedule_action(__auth_reject, data))
06454 #endif      
06455       __auth_reject(data);
06456    return 0;
06457 }
06458 
06459 static int auth_fail(int callno, int failcode)
06460 {
06461    /* Schedule sending the authentication failure in one second, to prevent
06462       guessing */
06463    if (iaxs[callno]) {
06464       iaxs[callno]->authfail = failcode;
06465       if (delayreject) {
06466          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06467          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06468       } else
06469          auth_reject((void *)(long)callno);
06470    }
06471    return 0;
06472 }
06473 
06474 static void __auto_hangup(const void *nothing)
06475 {
06476    /* Called from IAX thread only, without iaxs lock */
06477    int callno = (int)(long)(nothing);
06478    struct iax_ie_data ied;
06479    ast_mutex_lock(&iaxsl[callno]);
06480    if (iaxs[callno]) {
06481       memset(&ied, 0, sizeof(ied));
06482       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06483       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06484       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06485    }
06486    ast_mutex_unlock(&iaxsl[callno]);
06487 }
06488 
06489 static int auto_hangup(const void *data)
06490 {
06491    int callno = (int)(long)(data);
06492    ast_mutex_lock(&iaxsl[callno]);
06493    if (iaxs[callno]) {
06494       iaxs[callno]->autoid = -1;
06495    }
06496    ast_mutex_unlock(&iaxsl[callno]);
06497 #ifdef SCHED_MULTITHREADED
06498    if (schedule_action(__auto_hangup, data))
06499 #endif      
06500       __auto_hangup(data);
06501    return 0;
06502 }
06503 
06504 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06505 {
06506    struct iax_ie_data ied;
06507    /* Auto-hangup with 30 seconds of inactivity */
06508    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06509    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06510    memset(&ied, 0, sizeof(ied));
06511    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06512    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06513    dp->flags |= CACHE_FLAG_TRANSMITTED;
06514 }
06515 
06516 static int iax2_vnak(int callno)
06517 {
06518    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06519 }
06520 
06521 static void vnak_retransmit(int callno, int last)
06522 {
06523    struct iax_frame *f;
06524 
06525    AST_LIST_LOCK(&iaxq.queue);
06526    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06527       /* Send a copy immediately */
06528       if ((f->callno == callno) && iaxs[f->callno] &&
06529          ((unsigned char ) (f->oseqno - last) < 128) &&
06530          (f->retries >= 0)) {
06531          send_packet(f);
06532       }
06533    }
06534    AST_LIST_UNLOCK(&iaxq.queue);
06535 }
06536 
06537 static void __iax2_poke_peer_s(const void *data)
06538 {
06539    struct iax2_peer *peer = (struct iax2_peer *)data;
06540    iax2_poke_peer(peer, 0);
06541    peer_unref(peer);
06542 }
06543 
06544 static int iax2_poke_peer_s(const void *data)
06545 {
06546    struct iax2_peer *peer = (struct iax2_peer *)data;
06547    peer->pokeexpire = -1;
06548 #ifdef SCHED_MULTITHREADED
06549    if (schedule_action(__iax2_poke_peer_s, data))
06550 #endif      
06551       __iax2_poke_peer_s(data);
06552    return 0;
06553 }
06554 
06555 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06556 {
06557    int res = 0;
06558    struct iax_frame *fr;
06559    struct ast_iax2_meta_hdr *meta;
06560    struct ast_iax2_meta_trunk_hdr *mth;
06561    int calls = 0;
06562    
06563    /* Point to frame */
06564    fr = (struct iax_frame *)tpeer->trunkdata;
06565    /* Point to meta data */
06566    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06567    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06568    if (tpeer->trunkdatalen) {
06569       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06570       meta->zeros = 0;
06571       meta->metacmd = IAX_META_TRUNK;
06572       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06573          meta->cmddata = IAX_META_TRUNK_MINI;
06574       else
06575          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06576       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06577       /* And the rest of the ast_iax2 header */
06578       fr->direction = DIRECTION_OUTGRESS;
06579       fr->retrans = -1;
06580       fr->transfer = 0;
06581       /* Any appropriate call will do */
06582       fr->data = fr->afdata;
06583       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06584       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06585       calls = tpeer->calls;
06586 #if 0
06587       if (option_debug)
06588          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));
06589 #endif      
06590       /* Reset transmit trunk side data */
06591       tpeer->trunkdatalen = 0;
06592       tpeer->calls = 0;
06593    }
06594    if (res < 0)
06595       return res;
06596    return calls;
06597 }
06598 
06599 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06600 {
06601    /* Drop when trunk is about 5 seconds idle */
06602    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06603       return 1;
06604    return 0;
06605 }
06606 
06607 static int timing_read(int *id, int fd, short events, void *cbdata)
06608 {
06609    char buf[1024];
06610    int res;
06611    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06612    int processed = 0;
06613    int totalcalls = 0;
06614 #ifdef ZT_TIMERACK
06615    int x = 1;
06616 #endif
06617    struct timeval now;
06618    if (iaxtrunkdebug)
06619       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06620    gettimeofday(&now, NULL);
06621    if (events & AST_IO_PRI) {
06622 #ifdef ZT_TIMERACK
06623       /* Great, this is a timing interface, just call the ioctl */
06624       if (ioctl(fd, ZT_TIMERACK, &x)) {
06625          ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06626          usleep(1);
06627          return -1;
06628       }
06629 #endif      
06630    } else {
06631       /* Read and ignore from the pseudo channel for timing */
06632       res = read(fd, buf, sizeof(buf));
06633       if (res < 1) {
06634          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06635          return 1;
06636       }
06637    }
06638    /* For each peer that supports trunking... */
06639    ast_mutex_lock(&tpeerlock);
06640    tpeer = tpeers;
06641    while(tpeer) {
06642       processed++;
06643       res = 0;
06644       ast_mutex_lock(&tpeer->lock);
06645       /* We can drop a single tpeer per pass.  That makes all this logic
06646          substantially easier */
06647       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06648          /* Take it out of the list, but don't free it yet, because it
06649             could be in use */
06650          if (prev)
06651             prev->next = tpeer->next;
06652          else
06653             tpeers = tpeer->next;
06654          drop = tpeer;
06655       } else {
06656          res = send_trunk(tpeer, &now);
06657          if (iaxtrunkdebug)
06658             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);
06659       }     
06660       totalcalls += res;   
06661       res = 0;
06662       ast_mutex_unlock(&tpeer->lock);
06663       prev = tpeer;
06664       tpeer = tpeer->next;
06665    }
06666    ast_mutex_unlock(&tpeerlock);
06667    if (drop) {
06668       ast_mutex_lock(&drop->lock);
06669       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06670          because by the time they could get tpeerlock, we've already grabbed it */
06671       if (option_debug)
06672          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06673       if (drop->trunkdata) {
06674          free(drop->trunkdata);
06675          drop->trunkdata = NULL;
06676       }
06677       ast_mutex_unlock(&drop->lock);
06678       ast_mutex_destroy(&drop->lock);
06679       free(drop);
06680       
06681    }
06682    if (iaxtrunkdebug)
06683       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06684    iaxtrunkdebug =0;
06685    return 1;
06686 }
06687 
06688 struct dpreq_data {
06689    int callno;
06690    char context[AST_MAX_EXTENSION];
06691    char callednum[AST_MAX_EXTENSION];
06692    char *callerid;
06693 };
06694 
06695 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06696 {
06697    unsigned short dpstatus = 0;
06698    struct iax_ie_data ied1;
06699    int mm;
06700 
06701    memset(&ied1, 0, sizeof(ied1));
06702    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06703    /* Must be started */
06704    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06705       dpstatus = IAX_DPSTATUS_EXISTS;
06706    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06707       dpstatus = IAX_DPSTATUS_CANEXIST;
06708    } else {
06709       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06710    }
06711    if (ast_ignore_pattern(context, callednum))
06712       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06713    if (mm)
06714       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06715    if (!skiplock)
06716       ast_mutex_lock(&iaxsl[callno]);
06717    if (iaxs[callno]) {
06718       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06719       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06720       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06721       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06722    }
06723    if (!skiplock)
06724       ast_mutex_unlock(&iaxsl[callno]);
06725 }
06726 
06727 static void *dp_lookup_thread(void *data)
06728 {
06729    /* Look up for dpreq */
06730    struct dpreq_data *dpr = data;
06731    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06732    if (dpr->callerid)
06733       free(dpr->callerid);
06734    free(dpr);
06735    return NULL;
06736 }
06737 
06738 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06739 {
06740    pthread_t newthread;
06741    struct dpreq_data *dpr;
06742    pthread_attr_t attr;
06743    
06744    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06745       return;
06746 
06747    pthread_attr_init(&attr);
06748    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06749 
06750    dpr->callno = callno;
06751    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06752    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06753    if (callerid)
06754       dpr->callerid = ast_strdup(callerid);
06755    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06756       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06757    }
06758 
06759    pthread_attr_destroy(&attr);
06760 }
06761 
06762 struct iax_dual {
06763    struct ast_channel *chan1;
06764    struct ast_channel *chan2;
06765 };
06766 
06767 static void *iax_park_thread(void *stuff)
06768 {
06769    struct ast_channel *chan1, *chan2;
06770    struct iax_dual *d;
06771    struct ast_frame *f;
06772    int ext;
06773    int res;
06774    d = stuff;
06775    chan1 = d->chan1;
06776    chan2 = d->chan2;
06777    free(d);
06778    f = ast_read(chan1);
06779    if (f)
06780       ast_frfree(f);
06781    res = ast_park_call(chan1, chan2, 0, &ext);
06782    ast_hangup(chan2);
06783    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06784    return NULL;
06785 }
06786 
06787 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06788 {
06789    struct iax_dual *d;
06790    struct ast_channel *chan1m, *chan2m;
06791    pthread_t th;
06792    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06793    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06794    if (chan2m && chan1m) {
06795       /* Make formats okay */
06796       chan1m->readformat = chan1->readformat;
06797       chan1m->writeformat = chan1->writeformat;
06798       ast_channel_masquerade(chan1m, chan1);
06799       /* Setup the extensions and such */
06800       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06801       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06802       chan1m->priority = chan1->priority;
06803       
06804       /* We make a clone of the peer channel too, so we can play
06805          back the announcement */
06806       /* Make formats okay */
06807       chan2m->readformat = chan2->readformat;
06808       chan2m->writeformat = chan2->writeformat;
06809       ast_channel_masquerade(chan2m, chan2);
06810       /* Setup the extensions and such */
06811       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06812       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06813       chan2m->priority = chan2->priority;
06814       if (ast_do_masquerade(chan2m)) {
06815          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06816          ast_hangup(chan2m);
06817          return -1;
06818       }
06819    } else {
06820       if (chan1m)
06821          ast_hangup(chan1m);
06822       if (chan2m)
06823          ast_hangup(chan2m);
06824       return -1;
06825    }
06826    if ((d = ast_calloc(1, sizeof(*d)))) {
06827       pthread_attr_t attr;
06828 
06829       pthread_attr_init(&attr);
06830       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06831 
06832       d->chan1 = chan1m;
06833       d->chan2 = chan2m;
06834       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06835          pthread_attr_destroy(&attr);
06836          return 0;
06837       }
06838       pthread_attr_destroy(&attr);
06839       free(d);
06840    }
06841    return -1;
06842 }
06843 
06844 
06845 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06846 
06847 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06848 {
06849    unsigned int ourver;
06850    char rsi[80];
06851    snprintf(rsi, sizeof(rsi), "si-%s", si);
06852    if (iax_provision_version(&ourver, rsi, 1))
06853       return 0;
06854    if (option_debug)
06855       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06856    if (ourver != ver) 
06857       iax2_provision(sin, sockfd, NULL, rsi, 1);
06858    return 0;
06859 }
06860 
06861 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06862 {
06863    jb_info stats;
06864    jb_getinfo(pvt->jb, &stats);
06865    
06866    memset(iep, 0, sizeof(*iep));
06867 
06868    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06869    if(stats.frames_in == 0) stats.frames_in = 1;
06870    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06871    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06872    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06873    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06874    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06875 }
06876 
06877 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06878 {
06879    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06880    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06881    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06882    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06883    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06884    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06885    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06886 }
06887 
06888 static int socket_process(struct iax2_thread *thread);
06889 
06890 /*!
06891  * \brief Handle any deferred full frames for this thread
06892  */
06893 static void handle_deferred_full_frames(struct iax2_thread *thread)
06894 {
06895    struct iax2_pkt_buf *pkt_buf;
06896 
06897    ast_mutex_lock(&thread->lock);
06898 
06899    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06900       ast_mutex_unlock(&thread->lock);
06901 
06902       thread->buf = pkt_buf->buf;
06903       thread->buf_len = pkt_buf->len;
06904       thread->buf_size = pkt_buf->len + 1;
06905       
06906       socket_process(thread);
06907 
06908       thread->buf = NULL;
06909       ast_free(pkt_buf);
06910 
06911       ast_mutex_lock(&thread->lock);
06912    }
06913 
06914    ast_mutex_unlock(&thread->lock);
06915 }
06916 
06917 /*!
06918  * \brief Queue the last read full frame for processing by a certain thread
06919  *
06920  * If there are already any full frames queued, they are sorted
06921  * by sequence number.
06922  */
06923 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06924 {
06925    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06926    struct ast_iax2_full_hdr *fh, *cur_fh;
06927 
06928    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06929       return;
06930 
06931    pkt_buf->len = from_here->buf_len;
06932    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06933 
06934    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06935    ast_mutex_lock(&to_here->lock);
06936    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06937       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06938       if (fh->oseqno < cur_fh->oseqno) {
06939          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06940          break;
06941       }
06942    }
06943    AST_LIST_TRAVERSE_SAFE_END
06944 
06945    if (!cur_pkt_buf)
06946       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06947    
06948    ast_mutex_unlock(&to_here->lock);
06949 }
06950 
06951 static int socket_read(int *id, int fd, short events, void *cbdata)
06952 {
06953    struct iax2_thread *thread;
06954    socklen_t len;
06955    time_t t;
06956    static time_t last_errtime = 0;
06957    struct ast_iax2_full_hdr *fh;
06958 
06959    if (!(thread = find_idle_thread())) {
06960       time(&t);
06961       if (t != last_errtime && option_debug)
06962          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06963       last_errtime = t;
06964       usleep(1);
06965       return 1;
06966    }
06967 
06968    len = sizeof(thread->iosin);
06969    thread->iofd = fd;
06970    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06971    thread->buf_size = sizeof(thread->readbuf);
06972    thread->buf = thread->readbuf;
06973    if (thread->buf_len < 0) {
06974       if (errno != ECONNREFUSED && errno != EAGAIN)
06975          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06976       handle_error();
06977       thread->iostate = IAX_IOSTATE_IDLE;
06978       signal_condition(&thread->lock, &thread->cond);
06979       return 1;
06980    }
06981    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06982       thread->iostate = IAX_IOSTATE_IDLE;
06983       signal_condition(&thread->lock, &thread->cond);
06984       return 1;
06985    }
06986    
06987    /* Determine if this frame is a full frame; if so, and any thread is currently
06988       processing a full frame for the same callno from this peer, then drop this
06989       frame (and the peer will retransmit it) */
06990    fh = (struct ast_iax2_full_hdr *) thread->buf;
06991    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06992       struct iax2_thread *cur = NULL;
06993       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06994       
06995       AST_LIST_LOCK(&active_list);
06996       AST_LIST_TRAVERSE(&active_list, cur, list) {
06997          if ((cur->ffinfo.callno == callno) &&
06998              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06999             break;
07000       }
07001       if (cur) {
07002          /* we found another thread processing a full frame for this call,
07003             so queue it up for processing later. */
07004          defer_full_frame(thread, cur);
07005          AST_LIST_UNLOCK(&active_list);
07006          thread->iostate = IAX_IOSTATE_IDLE;
07007          signal_condition(&thread->lock, &thread->cond);
07008          return 1;
07009       } else {
07010          /* this thread is going to process this frame, so mark it */
07011          thread->ffinfo.callno = callno;
07012          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
07013          thread->ffinfo.type = fh->type;
07014          thread->ffinfo.csub = fh->csub;
07015       }
07016       AST_LIST_UNLOCK(&active_list);
07017    }
07018    
07019    /* Mark as ready and send on its way */
07020    thread->iostate = IAX_IOSTATE_READY;
07021 #ifdef DEBUG_SCHED_MULTITHREAD
07022    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07023 #endif
07024    signal_condition(&thread->lock, &thread->cond);
07025 
07026    return 1;
07027 }
07028 
07029 static int socket_process(struct iax2_thread *thread)
07030 {
07031    struct sockaddr_in sin;
07032    int res;
07033    int updatehistory=1;
07034    int new = NEW_PREVENT;
07035    void *ptr;
07036    int dcallno = 0;
07037    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07038    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07039    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07040    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07041    struct ast_iax2_meta_trunk_hdr *mth;
07042    struct ast_iax2_meta_trunk_entry *mte;
07043    struct ast_iax2_meta_trunk_mini *mtm;
07044    struct iax_frame *fr;
07045    struct iax_frame *cur;
07046    struct ast_frame f = { 0, };
07047    struct ast_channel *c;
07048    struct iax2_dpcache *dp;
07049    struct iax2_peer *peer;
07050    struct iax2_trunk_peer *tpeer;
07051    struct timeval rxtrunktime;
07052    struct iax_ies ies;
07053    struct iax_ie_data ied0, ied1;
07054    int format;
07055    int fd;
07056    int exists;
07057    int minivid = 0;
07058    unsigned int ts;
07059    char empty[32]="";      /* Safety measure */
07060    struct iax_frame *duped_fr;
07061    char host_pref_buf[128];
07062    char caller_pref_buf[128];
07063    struct ast_codec_pref pref;
07064    char *using_prefs = "mine";
07065 
07066    /* allocate an iax_frame with 4096 bytes of data buffer */
07067    fr = alloca(sizeof(*fr) + 4096);
07068    memset(fr, 0, sizeof(*fr));
07069    fr->afdatalen = 4096; /* From alloca() above */
07070 
07071    /* Copy frequently used parameters to the stack */
07072    res = thread->buf_len;
07073    fd = thread->iofd;
07074    memcpy(&sin, &thread->iosin, sizeof(sin));
07075 
07076    if (res < sizeof(*mh)) {
07077       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07078       return 1;
07079    }
07080    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07081       if (res < sizeof(*vh)) {
07082          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));
07083          return 1;
07084       }
07085 
07086       /* This is a video frame, get call number */
07087       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07088       minivid = 1;
07089    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07090       unsigned char metatype;
07091 
07092       if (res < sizeof(*meta)) {
07093          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));
07094          return 1;
07095       }
07096 
07097       /* This is a meta header */
07098       switch(meta->metacmd) {
07099       case IAX_META_TRUNK:
07100          if (res < (sizeof(*meta) + sizeof(*mth))) {
07101             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07102                sizeof(*meta) + sizeof(*mth));
07103             return 1;
07104          }
07105          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07106          ts = ntohl(mth->ts);
07107          metatype = meta->cmddata;
07108          res -= (sizeof(*meta) + sizeof(*mth));
07109          ptr = mth->data;
07110          tpeer = find_tpeer(&sin, fd);
07111          if (!tpeer) {
07112             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));
07113             return 1;
07114          }
07115          tpeer->trunkact = ast_tvnow();
07116          if (!ts || ast_tvzero(tpeer->rxtrunktime))
07117             tpeer->rxtrunktime = tpeer->trunkact;
07118          rxtrunktime = tpeer->rxtrunktime;
07119          ast_mutex_unlock(&tpeer->lock);
07120          while(res >= sizeof(*mte)) {
07121             /* Process channels */
07122             unsigned short callno, trunked_ts, len;
07123 
07124             if (metatype == IAX_META_TRUNK_MINI) {
07125                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07126                ptr += sizeof(*mtm);
07127                res -= sizeof(*mtm);
07128                len = ntohs(mtm->len);
07129                callno = ntohs(mtm->mini.callno);
07130                trunked_ts = ntohs(mtm->mini.ts);
07131             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07132                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07133                ptr += sizeof(*mte);
07134                res -= sizeof(*mte);
07135                len = ntohs(mte->len);
07136                callno = ntohs(mte->callno);
07137                trunked_ts = 0;
07138             } else {
07139                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07140                break;
07141             }
07142             /* Stop if we don't have enough data */
07143             if (len > res)
07144                break;
07145             fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07146             if (fr->callno) {
07147                /* If it's a valid call, deliver the contents.  If not, we
07148                   drop it, since we don't have a scallno to use for an INVAL */
07149                /* Process as a mini frame */
07150                memset(&f, 0, sizeof(f));
07151                f.frametype = AST_FRAME_VOICE;
07152                if (iaxs[fr->callno]) {
07153                   if (iaxs[fr->callno]->voiceformat > 0) {
07154                      f.subclass = iaxs[fr->callno]->voiceformat;
07155                      f.datalen = len;
07156                      if (f.datalen >= 0) {
07157                         if (f.datalen)
07158                            f.data = ptr;
07159                         if(trunked_ts) {
07160                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07161                         } else
07162                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07163                         /* Don't pass any packets until we're started */
07164                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07165                            /* Common things */
07166                            f.src = "IAX2";
07167                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
07168                               f.samples = ast_codec_get_samples(&f);
07169                            iax_frame_wrap(fr, &f);
07170                            duped_fr = iaxfrdup2(fr);
07171                            if (duped_fr) {
07172                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07173                            }
07174                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
07175                            if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07176                               iaxs[fr->callno]->last = fr->ts;
07177 #if 1
07178                               if (option_debug && iaxdebug)
07179                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07180 #endif
07181                            }
07182                         }
07183                      } else {
07184                         ast_log(LOG_WARNING, "Datalen < 0?\n");
07185                      }
07186                   } else {
07187                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07188                      iax2_vnak(fr->callno);
07189                   }
07190                }
07191                ast_mutex_unlock(&iaxsl[fr->callno]);
07192             }
07193             ptr += len;
07194             res -= len;
07195          }
07196          
07197       }
07198       return 1;
07199    }
07200 
07201 #ifdef DEBUG_SUPPORT
07202    if (iaxdebug && (res >= sizeof(*fh)))
07203       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07204 #endif
07205    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07206       if (res < sizeof(*fh)) {
07207          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));
07208          return 1;
07209       }
07210 
07211       /* Get the destination call number */
07212       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07213       /* Retrieve the type and subclass */
07214       f.frametype = fh->type;
07215       if (f.frametype == AST_FRAME_VIDEO) {
07216          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07217       } else {
07218          f.subclass = uncompress_subclass(fh->csub);
07219       }
07220 
07221       /* Deal with POKE/PONG without allocating a callno */
07222       if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07223          /* Reply back with a PONG, but don't care about the result. */
07224          send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07225          return 1;
07226       } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07227          /* Ignore */
07228          return 1;
07229       }
07230 
07231       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07232                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07233                          (f.subclass == IAX_COMMAND_REGREL)))
07234          new = NEW_ALLOW;
07235    } else {
07236       /* Don't know anything about it yet */
07237       f.frametype = AST_FRAME_NULL;
07238       f.subclass = 0;
07239    }
07240 
07241    if (!fr->callno) {
07242       int check_dcallno = 0;
07243 
07244       /*
07245        * We enforce accurate destination call numbers for all full frames except
07246        * LAGRQ and PING commands.  This is because older versions of Asterisk
07247        * schedule these commands to get sent very quickly, and they will sometimes
07248        * be sent before they receive the first frame from the other side.  When
07249        * that happens, it doesn't contain the destination call number.  However,
07250        * not checking it for these frames is safe.
07251        * 
07252        * Discussed in the following thread:
07253        *    http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 
07254        */
07255 
07256       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07257          check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07258       }
07259 
07260       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07261    }
07262 
07263    if (fr->callno > 0)
07264       ast_mutex_lock(&iaxsl[fr->callno]);
07265 
07266    if (!fr->callno || !iaxs[fr->callno]) {
07267       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07268          frame, reply with an inval */
07269       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07270          /* We can only raw hangup control frames */
07271          if (((f.subclass != IAX_COMMAND_INVAL) &&
07272              (f.subclass != IAX_COMMAND_TXCNT) &&
07273              (f.subclass != IAX_COMMAND_TXACC) &&
07274              (f.subclass != IAX_COMMAND_FWDOWNL))||
07275              (f.frametype != AST_FRAME_IAX))
07276             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07277             fd);
07278       }
07279       if (fr->callno > 0) 
07280          ast_mutex_unlock(&iaxsl[fr->callno]);
07281       return 1;
07282    }
07283    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07284       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07285          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07286          ast_mutex_unlock(&iaxsl[fr->callno]);
07287          return 1;
07288       }
07289 #ifdef DEBUG_SUPPORT
07290       else if (iaxdebug)
07291          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07292 #endif
07293    }
07294 
07295    /* count this frame */
07296    iaxs[fr->callno]->frames_received++;
07297 
07298    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07299       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07300       f.subclass != IAX_COMMAND_TXACC) {     /* for attended transfer */
07301       unsigned short new_peercallno;
07302 
07303       new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07304       if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07305          if (iaxs[fr->callno]->peercallno) {
07306             remove_by_peercallno(iaxs[fr->callno]);
07307          }
07308          iaxs[fr->callno]->peercallno = new_peercallno;
07309          store_by_peercallno(iaxs[fr->callno]);
07310       }
07311    }
07312    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07313       if (option_debug  && iaxdebug)
07314          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07315       /* Check if it's out of order (and not an ACK or INVAL) */
07316       fr->oseqno = fh->oseqno;
07317       fr->iseqno = fh->iseqno;
07318       fr->ts = ntohl(fh->ts);
07319 #ifdef IAXTESTS
07320       if (test_resync) {
07321          if (option_debug)
07322             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07323          fr->ts += test_resync;
07324       }
07325 #endif /* IAXTESTS */
07326 #if 0
07327       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07328            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07329                         (f.subclass == IAX_COMMAND_NEW ||
07330                          f.subclass == IAX_COMMAND_AUTHREQ ||
07331                          f.subclass == IAX_COMMAND_ACCEPT ||
07332                          f.subclass == IAX_COMMAND_REJECT))      ) )
07333 #endif
07334       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07335          updatehistory = 0;
07336       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07337          (iaxs[fr->callno]->iseqno ||
07338             ((f.subclass != IAX_COMMAND_TXCNT) &&
07339             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07340             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07341             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07342             (f.subclass != IAX_COMMAND_TXACC)) ||
07343             (f.frametype != AST_FRAME_IAX))) {
07344          if (
07345           ((f.subclass != IAX_COMMAND_ACK) &&
07346            (f.subclass != IAX_COMMAND_INVAL) &&
07347            (f.subclass != IAX_COMMAND_TXCNT) &&
07348            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07349            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07350            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07351            (f.subclass != IAX_COMMAND_TXACC) &&
07352            (f.subclass != IAX_COMMAND_VNAK)) ||
07353            (f.frametype != AST_FRAME_IAX)) {
07354             /* If it's not an ACK packet, it's out of order. */
07355             if (option_debug)
07356                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07357                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07358             /* Check to see if we need to request retransmission,
07359              * and take sequence number wraparound into account */
07360             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07361                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07362                if ((f.frametype != AST_FRAME_IAX) || 
07363                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07364                   if (option_debug)
07365                      ast_log(LOG_DEBUG, "Acking anyway\n");
07366                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07367                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07368                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07369                }
07370             } else {
07371                /* Send a VNAK requesting retransmission */
07372                iax2_vnak(fr->callno);
07373             }
07374             ast_mutex_unlock(&iaxsl[fr->callno]);
07375             return 1;
07376          }
07377       } else {
07378          /* Increment unless it's an ACK or VNAK */
07379          if (((f.subclass != IAX_COMMAND_ACK) &&
07380              (f.subclass != IAX_COMMAND_INVAL) &&
07381              (f.subclass != IAX_COMMAND_TXCNT) &&
07382              (f.subclass != IAX_COMMAND_TXACC) &&
07383             (f.subclass != IAX_COMMAND_VNAK)) ||
07384              (f.frametype != AST_FRAME_IAX))
07385             iaxs[fr->callno]->iseqno++;
07386       }
07387       /* A full frame */
07388       if (res < sizeof(*fh)) {
07389          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07390          ast_mutex_unlock(&iaxsl[fr->callno]);
07391          return 1;
07392       }
07393       /* Ensure text frames are NULL-terminated */
07394       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07395          if (res < thread->buf_size)
07396             thread->buf[res++] = '\0';
07397          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07398             thread->buf[res - 1] = '\0';
07399       }
07400       f.datalen = res - sizeof(*fh);
07401 
07402       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07403          from the real peer, not the transfer peer */
07404       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07405           ((f.subclass != IAX_COMMAND_INVAL) ||
07406            (f.frametype != AST_FRAME_IAX))) {
07407          unsigned char x;
07408          int call_to_destroy;
07409          /* XXX This code is not very efficient.  Surely there is a better way which still
07410                 properly handles boundary conditions? XXX */
07411          /* First we have to qualify that the ACKed value is within our window */
07412          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07413             if (fr->iseqno == x)
07414                break;
07415          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07416             /* The acknowledgement is within our window.  Time to acknowledge everything
07417                that it says to */
07418             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07419                /* Ack the packet with the given timestamp */
07420                if (option_debug && iaxdebug)
07421                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07422                call_to_destroy = 0;
07423                AST_LIST_LOCK(&iaxq.queue);
07424                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07425                   /* If it's our call, and our timestamp, mark -1 retries */
07426                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07427                      cur->retries = -1;
07428                      /* Destroy call if this is the end */
07429                      if (cur->final)
07430                         call_to_destroy = fr->callno;
07431                   }
07432                }
07433                AST_LIST_UNLOCK(&iaxq.queue);
07434                if (call_to_destroy) {
07435                   if (iaxdebug && option_debug)
07436                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07437                   ast_mutex_lock(&iaxsl[call_to_destroy]);
07438                   iax2_destroy(call_to_destroy);
07439                   ast_mutex_unlock(&iaxsl[call_to_destroy]);
07440                }
07441             }
07442             /* Note how much we've received acknowledgement for */
07443             if (iaxs[fr->callno])
07444                iaxs[fr->callno]->rseqno = fr->iseqno;
07445             else {
07446                /* Stop processing now */
07447                ast_mutex_unlock(&iaxsl[fr->callno]);
07448                return 1;
07449             }
07450          } else if (option_debug)
07451             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07452       }
07453       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07454          ((f.frametype != AST_FRAME_IAX) || 
07455           ((f.subclass != IAX_COMMAND_TXACC) &&
07456            (f.subclass != IAX_COMMAND_TXCNT)))) {
07457          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07458          ast_mutex_unlock(&iaxsl[fr->callno]);
07459          return 1;
07460       }
07461 
07462       if (f.datalen) {
07463          if (f.frametype == AST_FRAME_IAX) {
07464             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07465                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07466                ast_mutex_unlock(&iaxsl[fr->callno]);
07467                return 1;
07468             }
07469             f.data = NULL;
07470             f.datalen = 0;
07471          } else
07472             f.data = thread->buf + sizeof(*fh);
07473       } else {
07474          if (f.frametype == AST_FRAME_IAX)
07475             f.data = NULL;
07476          else
07477             f.data = empty;
07478          memset(&ies, 0, sizeof(ies));
07479       }
07480 
07481       /* when we receive the first full frame for a new incoming channel,
07482          it is safe to start the PBX on the channel because we have now
07483          completed a 3-way handshake with the peer */
07484       if ((f.frametype == AST_FRAME_VOICE) ||
07485           (f.frametype == AST_FRAME_VIDEO) ||
07486           (f.frametype == AST_FRAME_IAX)) {
07487          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07488             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07489             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07490                ast_mutex_unlock(&iaxsl[fr->callno]);
07491                return 1;
07492             }
07493          }
07494       }
07495 
07496       if (f.frametype == AST_FRAME_VOICE) {
07497          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07498                iaxs[fr->callno]->voiceformat = f.subclass;
07499                if (option_debug)
07500                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07501                if (iaxs[fr->callno]->owner) {
07502                   int orignative;
07503 retryowner:
07504                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07505                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07506                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07507                   }
07508                   if (iaxs[fr->callno]) {
07509                      if (iaxs[fr->callno]->owner) {
07510                         orignative = iaxs[fr->callno]->owner->nativeformats;
07511                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07512                         if (iaxs[fr->callno]->owner->readformat)
07513                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07514                         iaxs[fr->callno]->owner->nativeformats = orignative;
07515                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07516                      }
07517                   } else {
07518                      if (option_debug)
07519                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07520                      ast_mutex_unlock(&iaxsl[fr->callno]);
07521                      return 1;
07522                   }
07523                }
07524          }
07525       }
07526       if (f.frametype == AST_FRAME_VIDEO) {
07527          if (f.subclass != iaxs[fr->callno]->videoformat) {
07528             if (option_debug)
07529                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07530             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07531          }
07532       }
07533       if (f.frametype == AST_FRAME_IAX) {
07534          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07535          /* Handle the IAX pseudo frame itself */
07536          if (option_debug && iaxdebug)
07537             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07538 
07539                         /* Update last ts unless the frame's timestamp originated with us. */
07540          if (iaxs[fr->callno]->last < fr->ts &&
07541                             f.subclass != IAX_COMMAND_ACK &&
07542                             f.subclass != IAX_COMMAND_PONG &&
07543                             f.subclass != IAX_COMMAND_LAGRP) {
07544             iaxs[fr->callno]->last = fr->ts;
07545             if (option_debug && iaxdebug)
07546                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07547          }
07548 
07549          switch(f.subclass) {
07550          case IAX_COMMAND_ACK:
07551             /* Do nothing */
07552             break;
07553          case IAX_COMMAND_QUELCH:
07554             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07555                     /* Generate Manager Hold event, if necessary*/
07556                if (iaxs[fr->callno]->owner) {
07557                   manager_event(EVENT_FLAG_CALL, "Hold",
07558                      "Channel: %s\r\n"
07559                      "Uniqueid: %s\r\n",
07560                      iaxs[fr->callno]->owner->name, 
07561                      iaxs[fr->callno]->owner->uniqueid);
07562                }
07563 
07564                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07565                if (ies.musiconhold) {
07566                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07567                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07568                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07569                         S_OR(mohsuggest, NULL),
07570                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07571                      if (!iaxs[fr->callno]) {
07572                         ast_mutex_unlock(&iaxsl[fr->callno]);
07573                         return 1;
07574                      }
07575                   }
07576                }
07577             }
07578             break;
07579          case IAX_COMMAND_UNQUELCH:
07580             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07581                     /* Generate Manager Unhold event, if necessary*/
07582                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07583                   manager_event(EVENT_FLAG_CALL, "Unhold",
07584                      "Channel: %s\r\n"
07585                      "Uniqueid: %s\r\n",
07586                      iaxs[fr->callno]->owner->name, 
07587                      iaxs[fr->callno]->owner->uniqueid);
07588                }
07589 
07590                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07591                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07592                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07593                   if (!iaxs[fr->callno]) {
07594                      ast_mutex_unlock(&iaxsl[fr->callno]);
07595                      return 1;
07596                   }
07597                }
07598             }
07599             break;
07600          case IAX_COMMAND_TXACC:
07601             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07602                /* Ack the packet with the given timestamp */
07603                AST_LIST_LOCK(&iaxq.queue);
07604                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07605                   /* Cancel any outstanding txcnt's */
07606                   if ((fr->callno == cur->callno) && (cur->transfer))
07607                      cur->retries = -1;
07608                }
07609                AST_LIST_UNLOCK(&iaxq.queue);
07610                memset(&ied1, 0, sizeof(ied1));
07611                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07612                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07613                iaxs[fr->callno]->transferring = TRANSFER_READY;
07614             }
07615             break;
07616          case IAX_COMMAND_NEW:
07617             /* Ignore if it's already up */
07618             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07619                break;
07620             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07621                ast_mutex_unlock(&iaxsl[fr->callno]);
07622                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07623                ast_mutex_lock(&iaxsl[fr->callno]);
07624                if (!iaxs[fr->callno]) {
07625                   ast_mutex_unlock(&iaxsl[fr->callno]);
07626                   return 1;
07627                }
07628             }
07629             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07630             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07631                int new_callno;
07632                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07633                   fr->callno = new_callno;
07634             }
07635             /* For security, always ack immediately */
07636             if (delayreject)
07637                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07638             if (check_access(fr->callno, &sin, &ies)) {
07639                /* They're not allowed on */
07640                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07641                if (authdebug)
07642                   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);
07643                break;
07644             }
07645             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07646                const char *context, *exten, *cid_num;
07647 
07648                context = ast_strdupa(iaxs[fr->callno]->context);
07649                exten = ast_strdupa(iaxs[fr->callno]->exten);
07650                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07651 
07652                /* This might re-enter the IAX code and need the lock */
07653                ast_mutex_unlock(&iaxsl[fr->callno]);
07654                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07655                ast_mutex_lock(&iaxsl[fr->callno]);
07656 
07657                if (!iaxs[fr->callno]) {
07658                   ast_mutex_unlock(&iaxsl[fr->callno]);
07659                   return 1;
07660                }
07661             } else
07662                exists = 0;
07663             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07664                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07665                   memset(&ied0, 0, sizeof(ied0));
07666                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07667                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07668                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07669                   if (!iaxs[fr->callno]) {
07670                      ast_mutex_unlock(&iaxsl[fr->callno]);
07671                      return 1;
07672                   }
07673                   if (authdebug)
07674                      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);
07675                } else {
07676                   /* Select an appropriate format */
07677 
07678                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07679                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07680                         using_prefs = "reqonly";
07681                      } else {
07682                         using_prefs = "disabled";
07683                      }
07684                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07685                      memset(&pref, 0, sizeof(pref));
07686                      strcpy(caller_pref_buf, "disabled");
07687                      strcpy(host_pref_buf, "disabled");
07688                   } else {
07689                      using_prefs = "mine";
07690                      /* If the information elements are in here... use them */
07691                      if (ies.codec_prefs)
07692                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07693                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07694                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07695                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07696                            pref = iaxs[fr->callno]->rprefs;
07697                            using_prefs = "caller";
07698                         } else {
07699                            pref = iaxs[fr->callno]->prefs;
07700                         }
07701                      } else
07702                         pref = iaxs[fr->callno]->prefs;
07703                      
07704                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07705                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07706                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07707                   }
07708                   if (!format) {
07709                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07710                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07711                      if (!format) {
07712                         memset(&ied0, 0, sizeof(ied0));
07713                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07714                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07715                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07716                         if (!iaxs[fr->callno]) {
07717                            ast_mutex_unlock(&iaxsl[fr->callno]);
07718                            return 1;
07719                         }
07720                         if (authdebug) {
07721                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07722                               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);
07723                            else 
07724                               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);
07725                         }
07726                      } else {
07727                         /* Pick one... */
07728                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07729                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07730                               format = 0;
07731                         } else {
07732                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07733                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07734                               memset(&pref, 0, sizeof(pref));
07735                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07736                               strcpy(caller_pref_buf,"disabled");
07737                               strcpy(host_pref_buf,"disabled");
07738                            } else {
07739                               using_prefs = "mine";
07740                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07741                                  /* Do the opposite of what we tried above. */
07742                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07743                                     pref = iaxs[fr->callno]->prefs;                       
07744                                  } else {
07745                                     pref = iaxs[fr->callno]->rprefs;
07746                                     using_prefs = "caller";
07747                                  }
07748                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07749                            
07750                               } else /* if no codec_prefs IE do it the old way */
07751                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07752                            }
07753                         }
07754 
07755                         if (!format) {
07756                            memset(&ied0, 0, sizeof(ied0));
07757                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07758                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07759                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07760                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07761                            if (!iaxs[fr->callno]) {
07762                               ast_mutex_unlock(&iaxsl[fr->callno]);
07763                               return 1;
07764                            }
07765                            if (authdebug)
07766                               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);
07767                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07768                            break;
07769                         }
07770                      }
07771                   }
07772                   if (format) {
07773                      /* No authentication required, let them in */
07774                      memset(&ied1, 0, sizeof(ied1));
07775                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07776                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07777                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07778                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07779                         if (option_verbose > 2) 
07780                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07781                                     "%srequested format = %s,\n"
07782                                     "%srequested prefs = %s,\n"
07783                                     "%sactual format = %s,\n"
07784                                     "%shost prefs = %s,\n"
07785                                     "%spriority = %s\n",
07786                                     ast_inet_ntoa(sin.sin_addr), 
07787                                     VERBOSE_PREFIX_4,
07788                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07789                                     VERBOSE_PREFIX_4,
07790                                     caller_pref_buf,
07791                                     VERBOSE_PREFIX_4,
07792                                     ast_getformatname(format), 
07793                                     VERBOSE_PREFIX_4,
07794                                     host_pref_buf, 
07795                                     VERBOSE_PREFIX_4,
07796                                     using_prefs);
07797                         
07798                         iaxs[fr->callno]->chosenformat = format;
07799                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07800                      } else {
07801                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07802                         /* If this is a TBD call, we're ready but now what...  */
07803                         if (option_verbose > 2)
07804                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07805                      }
07806                   }
07807                }
07808                break;
07809             }
07810             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07811                merge_encryption(iaxs[fr->callno],ies.encmethods);
07812             else
07813                iaxs[fr->callno]->encmethods = 0;
07814             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07815                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07816             if (!iaxs[fr->callno]) {
07817                ast_mutex_unlock(&iaxsl[fr->callno]);
07818                return 1;
07819             }
07820             break;
07821          case IAX_COMMAND_DPREQ:
07822             /* Request status in the dialplan */
07823             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07824                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07825                if (iaxcompat) {
07826                   /* Spawn a thread for the lookup */
07827                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07828                } else {
07829                   /* Just look it up */
07830                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07831                }
07832             }
07833             break;
07834          case IAX_COMMAND_HANGUP:
07835             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07836             if (option_debug)
07837                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07838             /* Set hangup cause according to remote */
07839             if (ies.causecode && iaxs[fr->callno]->owner)
07840                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07841             /* Send ack immediately, before we destroy */
07842             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07843             iax2_destroy(fr->callno);
07844             break;
07845          case IAX_COMMAND_REJECT:
07846             /* Set hangup cause according to remote */
07847             if (ies.causecode && iaxs[fr->callno]->owner)
07848                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07849 
07850             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07851                if (iaxs[fr->callno]->owner && authdebug)
07852                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07853                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07854                      ies.cause ? ies.cause : "<Unknown>");
07855                if (option_debug)
07856                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07857                      fr->callno);
07858             }
07859             /* Send ack immediately, before we destroy */
07860             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07861                          fr->ts, NULL, 0, fr->iseqno);
07862             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07863                iaxs[fr->callno]->error = EPERM;
07864             iax2_destroy(fr->callno);
07865             break;
07866          case IAX_COMMAND_TRANSFER:
07867          {
07868             struct ast_channel *bridged_chan;
07869 
07870             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07871                /* Set BLINDTRANSFER channel variables */
07872 
07873                ast_mutex_unlock(&iaxsl[fr->callno]);
07874                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07875                ast_mutex_lock(&iaxsl[fr->callno]);
07876                if (!iaxs[fr->callno]) {
07877                   ast_mutex_unlock(&iaxsl[fr->callno]);
07878                   return 1;
07879                }
07880 
07881                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07882                if (!strcmp(ies.called_number, ast_parking_ext())) {
07883                   if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07884                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07885                   } else {
07886                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07887                   }
07888                } else {
07889                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07890                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07891                         ies.called_number, iaxs[fr->callno]->context);
07892                   else
07893                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07894                         ies.called_number, iaxs[fr->callno]->context);
07895                }
07896             } else
07897                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07898 
07899             break;
07900          }
07901          case IAX_COMMAND_ACCEPT:
07902             /* Ignore if call is already up or needs authentication or is a TBD */
07903             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07904                break;
07905             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07906                /* Send ack immediately, before we destroy */
07907                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07908                iax2_destroy(fr->callno);
07909                break;
07910             }
07911             if (ies.format) {
07912                iaxs[fr->callno]->peerformat = ies.format;
07913             } else {
07914                if (iaxs[fr->callno]->owner)
07915                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07916                else
07917                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07918             }
07919             if (option_verbose > 2)
07920                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));
07921             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07922                memset(&ied0, 0, sizeof(ied0));
07923                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07924                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07925                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07926                if (!iaxs[fr->callno]) {
07927                   ast_mutex_unlock(&iaxsl[fr->callno]);
07928                   return 1;
07929                }
07930                if (authdebug)
07931                   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);
07932             } else {
07933                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07934                if (iaxs[fr->callno]->owner) {
07935                   /* Switch us to use a compatible format */
07936                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07937                   if (option_verbose > 2)
07938                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07939 retryowner2:
07940                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07941                      DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07942                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07943                   }
07944                   
07945                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07946                      /* Setup read/write formats properly. */
07947                      if (iaxs[fr->callno]->owner->writeformat)
07948                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07949                      if (iaxs[fr->callno]->owner->readformat)
07950                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07951                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07952                   }
07953                }
07954             }
07955             if (iaxs[fr->callno]) {
07956                ast_mutex_lock(&dpcache_lock);
07957                dp = iaxs[fr->callno]->dpentries;
07958                while(dp) {
07959                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07960                      iax2_dprequest(dp, fr->callno);
07961                   }
07962                   dp = dp->peer;
07963                }
07964                ast_mutex_unlock(&dpcache_lock);
07965             }
07966             break;
07967          case IAX_COMMAND_POKE:
07968             /* Send back a pong packet with the original timestamp */
07969             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07970             if (!iaxs[fr->callno]) {
07971                ast_mutex_unlock(&iaxsl[fr->callno]);
07972                return 1;
07973             }
07974             break;
07975          case IAX_COMMAND_PING:
07976          {
07977             struct iax_ie_data pingied;
07978             construct_rr(iaxs[fr->callno], &pingied);
07979             /* Send back a pong packet with the original timestamp */
07980             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07981          }
07982             break;
07983          case IAX_COMMAND_PONG:
07984             /* Calculate ping time */
07985             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07986             /* save RR info */
07987             save_rr(fr, &ies);
07988 
07989             if (iaxs[fr->callno]->peerpoke) {
07990                peer = iaxs[fr->callno]->peerpoke;
07991                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07992                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07993                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07994                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07995                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07996                   }
07997                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07998                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07999                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
08000                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
08001                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08002                   }
08003                }
08004                peer->lastms = iaxs[fr->callno]->pingtime;
08005                if (peer->smoothing && (peer->lastms > -1))
08006                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
08007                else if (peer->smoothing && peer->lastms < 0)
08008                   peer->historicms = (0 + peer->historicms) / 2;
08009                else              
08010                   peer->historicms = iaxs[fr->callno]->pingtime;
08011 
08012                /* Remove scheduled iax2_poke_noanswer */
08013                if (peer->pokeexpire > -1) {
08014                   if (!ast_sched_del(sched, peer->pokeexpire)) {
08015                      peer_unref(peer);
08016                      peer->pokeexpire = -1;
08017                   }
08018                }
08019                /* Schedule the next cycle */
08020                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
08021                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08022                else
08023                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08024                if (peer->pokeexpire == -1)
08025                   peer_unref(peer);
08026                /* and finally send the ack */
08027                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08028                /* And wrap up the qualify call */
08029                iax2_destroy(fr->callno);
08030                peer->callno = 0;
08031                if (option_debug)
08032                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08033             }
08034             break;
08035          case IAX_COMMAND_LAGRQ:
08036          case IAX_COMMAND_LAGRP:
08037             f.src = "LAGRQ";
08038             f.mallocd = 0;
08039             f.offset = 0;
08040             f.samples = 0;
08041             iax_frame_wrap(fr, &f);
08042             if(f.subclass == IAX_COMMAND_LAGRQ) {
08043                /* Received a LAGRQ - echo back a LAGRP */
08044                fr->af.subclass = IAX_COMMAND_LAGRP;
08045                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08046             } else {
08047                /* Received LAGRP in response to our LAGRQ */
08048                unsigned int ts;
08049                /* This is a reply we've been given, actually measure the difference */
08050                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08051                iaxs[fr->callno]->lag = ts - fr->ts;
08052                if (option_debug && iaxdebug)
08053                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08054                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08055             }
08056             break;
08057          case IAX_COMMAND_AUTHREQ:
08058             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08059                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>");
08060                break;
08061             }
08062             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08063                struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08064                         .subclass = AST_CONTROL_HANGUP,
08065                };
08066                ast_log(LOG_WARNING, 
08067                   "I don't know how to authenticate %s to %s\n", 
08068                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08069                iax2_queue_frame(fr->callno, &hangup_fr);
08070             }
08071             if (!iaxs[fr->callno]) {
08072                ast_mutex_unlock(&iaxsl[fr->callno]);
08073                return 1;
08074             }
08075             break;
08076          case IAX_COMMAND_AUTHREP:
08077             /* For security, always ack immediately */
08078             if (delayreject)
08079                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08080             /* Ignore once we've started */
08081             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08082                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>");
08083                break;
08084             }
08085             if (authenticate_verify(iaxs[fr->callno], &ies)) {
08086                if (authdebug)
08087                   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);
08088                memset(&ied0, 0, sizeof(ied0));
08089                auth_fail(fr->callno, IAX_COMMAND_REJECT);
08090                break;
08091             }
08092             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08093                /* This might re-enter the IAX code and need the lock */
08094                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08095             } else
08096                exists = 0;
08097             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08098                if (authdebug)
08099                   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);
08100                memset(&ied0, 0, sizeof(ied0));
08101                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08102                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08103                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08104                if (!iaxs[fr->callno]) {
08105                   ast_mutex_unlock(&iaxsl[fr->callno]);
08106                   return 1;
08107                }
08108             } else {
08109                /* Select an appropriate format */
08110                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08111                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08112                      using_prefs = "reqonly";
08113                   } else {
08114                      using_prefs = "disabled";
08115                   }
08116                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08117                   memset(&pref, 0, sizeof(pref));
08118                   strcpy(caller_pref_buf, "disabled");
08119                   strcpy(host_pref_buf, "disabled");
08120                } else {
08121                   using_prefs = "mine";
08122                   if (ies.codec_prefs)
08123                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08124                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08125                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08126                         pref = iaxs[fr->callno]->rprefs;
08127                         using_prefs = "caller";
08128                      } else {
08129                         pref = iaxs[fr->callno]->prefs;
08130                      }
08131                   } else /* if no codec_prefs IE do it the old way */
08132                      pref = iaxs[fr->callno]->prefs;
08133                
08134                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08135                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08136                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08137                }
08138                if (!format) {
08139                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08140                      if (option_debug)
08141                         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);
08142                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08143                   }
08144                   if (!format) {
08145                      if (authdebug) {
08146                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
08147                            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);
08148                         else
08149                            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);
08150                      }
08151                      memset(&ied0, 0, sizeof(ied0));
08152                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08153                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08154                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08155                      if (!iaxs[fr->callno]) {
08156                         ast_mutex_unlock(&iaxsl[fr->callno]);
08157                         return 1;
08158                      }
08159                   } else {
08160                      /* Pick one... */
08161                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08162                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08163                            format = 0;
08164                      } else {
08165                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08166                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08167                            memset(&pref, 0, sizeof(pref));
08168                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08169                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08170                            strcpy(caller_pref_buf,"disabled");
08171                            strcpy(host_pref_buf,"disabled");
08172                         } else {
08173                            using_prefs = "mine";
08174                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08175                               /* Do the opposite of what we tried above. */
08176                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08177                                  pref = iaxs[fr->callno]->prefs;                 
08178                               } else {
08179                                  pref = iaxs[fr->callno]->rprefs;
08180                                  using_prefs = "caller";
08181                               }
08182                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08183                            } else /* if no codec_prefs IE do it the old way */
08184                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
08185                         }
08186                      }
08187                      if (!format) {
08188                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08189                         if (authdebug) {
08190                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08191                               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);
08192                            else
08193                               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);
08194                         }
08195                         memset(&ied0, 0, sizeof(ied0));
08196                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08197                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08198                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08199                         if (!iaxs[fr->callno]) {
08200                            ast_mutex_unlock(&iaxsl[fr->callno]);
08201                            return 1;
08202                         }
08203                      }
08204                   }
08205                }
08206                if (format) {
08207                   /* Authentication received */
08208                   memset(&ied1, 0, sizeof(ied1));
08209                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08210                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08211                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08212                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08213                      if (option_verbose > 2) 
08214                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08215                                  "%srequested format = %s,\n"
08216                                  "%srequested prefs = %s,\n"
08217                                  "%sactual format = %s,\n"
08218                                  "%shost prefs = %s,\n"
08219                                  "%spriority = %s\n", 
08220                                  ast_inet_ntoa(sin.sin_addr), 
08221                                  VERBOSE_PREFIX_4,
08222                                  ast_getformatname(iaxs[fr->callno]->peerformat),
08223                                  VERBOSE_PREFIX_4,
08224                                  caller_pref_buf,
08225                                  VERBOSE_PREFIX_4,
08226                                  ast_getformatname(format),
08227                                  VERBOSE_PREFIX_4,
08228                                  host_pref_buf,
08229                                  VERBOSE_PREFIX_4,
08230                                  using_prefs);
08231 
08232                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08233                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08234                         iax2_destroy(fr->callno);
08235                   } else {
08236                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08237                      /* If this is a TBD call, we're ready but now what...  */
08238                      if (option_verbose > 2)
08239                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08240                   }
08241                }
08242             }
08243             break;
08244          case IAX_COMMAND_DIAL:
08245             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08246                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08247                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08248                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08249                   if (authdebug)
08250                      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);
08251                   memset(&ied0, 0, sizeof(ied0));
08252                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08253                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08254                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08255                   if (!iaxs[fr->callno]) {
08256                      ast_mutex_unlock(&iaxsl[fr->callno]);
08257                      return 1;
08258                   }
08259                } else {
08260                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08261                   if (option_verbose > 2) 
08262                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08263                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08264                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08265                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08266                      iax2_destroy(fr->callno);
08267                }
08268             }
08269             break;
08270          case IAX_COMMAND_INVAL:
08271             iaxs[fr->callno]->error = ENOTCONN;
08272             if (option_debug)
08273                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08274             iax2_destroy(fr->callno);
08275             if (option_debug)
08276                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08277             break;
08278          case IAX_COMMAND_VNAK:
08279             if (option_debug)
08280                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08281             /* Force retransmission */
08282             vnak_retransmit(fr->callno, fr->iseqno);
08283             break;
08284          case IAX_COMMAND_REGREQ:
08285          case IAX_COMMAND_REGREL:
08286             /* For security, always ack immediately */
08287             if (delayreject)
08288                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08289             if (register_verify(fr->callno, &sin, &ies)) {
08290                if (!iaxs[fr->callno]) {
08291                   ast_mutex_unlock(&iaxsl[fr->callno]);
08292                   return 1;
08293                }
08294                /* Send delayed failure */
08295                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08296                break;
08297             }
08298             if (!iaxs[fr->callno]) {
08299                ast_mutex_unlock(&iaxsl[fr->callno]);
08300                return 1;
08301             }
08302             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
08303                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
08304 
08305                if (f.subclass == IAX_COMMAND_REGREL)
08306                   memset(&sin, 0, sizeof(sin));
08307                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08308                   ast_log(LOG_WARNING, "Registry error\n");
08309                if (!iaxs[fr->callno]) {
08310                   ast_mutex_unlock(&iaxsl[fr->callno]);
08311                   return 1;
08312                }
08313                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08314                   ast_mutex_unlock(&iaxsl[fr->callno]);
08315                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08316                   ast_mutex_lock(&iaxsl[fr->callno]);
08317                   if (!iaxs[fr->callno]) {
08318                      ast_mutex_unlock(&iaxsl[fr->callno]);
08319                      return 1;
08320                   }
08321                }
08322                break;
08323             }
08324             registry_authrequest(fr->callno);
08325             if (!iaxs[fr->callno]) {
08326                ast_mutex_unlock(&iaxsl[fr->callno]);
08327                return 1;
08328             }
08329             break;
08330          case IAX_COMMAND_REGACK:
08331             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08332                ast_log(LOG_WARNING, "Registration failure\n");
08333             /* Send ack immediately, before we destroy */
08334             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08335             iax2_destroy(fr->callno);
08336             break;
08337          case IAX_COMMAND_REGREJ:
08338             if (iaxs[fr->callno]->reg) {
08339                if (authdebug) {
08340                   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));
08341                   manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
08342                }
08343                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08344             }
08345             /* Send ack immediately, before we destroy */
08346             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08347             iax2_destroy(fr->callno);
08348             break;
08349          case IAX_COMMAND_REGAUTH:
08350             /* Authentication request */
08351             if (registry_rerequest(&ies, fr->callno, &sin)) {
08352                memset(&ied0, 0, sizeof(ied0));
08353                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08354                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08355                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08356                if (!iaxs[fr->callno]) {
08357                   ast_mutex_unlock(&iaxsl[fr->callno]);
08358                   return 1;
08359                }
08360             }
08361             break;
08362          case IAX_COMMAND_TXREJ:
08363             iaxs[fr->callno]->transferring = 0;
08364             if (option_verbose > 2) 
08365                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08366             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08367             if (iaxs[fr->callno]->bridgecallno) {
08368                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08369                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08370                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08371                }
08372             }
08373             break;
08374          case IAX_COMMAND_TXREADY:
08375             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08376                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08377                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08378                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08379                else
08380                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08381                if (option_verbose > 2) 
08382                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08383                if (iaxs[fr->callno]->bridgecallno) {
08384                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08385                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08386                      /* They're both ready, now release them. */
08387                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08388                         if (option_verbose > 2) 
08389                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08390                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08391 
08392                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08393                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08394 
08395                         memset(&ied0, 0, sizeof(ied0));
08396                         memset(&ied1, 0, sizeof(ied1));
08397                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08398                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08399                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08400                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08401                      } else {
08402                         if (option_verbose > 2) 
08403                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08404                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08405 
08406                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08407                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08408                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08409                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08410 
08411                         /* Stop doing lag & ping requests */
08412                         stop_stuff(fr->callno);
08413                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08414 
08415                         memset(&ied0, 0, sizeof(ied0));
08416                         memset(&ied1, 0, sizeof(ied1));
08417                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08418                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08419                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08420                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08421                      }
08422 
08423                   }
08424                }
08425             }
08426             break;
08427          case IAX_COMMAND_TXREQ:
08428             try_transfer(iaxs[fr->callno], &ies);
08429             break;
08430          case IAX_COMMAND_TXCNT:
08431             if (iaxs[fr->callno]->transferring)
08432                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08433             break;
08434          case IAX_COMMAND_TXREL:
08435             /* Send ack immediately, rather than waiting until we've changed addresses */
08436             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08437             complete_transfer(fr->callno, &ies);
08438             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08439             break;   
08440          case IAX_COMMAND_TXMEDIA:
08441             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08442                                         AST_LIST_LOCK(&iaxq.queue);
08443                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08444                                                 /* Cancel any outstanding frames and start anew */
08445                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08446                                                         cur->retries = -1;
08447                                                 }
08448                                         }
08449                                         AST_LIST_UNLOCK(&iaxq.queue);
08450                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08451                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08452             }
08453             break;   
08454          case IAX_COMMAND_DPREP:
08455             complete_dpreply(iaxs[fr->callno], &ies);
08456             break;
08457          case IAX_COMMAND_UNSUPPORT:
08458             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08459             break;
08460          case IAX_COMMAND_FWDOWNL:
08461             /* Firmware download */
08462             if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08463                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08464                break;
08465             }
08466             memset(&ied0, 0, sizeof(ied0));
08467             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08468             if (res < 0)
08469                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08470             else if (res > 0)
08471                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08472             else
08473                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08474             if (!iaxs[fr->callno]) {
08475                ast_mutex_unlock(&iaxsl[fr->callno]);
08476                return 1;
08477             }
08478             break;
08479          default:
08480             if (option_debug)
08481                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08482             memset(&ied0, 0, sizeof(ied0));
08483             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08484             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08485          }
08486          /* Don't actually pass these frames along */
08487          if ((f.subclass != IAX_COMMAND_ACK) && 
08488            (f.subclass != IAX_COMMAND_TXCNT) && 
08489            (f.subclass != IAX_COMMAND_TXACC) && 
08490            (f.subclass != IAX_COMMAND_INVAL) &&
08491            (f.subclass != IAX_COMMAND_VNAK)) { 
08492             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08493                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08494          }
08495          ast_mutex_unlock(&iaxsl[fr->callno]);
08496          return 1;
08497       }
08498       /* Unless this is an ACK or INVAL frame, ack it */
08499       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08500          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08501    } else if (minivid) {
08502       f.frametype = AST_FRAME_VIDEO;
08503       if (iaxs[fr->callno]->videoformat > 0) 
08504          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08505       else {
08506          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08507          iax2_vnak(fr->callno);
08508          ast_mutex_unlock(&iaxsl[fr->callno]);
08509          return 1;
08510       }
08511       f.datalen = res - sizeof(*vh);
08512       if (f.datalen)
08513          f.data = thread->buf + sizeof(*vh);
08514       else
08515          f.data = NULL;
08516 #ifdef IAXTESTS
08517       if (test_resync) {
08518          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08519       } else
08520 #endif /* IAXTESTS */
08521          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08522    } else {
08523       /* A mini frame */
08524       f.frametype = AST_FRAME_VOICE;
08525       if (iaxs[fr->callno]->voiceformat > 0)
08526          f.subclass = iaxs[fr->callno]->voiceformat;
08527       else {
08528          if (option_debug)
08529             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08530          iax2_vnak(fr->callno);
08531          ast_mutex_unlock(&iaxsl[fr->callno]);
08532          return 1;
08533       }
08534       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08535       if (f.datalen < 0) {
08536          ast_log(LOG_WARNING, "Datalen < 0?\n");
08537          ast_mutex_unlock(&iaxsl[fr->callno]);
08538          return 1;
08539       }
08540       if (f.datalen)
08541          f.data = thread->buf + sizeof(*mh);
08542       else
08543          f.data = NULL;
08544 #ifdef IAXTESTS
08545       if (test_resync) {
08546          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08547       } else
08548 #endif /* IAXTESTS */
08549       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08550       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08551    }
08552    /* Don't pass any packets until we're started */
08553    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08554       ast_mutex_unlock(&iaxsl[fr->callno]);
08555       return 1;
08556    }
08557    /* Common things */
08558    f.src = "IAX2";
08559    f.mallocd = 0;
08560    f.offset = 0;
08561    f.len = 0;
08562    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08563       f.samples = ast_codec_get_samples(&f);
08564       /* We need to byteswap incoming slinear samples from network byte order */
08565       if (f.subclass == AST_FORMAT_SLINEAR)
08566          ast_frame_byteswap_be(&f);
08567    } else
08568       f.samples = 0;
08569    iax_frame_wrap(fr, &f);
08570 
08571    /* If this is our most recent packet, use it as our basis for timestamping */
08572    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08573       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08574       fr->outoforder = 0;
08575    } else {
08576       if (option_debug && iaxdebug && iaxs[fr->callno])
08577          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);
08578       fr->outoforder = -1;
08579    }
08580    fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08581    duped_fr = iaxfrdup2(fr);
08582    if (duped_fr) {
08583       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08584    }
08585    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08586       iaxs[fr->callno]->last = fr->ts;
08587 #if 1
08588       if (option_debug && iaxdebug)
08589          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08590 #endif
08591    }
08592 
08593    /* Always run again */
08594    ast_mutex_unlock(&iaxsl[fr->callno]);
08595    return 1;
08596 }
08597 
08598 /* Function to clean up process thread if it is cancelled */
08599 static void iax2_process_thread_cleanup(void *data)
08600 {
08601    struct iax2_thread *thread = data;
08602    ast_mutex_destroy(&thread->lock);
08603    ast_cond_destroy(&thread->cond);
08604    free(thread);
08605    ast_atomic_dec_and_test(&iaxactivethreadcount);
08606 }
08607 
08608 static void *iax2_process_thread(void *data)
08609 {
08610    struct iax2_thread *thread = data;
08611    struct timeval tv;
08612    struct timespec ts;
08613    int put_into_idle = 0;
08614 
08615    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08616    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08617    for(;;) {
08618       /* Wait for something to signal us to be awake */
08619       ast_mutex_lock(&thread->lock);
08620 
08621       /* Flag that we're ready to accept signals */
08622       thread->ready_for_signal = 1;
08623       
08624       /* Put into idle list if applicable */
08625       if (put_into_idle)
08626          insert_idle_thread(thread);
08627 
08628       if (thread->type == IAX_TYPE_DYNAMIC) {
08629          struct iax2_thread *t = NULL;
08630          /* Wait to be signalled or time out */
08631          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08632          ts.tv_sec = tv.tv_sec;
08633          ts.tv_nsec = tv.tv_usec * 1000;
08634          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08635             /* This thread was never put back into the available dynamic
08636              * thread list, so just go away. */
08637             if (!put_into_idle) {
08638                ast_mutex_unlock(&thread->lock);
08639                break;
08640             }
08641             AST_LIST_LOCK(&dynamic_list);
08642             /* Account for the case where this thread is acquired *right* after a timeout */
08643             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08644                iaxdynamicthreadcount--;
08645             AST_LIST_UNLOCK(&dynamic_list);
08646             if (t) {
08647                /* This dynamic thread timed out waiting for a task and was
08648                 * not acquired immediately after the timeout, 
08649                 * so it's time to go away. */
08650                ast_mutex_unlock(&thread->lock);
08651                break;
08652             }
08653             /* Someone grabbed our thread *right* after we timed out.
08654              * Wait for them to set us up with something to do and signal
08655              * us to continue. */
08656             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08657             ts.tv_sec = tv.tv_sec;
08658             ts.tv_nsec = tv.tv_usec * 1000;
08659             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08660             {
08661                ast_mutex_unlock(&thread->lock);
08662                break;
08663             }
08664          }
08665       } else {
08666          ast_cond_wait(&thread->cond, &thread->lock);
08667       }
08668 
08669       /* Go back into our respective list */
08670       put_into_idle = 1;
08671 
08672       ast_mutex_unlock(&thread->lock);
08673 
08674       if (thread->iostate == IAX_IOSTATE_IDLE)
08675          continue;
08676 
08677       /* Add ourselves to the active list now */
08678       AST_LIST_LOCK(&active_list);
08679       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08680       AST_LIST_UNLOCK(&active_list);
08681 
08682       /* See what we need to do */
08683       switch(thread->iostate) {
08684       case IAX_IOSTATE_READY:
08685          thread->actions++;
08686          thread->iostate = IAX_IOSTATE_PROCESSING;
08687          socket_process(thread);
08688          handle_deferred_full_frames(thread);
08689          break;
08690       case IAX_IOSTATE_SCHEDREADY:
08691          thread->actions++;
08692          thread->iostate = IAX_IOSTATE_PROCESSING;
08693 #ifdef SCHED_MULTITHREADED
08694          thread->schedfunc(thread->scheddata);
08695 #endif      
08696          break;
08697       }
08698       time(&thread->checktime);
08699       thread->iostate = IAX_IOSTATE_IDLE;
08700 #ifdef DEBUG_SCHED_MULTITHREAD
08701       thread->curfunc[0]='\0';
08702 #endif      
08703 
08704       /* Now... remove ourselves from the active list, and return to the idle list */
08705       AST_LIST_LOCK(&active_list);
08706       AST_LIST_REMOVE(&active_list, thread, list);
08707       AST_LIST_UNLOCK(&active_list);
08708 
08709       /* Make sure another frame didn't sneak in there after we thought we were done. */
08710       handle_deferred_full_frames(thread);
08711    }
08712 
08713    /*!\note For some reason, idle threads are exiting without being removed
08714     * from an idle list, which is causing memory corruption.  Forcibly remove
08715     * it from the list, if it's there.
08716     */
08717    AST_LIST_LOCK(&idle_list);
08718    AST_LIST_REMOVE(&idle_list, thread, list);
08719    AST_LIST_UNLOCK(&idle_list);
08720 
08721    AST_LIST_LOCK(&dynamic_list);
08722    AST_LIST_REMOVE(&dynamic_list, thread, list);
08723    AST_LIST_UNLOCK(&dynamic_list);
08724 
08725    /* I am exiting here on my own volition, I need to clean up my own data structures
08726    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08727    */
08728    pthread_cleanup_pop(1);
08729 
08730    return NULL;
08731 }
08732 
08733 static int iax2_do_register(struct iax2_registry *reg)
08734 {
08735    struct iax_ie_data ied;
08736    if (option_debug && iaxdebug)
08737       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08738 
08739    if (reg->dnsmgr && 
08740        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08741       /* Maybe the IP has changed, force DNS refresh */
08742       ast_dnsmgr_refresh(reg->dnsmgr);
08743    }
08744    
08745    /*
08746     * if IP has Changed, free allocated call to create a new one with new IP
08747     * call has the pointer to IP and must be updated to the new one
08748     */
08749    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08750       ast_mutex_lock(&iaxsl[reg->callno]);
08751       iax2_destroy(reg->callno);
08752       ast_mutex_unlock(&iaxsl[reg->callno]);
08753       reg->callno = 0;
08754    }
08755    if (!reg->addr.sin_addr.s_addr) {
08756       if (option_debug && iaxdebug)
08757          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08758       /* Setup the next registration attempt */
08759       AST_SCHED_DEL(sched, reg->expire);
08760       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08761       return -1;
08762    }
08763 
08764    if (!reg->callno) {
08765       if (option_debug)
08766          ast_log(LOG_DEBUG, "Allocate call number\n");
08767       reg->callno = find_callno_locked(0, 0, &reg->addr, NEW_FORCE, defaultsockfd, 0);
08768       if (reg->callno < 1) {
08769          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08770          return -1;
08771       } else if (option_debug)
08772          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08773       iaxs[reg->callno]->reg = reg;
08774       ast_mutex_unlock(&iaxsl[reg->callno]);
08775    }
08776    /* Schedule the next registration attempt */
08777    AST_SCHED_DEL(sched, reg->expire);
08778    /* Setup the next registration a little early */
08779    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08780    /* Send the request */
08781    memset(&ied, 0, sizeof(ied));
08782    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08783    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08784    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08785    reg->regstate = REG_STATE_REGSENT;
08786    return 0;
08787 }
08788 
08789 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08790 {
08791    if (pos != 3)
08792       return NULL;
08793    return iax_prov_complete_template(line, word, pos, state);
08794 }
08795 
08796 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08797 {
08798    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08799       is found for template */
08800    struct iax_ie_data provdata;
08801    struct iax_ie_data ied;
08802    unsigned int sig;
08803    struct sockaddr_in sin;
08804    int callno;
08805    struct create_addr_info cai;
08806 
08807    memset(&cai, 0, sizeof(cai));
08808 
08809    if (option_debug)
08810       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08811 
08812    if (iax_provision_build(&provdata, &sig, template, force)) {
08813       if (option_debug)
08814          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08815       return 0;
08816    }
08817 
08818    if (end) {
08819       memcpy(&sin, end, sizeof(sin));
08820       cai.sockfd = sockfd;
08821    } else if (create_addr(dest, NULL, &sin, &cai))
08822       return -1;
08823 
08824    /* Build the rest of the message */
08825    memset(&ied, 0, sizeof(ied));
08826    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08827 
08828    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08829    if (!callno)
08830       return -1;
08831 
08832    if (iaxs[callno]) {
08833       /* Schedule autodestruct in case they don't ever give us anything back */
08834       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08835       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08836       ast_set_flag(iaxs[callno], IAX_PROVISION);
08837       /* Got a call number now, so go ahead and send the provisioning information */
08838       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08839    }
08840    ast_mutex_unlock(&iaxsl[callno]);
08841 
08842    return 1;
08843 }
08844 
08845 static char *papp = "IAX2Provision";
08846 static char *psyn = "Provision a calling IAXy with a given template";
08847 static char *pdescrip = 
08848 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08849 "the calling entity is in fact an IAXy) with the given template or\n"
08850 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08851 
08852 /*! iax2provision
08853 \ingroup applications
08854 */
08855 static int iax2_prov_app(struct ast_channel *chan, void *data)
08856 {
08857    int res;
08858    char *sdata;
08859    char *opts;
08860    int force =0;
08861    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08862    if (ast_strlen_zero(data))
08863       data = "default";
08864    sdata = ast_strdupa(data);
08865    opts = strchr(sdata, '|');
08866    if (opts)
08867       *opts='\0';
08868 
08869    if (chan->tech != &iax2_tech) {
08870       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08871       return -1;
08872    } 
08873    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08874       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08875       return -1;
08876    }
08877    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08878    if (option_verbose > 2)
08879       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08880       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08881       sdata, res);
08882    return res;
08883 }
08884 
08885 
08886 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08887 {
08888    int force = 0;
08889    int res;
08890    if (argc < 4)
08891       return RESULT_SHOWUSAGE;
08892    if ((argc > 4)) {
08893       if (!strcasecmp(argv[4], "forced"))
08894          force = 1;
08895       else
08896          return RESULT_SHOWUSAGE;
08897    }
08898    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08899    if (res < 0)
08900       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08901    else if (res < 1)
08902       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08903    else
08904       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08905    return RESULT_SUCCESS;
08906 }
08907 
08908 static void __iax2_poke_noanswer(const void *data)
08909 {
08910    struct iax2_peer *peer = (struct iax2_peer *)data;
08911    int callno;
08912 
08913    if (peer->lastms > -1) {
08914       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08915       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08916       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08917    }
08918    if ((callno = peer->callno) > 0) {
08919       ast_mutex_lock(&iaxsl[callno]);
08920       iax2_destroy(callno);
08921       ast_mutex_unlock(&iaxsl[callno]);
08922    }
08923    peer->callno = 0;
08924    peer->lastms = -1;
08925    /* Try again quickly */
08926    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08927    if (peer->pokeexpire == -1)
08928       peer_unref(peer);
08929 }
08930 
08931 static int iax2_poke_noanswer(const void *data)
08932 {
08933    struct iax2_peer *peer = (struct iax2_peer *)data;
08934    peer->pokeexpire = -1;
08935 #ifdef SCHED_MULTITHREADED
08936    if (schedule_action(__iax2_poke_noanswer, data))
08937 #endif      
08938       __iax2_poke_noanswer(data);
08939    peer_unref(peer);
08940    return 0;
08941 }
08942 
08943 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08944 {
08945    struct iax2_peer *peer = obj;
08946 
08947    iax2_poke_peer(peer, 0);
08948 
08949    return 0;
08950 }
08951 
08952 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08953 {
08954    int callno;
08955    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08956       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08957         immediately after clearing things out */
08958       peer->lastms = 0;
08959       peer->historicms = 0;
08960       peer->pokeexpire = -1;
08961       peer->callno = 0;
08962       return 0;
08963    }
08964 
08965    /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */
08966    if ((callno = peer->callno) > 0) {
08967       ast_log(LOG_NOTICE, "Still have a callno...\n");
08968       ast_mutex_lock(&iaxsl[callno]);
08969       iax2_destroy(callno);
08970       ast_mutex_unlock(&iaxsl[callno]);
08971    }
08972    if (heldcall)
08973       ast_mutex_unlock(&iaxsl[heldcall]);
08974    callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08975    if (heldcall)
08976       ast_mutex_lock(&iaxsl[heldcall]);
08977    if (peer->callno < 1) {
08978       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08979       return -1;
08980    }
08981 
08982    /* Speed up retransmission times for this qualify call */
08983    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08984    iaxs[peer->callno]->peerpoke = peer;
08985    
08986    /* Remove any pending pokeexpire task */
08987    if (peer->pokeexpire > -1) {
08988       if (!ast_sched_del(sched, peer->pokeexpire)) {
08989          peer->pokeexpire = -1;
08990          peer_unref(peer);
08991       }
08992    }
08993 
08994    /* Queue up a new task to handle no reply */
08995    /* If the host is already unreachable then use the unreachable interval instead */
08996    if (peer->lastms < 0) {
08997       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08998    } else
08999       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
09000 
09001    if (peer->pokeexpire == -1)
09002       peer_unref(peer);
09003 
09004    /* And send the poke */
09005    ast_mutex_lock(&iaxsl[callno]);
09006    if (iaxs[callno]) {
09007       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
09008    }
09009    ast_mutex_unlock(&iaxsl[callno]);
09010 
09011    return 0;
09012 }
09013 
09014 static void free_context(struct iax2_context *con)
09015 {
09016    struct iax2_context *conl;
09017    while(con) {
09018       conl = con;
09019       con = con->next;
09020       free(conl);
09021    }
09022 }
09023 
09024 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09025 {
09026    int callno;
09027    int res;
09028    int fmt, native;
09029    struct sockaddr_in sin;
09030    struct ast_channel *c;
09031    struct parsed_dial_string pds;
09032    struct create_addr_info cai;
09033    char *tmpstr;
09034 
09035    memset(&pds, 0, sizeof(pds));
09036    tmpstr = ast_strdupa(data);
09037    parse_dial_string(tmpstr, &pds);
09038 
09039    if (ast_strlen_zero(pds.peer)) {
09040       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09041       return NULL;
09042    }
09043           
09044    memset(&cai, 0, sizeof(cai));
09045    cai.capability = iax2_capability;
09046 
09047    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09048    
09049    /* Populate our address from the given */
09050    if (create_addr(pds.peer, NULL, &sin, &cai)) {
09051       *cause = AST_CAUSE_UNREGISTERED;
09052       return NULL;
09053    }
09054 
09055    if (pds.port)
09056       sin.sin_port = htons(atoi(pds.port));
09057 
09058    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09059    if (callno < 1) {
09060       ast_log(LOG_WARNING, "Unable to create call\n");
09061       *cause = AST_CAUSE_CONGESTION;
09062       return NULL;
09063    }
09064 
09065    /* If this is a trunk, update it now */
09066    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
09067    if (ast_test_flag(&cai, IAX_TRUNK)) {
09068       int new_callno;
09069       if ((new_callno = make_trunk(callno, 1)) != -1)
09070          callno = new_callno;
09071    }
09072    iaxs[callno]->maxtime = cai.maxtime;
09073    if (cai.found)
09074       ast_string_field_set(iaxs[callno], host, pds.peer);
09075 
09076    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09077 
09078    ast_mutex_unlock(&iaxsl[callno]);
09079 
09080    if (c) {
09081       /* Choose a format we can live with */
09082       if (c->nativeformats & format) 
09083          c->nativeformats &= format;
09084       else {
09085          native = c->nativeformats;
09086          fmt = format;
09087          res = ast_translator_best_choice(&fmt, &native);
09088          if (res < 0) {
09089             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09090                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09091             ast_hangup(c);
09092             return NULL;
09093          }
09094          c->nativeformats = native;
09095       }
09096       c->readformat = ast_best_codec(c->nativeformats);
09097       c->writeformat = c->readformat;
09098    }
09099 
09100    return c;
09101 }
09102 
09103 static void *sched_thread(void *ignore)
09104 {
09105    int count;
09106    int res;
09107    struct timeval tv;
09108    struct timespec ts;
09109 
09110    for (;;) {
09111       res = ast_sched_wait(sched);
09112       if ((res > 1000) || (res < 0))
09113          res = 1000;
09114       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09115       ts.tv_sec = tv.tv_sec;
09116       ts.tv_nsec = tv.tv_usec * 1000;
09117 
09118       pthread_testcancel();
09119       ast_mutex_lock(&sched_lock);
09120       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09121       ast_mutex_unlock(&sched_lock);
09122       pthread_testcancel();
09123 
09124       count = ast_sched_runq(sched);
09125       if (option_debug && count >= 20)
09126          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09127    }
09128    return NULL;
09129 }
09130 
09131 static void *network_thread(void *ignore)
09132 {
09133    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
09134       from the network, and queue them for delivery to the channels */
09135    int res, count, wakeup;
09136    struct iax_frame *f;
09137 
09138    if (timingfd > -1)
09139       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09140    
09141    for(;;) {
09142       pthread_testcancel();
09143 
09144       /* Go through the queue, sending messages which have not yet been
09145          sent, and scheduling retransmissions if appropriate */
09146       AST_LIST_LOCK(&iaxq.queue);
09147       count = 0;
09148       wakeup = -1;
09149       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09150          if (f->sentyet)
09151             continue;
09152          
09153          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
09154          if (ast_mutex_trylock(&iaxsl[f->callno])) {
09155             wakeup = 1;
09156             continue;
09157          }
09158 
09159          f->sentyet++;
09160 
09161          if (iaxs[f->callno]) {
09162             send_packet(f);
09163             count++;
09164          } 
09165 
09166          ast_mutex_unlock(&iaxsl[f->callno]);
09167 
09168          if (f->retries < 0) {
09169             /* This is not supposed to be retransmitted */
09170             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09171             iaxq.count--;
09172             /* Free the iax frame */
09173             iax_frame_free(f);
09174          } else {
09175             /* We need reliable delivery.  Schedule a retransmission */
09176             f->retries++;
09177             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09178          }
09179       }
09180       AST_LIST_TRAVERSE_SAFE_END
09181       AST_LIST_UNLOCK(&iaxq.queue);
09182 
09183       pthread_testcancel();
09184 
09185       if (option_debug && count >= 20)
09186          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09187 
09188       /* Now do the IO, and run scheduled tasks */
09189       res = ast_io_wait(io, wakeup);
09190       if (res >= 0) {
09191          if (option_debug && res >= 20)
09192             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09193       }
09194    }
09195    return NULL;
09196 }
09197 
09198 static int start_network_thread(void)
09199 {
09200    pthread_attr_t attr;
09201    int threadcount = 0;
09202    int x;
09203    for (x = 0; x < iaxthreadcount; x++) {
09204       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09205       if (thread) {
09206          thread->type = IAX_TYPE_POOL;
09207          thread->threadnum = ++threadcount;
09208          ast_mutex_init(&thread->lock);
09209          ast_cond_init(&thread->cond, NULL);
09210          pthread_attr_init(&attr);
09211          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
09212          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09213             ast_log(LOG_WARNING, "Failed to create new thread!\n");
09214             free(thread);
09215             thread = NULL;
09216          }
09217          AST_LIST_LOCK(&idle_list);
09218          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09219          AST_LIST_UNLOCK(&idle_list);
09220       }
09221    }
09222    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09223    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09224    if (option_verbose > 1)
09225       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09226    return 0;
09227 }
09228 
09229 static struct iax2_context *build_context(char *context)
09230 {
09231    struct iax2_context *con;
09232 
09233    if ((con = ast_calloc(1, sizeof(*con))))
09234       ast_copy_string(con->context, context, sizeof(con->context));
09235    
09236    return con;
09237 }
09238 
09239 static int get_auth_methods(char *value)
09240 {
09241    int methods = 0;
09242    if (strstr(value, "rsa"))
09243       methods |= IAX_AUTH_RSA;
09244    if (strstr(value, "md5"))
09245       methods |= IAX_AUTH_MD5;
09246    if (strstr(value, "plaintext"))
09247       methods |= IAX_AUTH_PLAINTEXT;
09248    return methods;
09249 }
09250 
09251 
09252 /*! \brief Check if address can be used as packet source.
09253  \return 0  address available, 1  address unavailable, -1  error
09254 */
09255 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09256 {
09257    int sd;
09258    int res;
09259    
09260    sd = socket(AF_INET, SOCK_DGRAM, 0);
09261    if (sd < 0) {
09262       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09263       return -1;
09264    }
09265 
09266    res = bind(sd, sa, salen);
09267    if (res < 0) {
09268       if (option_debug)
09269          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09270       close(sd);
09271       return 1;
09272    }
09273 
09274    close(sd);
09275    return 0;
09276 }
09277 
09278 /*! \brief Parse the "sourceaddress" value,
09279   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09280   not found. */
09281 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09282 {
09283    struct sockaddr_in sin;
09284    int nonlocal = 1;
09285    int port = IAX_DEFAULT_PORTNO;
09286    int sockfd = defaultsockfd;
09287    char *tmp;
09288    char *addr;
09289    char *portstr;
09290 
09291    if (!(tmp = ast_strdupa(srcaddr)))
09292       return -1;
09293 
09294    addr = strsep(&tmp, ":");
09295    portstr = tmp;
09296 
09297    if (portstr) {
09298       port = atoi(portstr);
09299       if (port < 1)
09300          port = IAX_DEFAULT_PORTNO;
09301    }
09302    
09303    if (!ast_get_ip(&sin, addr)) {
09304       struct ast_netsock *sock;
09305       int res;
09306 
09307       sin.sin_port = 0;
09308       sin.sin_family = AF_INET;
09309       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09310       if (res == 0) {
09311          /* ip address valid. */
09312          sin.sin_port = htons(port);
09313          if (!(sock = ast_netsock_find(netsock, &sin)))
09314             sock = ast_netsock_find(outsock, &sin);
09315          if (sock) {
09316             sockfd = ast_netsock_sockfd(sock);
09317             nonlocal = 0;
09318          } else {
09319             unsigned int orig_saddr = sin.sin_addr.s_addr;
09320             /* INADDR_ANY matches anyway! */
09321             sin.sin_addr.s_addr = INADDR_ANY;
09322             if (ast_netsock_find(netsock, &sin)) {
09323                sin.sin_addr.s_addr = orig_saddr;
09324                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09325                if (sock) {
09326                   sockfd = ast_netsock_sockfd(sock);
09327                   ast_netsock_unref(sock);
09328                   nonlocal = 0;
09329                } else {
09330                   nonlocal = 2;
09331                }
09332             }
09333          }
09334       }
09335    }
09336       
09337    peer->sockfd = sockfd;
09338 
09339    if (nonlocal == 1) {
09340       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09341          srcaddr, peer->name);
09342       return -1;
09343         } else if (nonlocal == 2) {
09344       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09345          srcaddr, peer->name);
09346          return -1;
09347    } else {
09348       if (option_debug)
09349          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09350       return 0;
09351    }
09352 }
09353 
09354 static void peer_destructor(void *obj)
09355 {
09356    struct iax2_peer *peer = obj;
09357 
09358    ast_free_ha(peer->ha);
09359 
09360    if (peer->callno > 0) {
09361       ast_mutex_lock(&iaxsl[peer->callno]);
09362       iax2_destroy(peer->callno);
09363       ast_mutex_unlock(&iaxsl[peer->callno]);
09364    }
09365 
09366    register_peer_exten(peer, 0);
09367 
09368    if (peer->dnsmgr)
09369       ast_dnsmgr_release(peer->dnsmgr);
09370 
09371    ast_string_field_free_memory(peer);
09372 }
09373 
09374 /*! \brief Create peer structure based on configuration */
09375 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09376 {
09377    struct iax2_peer *peer = NULL;
09378    struct ast_ha *oldha = NULL;
09379    int maskfound=0;
09380    int found=0;
09381    int firstpass=1;
09382    struct iax2_peer tmp_peer = {
09383       .name = name,
09384    };
09385 
09386    if (!temponly) {
09387       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09388       if (peer && !ast_test_flag(peer, IAX_DELME))
09389          firstpass = 0;
09390    }
09391 
09392    if (peer) {
09393       found++;
09394       if (firstpass) {
09395          oldha = peer->ha;
09396          peer->ha = NULL;
09397       }
09398       unlink_peer(peer);
09399    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09400       peer->expire = -1;
09401       peer->pokeexpire = -1;
09402       peer->sockfd = defaultsockfd;
09403       if (ast_string_field_init(peer, 32))
09404          peer = peer_unref(peer);
09405    }
09406 
09407    if (peer) {
09408       if (firstpass) {
09409          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09410          peer->encmethods = iax2_encryption;
09411          peer->adsi = adsi;
09412          ast_string_field_set(peer,secret,"");
09413          if (!found) {
09414             ast_string_field_set(peer, name, name);
09415             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09416             peer->expiry = min_reg_expire;
09417          }
09418          peer->prefs = prefs;
09419          peer->capability = iax2_capability;
09420          peer->smoothing = 0;
09421          peer->pokefreqok = DEFAULT_FREQ_OK;
09422          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09423          ast_string_field_set(peer,context,"");
09424          ast_string_field_set(peer,peercontext,"");
09425          ast_clear_flag(peer, IAX_HASCALLERID);
09426          ast_string_field_set(peer, cid_name, "");
09427          ast_string_field_set(peer, cid_num, "");
09428       }
09429 
09430       if (!v) {
09431          v = alt;
09432          alt = NULL;
09433       }
09434       while(v) {
09435          if (!strcasecmp(v->name, "secret")) {
09436             ast_string_field_set(peer, secret, v->value);
09437          } else if (!strcasecmp(v->name, "mailbox")) {
09438             ast_string_field_set(peer, mailbox, v->value);
09439          } else if (!strcasecmp(v->name, "mohinterpret")) {
09440             ast_string_field_set(peer, mohinterpret, v->value);
09441          } else if (!strcasecmp(v->name, "mohsuggest")) {
09442             ast_string_field_set(peer, mohsuggest, v->value);
09443          } else if (!strcasecmp(v->name, "dbsecret")) {
09444             ast_string_field_set(peer, dbsecret, v->value);
09445          } else if (!strcasecmp(v->name, "trunk")) {
09446             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09447             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09448                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09449                ast_clear_flag(peer, IAX_TRUNK);
09450             }
09451          } else if (!strcasecmp(v->name, "auth")) {
09452             peer->authmethods = get_auth_methods(v->value);
09453          } else if (!strcasecmp(v->name, "encryption")) {
09454             peer->encmethods = get_encrypt_methods(v->value);
09455          } else if (!strcasecmp(v->name, "notransfer")) {
09456             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09457             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09458             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09459          } else if (!strcasecmp(v->name, "transfer")) {
09460             if (!strcasecmp(v->value, "mediaonly")) {
09461                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09462             } else if (ast_true(v->value)) {
09463                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09464             } else 
09465                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09466          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09467             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09468          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09469             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09470          } else if (!strcasecmp(v->name, "host")) {
09471             if (!strcasecmp(v->value, "dynamic")) {
09472                /* They'll register with us */
09473                ast_set_flag(peer, IAX_DYNAMIC); 
09474                if (!found) {
09475                   /* Initialize stuff iff we're not found, otherwise
09476                      we keep going with what we had */
09477                   memset(&peer->addr.sin_addr, 0, 4);
09478                   if (peer->addr.sin_port) {
09479                      /* If we've already got a port, make it the default rather than absolute */
09480                      peer->defaddr.sin_port = peer->addr.sin_port;
09481                      peer->addr.sin_port = 0;
09482                   }
09483                }
09484             } else {
09485                /* Non-dynamic.  Make sure we become that way if we're not */
09486                AST_SCHED_DEL(sched, peer->expire);
09487                ast_clear_flag(peer, IAX_DYNAMIC);
09488                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09489                   return peer_unref(peer);
09490                if (!peer->addr.sin_port)
09491                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09492             }
09493             if (!maskfound)
09494                inet_aton("255.255.255.255", &peer->mask);
09495          } else if (!strcasecmp(v->name, "defaultip")) {
09496             if (ast_get_ip(&peer->defaddr, v->value))
09497                return peer_unref(peer);
09498          } else if (!strcasecmp(v->name, "sourceaddress")) {
09499             peer_set_srcaddr(peer, v->value);
09500          } else if (!strcasecmp(v->name, "permit") ||
09501                   !strcasecmp(v->name, "deny")) {
09502             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09503          } else if (!strcasecmp(v->name, "mask")) {
09504             maskfound++;
09505             inet_aton(v->value, &peer->mask);
09506          } else if (!strcasecmp(v->name, "context")) {
09507             ast_string_field_set(peer, context, v->value);
09508          } else if (!strcasecmp(v->name, "regexten")) {
09509             ast_string_field_set(peer, regexten, v->value);
09510          } else if (!strcasecmp(v->name, "peercontext")) {
09511             ast_string_field_set(peer, peercontext, v->value);
09512          } else if (!strcasecmp(v->name, "port")) {
09513             if (ast_test_flag(peer, IAX_DYNAMIC))
09514                peer->defaddr.sin_port = htons(atoi(v->value));
09515             else
09516                peer->addr.sin_port = htons(atoi(v->value));
09517          } else if (!strcasecmp(v->name, "username")) {
09518             ast_string_field_set(peer, username, v->value);
09519          } else if (!strcasecmp(v->name, "allow")) {
09520             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09521          } else if (!strcasecmp(v->name, "disallow")) {
09522             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09523          } else if (!strcasecmp(v->name, "callerid")) {
09524             if (!ast_strlen_zero(v->value)) {
09525                char name2[80];
09526                char num2[80];
09527                ast_callerid_split(v->value, name2, 80, num2, 80);
09528                ast_string_field_set(peer, cid_name, name2);
09529                ast_string_field_set(peer, cid_num, num2);
09530                ast_set_flag(peer, IAX_HASCALLERID);
09531             } else {
09532                ast_clear_flag(peer, IAX_HASCALLERID);
09533                ast_string_field_set(peer, cid_name, "");
09534                ast_string_field_set(peer, cid_num, "");
09535             }
09536          } else if (!strcasecmp(v->name, "fullname")) {
09537             if (!ast_strlen_zero(v->value)) {
09538                ast_string_field_set(peer, cid_name, v->value);
09539                ast_set_flag(peer, IAX_HASCALLERID);
09540             } else {
09541                ast_string_field_set(peer, cid_name, "");
09542                if (ast_strlen_zero(peer->cid_num))
09543                   ast_clear_flag(peer, IAX_HASCALLERID);
09544             }
09545          } else if (!strcasecmp(v->name, "cid_number")) {
09546             if (!ast_strlen_zero(v->value)) {
09547                ast_string_field_set(peer, cid_num, v->value);
09548                ast_set_flag(peer, IAX_HASCALLERID);
09549             } else {
09550                ast_string_field_set(peer, cid_num, "");
09551                if (ast_strlen_zero(peer->cid_name))
09552                   ast_clear_flag(peer, IAX_HASCALLERID);
09553             }
09554          } else if (!strcasecmp(v->name, "sendani")) {
09555             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09556          } else if (!strcasecmp(v->name, "inkeys")) {
09557             ast_string_field_set(peer, inkeys, v->value);
09558          } else if (!strcasecmp(v->name, "outkey")) {
09559             ast_string_field_set(peer, outkey, v->value);
09560          } else if (!strcasecmp(v->name, "qualify")) {
09561             if (!strcasecmp(v->value, "no")) {
09562                peer->maxms = 0;
09563             } else if (!strcasecmp(v->value, "yes")) {
09564                peer->maxms = DEFAULT_MAXMS;
09565             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09566                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);
09567                peer->maxms = 0;
09568             }
09569          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09570             peer->smoothing = ast_true(v->value);
09571          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09572             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09573                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);
09574             }
09575          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09576             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09577                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);
09578             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09579          } else if (!strcasecmp(v->name, "timezone")) {
09580             ast_string_field_set(peer, zonetag, v->value);
09581          } else if (!strcasecmp(v->name, "adsi")) {
09582             peer->adsi = ast_true(v->value);
09583          }/* else if (strcasecmp(v->name,"type")) */
09584          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09585          v = v->next;
09586          if (!v) {
09587             v = alt;
09588             alt = NULL;
09589          }
09590       }
09591       if (!peer->authmethods)
09592          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09593       ast_clear_flag(peer, IAX_DELME); 
09594       /* Make sure these are IPv4 addresses */
09595       peer->addr.sin_family = AF_INET;
09596    }
09597    if (oldha)
09598       ast_free_ha(oldha);
09599    return peer;
09600 }
09601 
09602 static void user_destructor(void *obj)
09603 {
09604    struct iax2_user *user = obj;
09605 
09606    ast_free_ha(user->ha);
09607    free_context(user->contexts);
09608    if(user->vars) {
09609       ast_variables_destroy(user->vars);
09610       user->vars = NULL;
09611    }
09612    ast_string_field_free_memory(user);
09613 }
09614 
09615 /*! \brief Create in-memory user structure from configuration */
09616 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09617 {
09618    struct iax2_user *user = NULL;
09619    struct iax2_context *con, *conl = NULL;
09620    struct ast_ha *oldha = NULL;
09621    struct iax2_context *oldcon = NULL;
09622    int format;
09623    int firstpass=1;
09624    int oldcurauthreq = 0;
09625    char *varname = NULL, *varval = NULL;
09626    struct ast_variable *tmpvar = NULL;
09627    struct iax2_user tmp_user = {
09628       .name = name,
09629    };
09630 
09631    if (!temponly) {
09632       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09633       if (user && !ast_test_flag(user, IAX_DELME))
09634          firstpass = 0;
09635    }
09636 
09637    if (user) {
09638       if (firstpass) {
09639          oldcurauthreq = user->curauthreq;
09640          oldha = user->ha;
09641          oldcon = user->contexts;
09642          user->ha = NULL;
09643          user->contexts = NULL;
09644       }
09645       /* Already in the list, remove it and it will be added back (or FREE'd) */
09646       ao2_unlink(users, user);
09647    } else {
09648       user = ao2_alloc(sizeof(*user), user_destructor);
09649    }
09650    
09651    if (user) {
09652       if (firstpass) {
09653          ast_string_field_free_memory(user);
09654          memset(user, 0, sizeof(struct iax2_user));
09655          if (ast_string_field_init(user, 32)) {
09656             user = user_unref(user);
09657             goto cleanup;
09658          }
09659          user->maxauthreq = maxauthreq;
09660          user->curauthreq = oldcurauthreq;
09661          user->prefs = prefs;
09662          user->capability = iax2_capability;
09663          user->encmethods = iax2_encryption;
09664          user->adsi = adsi;
09665          ast_string_field_set(user, name, name);
09666          ast_string_field_set(user, language, language);
09667          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09668          ast_clear_flag(user, IAX_HASCALLERID);
09669          ast_string_field_set(user, cid_name, "");
09670          ast_string_field_set(user, cid_num, "");
09671       }
09672       if (!v) {
09673          v = alt;
09674          alt = NULL;
09675       }
09676       while(v) {
09677          if (!strcasecmp(v->name, "context")) {
09678             con = build_context(v->value);
09679             if (con) {
09680                if (conl)
09681                   conl->next = con;
09682                else
09683                   user->contexts = con;
09684                conl = con;
09685             }
09686          } else if (!strcasecmp(v->name, "permit") ||
09687                   !strcasecmp(v->name, "deny")) {
09688             user->ha = ast_append_ha(v->name, v->value, user->ha);
09689          } else if (!strcasecmp(v->name, "setvar")) {
09690             varname = ast_strdupa(v->value);
09691             if (varname && (varval = strchr(varname,'='))) {
09692                *varval = '\0';
09693                varval++;
09694                if((tmpvar = ast_variable_new(varname, varval))) {
09695                   tmpvar->next = user->vars; 
09696                   user->vars = tmpvar;
09697                }
09698             }
09699          } else if (!strcasecmp(v->name, "allow")) {
09700             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09701          } else if (!strcasecmp(v->name, "disallow")) {
09702             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09703          } else if (!strcasecmp(v->name, "trunk")) {
09704             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09705             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09706                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09707                ast_clear_flag(user, IAX_TRUNK);
09708             }
09709          } else if (!strcasecmp(v->name, "auth")) {
09710             user->authmethods = get_auth_methods(v->value);
09711          } else if (!strcasecmp(v->name, "encryption")) {
09712             user->encmethods = get_encrypt_methods(v->value);
09713          } else if (!strcasecmp(v->name, "notransfer")) {
09714             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09715             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09716             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09717          } else if (!strcasecmp(v->name, "transfer")) {
09718             if (!strcasecmp(v->value, "mediaonly")) {
09719                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09720             } else if (ast_true(v->value)) {
09721                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09722             } else 
09723                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09724          } else if (!strcasecmp(v->name, "codecpriority")) {
09725             if(!strcasecmp(v->value, "caller"))
09726                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09727             else if(!strcasecmp(v->value, "disabled"))
09728                ast_set_flag(user, IAX_CODEC_NOPREFS);
09729             else if(!strcasecmp(v->value, "reqonly")) {
09730                ast_set_flag(user, IAX_CODEC_NOCAP);
09731                ast_set_flag(user, IAX_CODEC_NOPREFS);
09732             }
09733          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09734             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09735          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09736             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09737          } else if (!strcasecmp(v->name, "dbsecret")) {
09738             ast_string_field_set(user, dbsecret, v->value);
09739          } else if (!strcasecmp(v->name, "secret")) {
09740             if (!ast_strlen_zero(user->secret)) {
09741                char *old = ast_strdupa(user->secret);
09742 
09743                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09744             } else
09745                ast_string_field_set(user, secret, v->value);
09746          } else if (!strcasecmp(v->name, "callerid")) {
09747             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09748                char name2[80];
09749                char num2[80];
09750                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09751                ast_string_field_set(user, cid_name, name2);
09752                ast_string_field_set(user, cid_num, num2);
09753                ast_set_flag(user, IAX_HASCALLERID);
09754             } else {
09755                ast_clear_flag(user, IAX_HASCALLERID);
09756                ast_string_field_set(user, cid_name, "");
09757                ast_string_field_set(user, cid_num, "");
09758             }
09759          } else if (!strcasecmp(v->name, "fullname")) {
09760             if (!ast_strlen_zero(v->value)) {
09761                ast_string_field_set(user, cid_name, v->value);
09762                ast_set_flag(user, IAX_HASCALLERID);
09763             } else {
09764                ast_string_field_set(user, cid_name, "");
09765                if (ast_strlen_zero(user->cid_num))
09766                   ast_clear_flag(user, IAX_HASCALLERID);
09767             }
09768          } else if (!strcasecmp(v->name, "cid_number")) {
09769             if (!ast_strlen_zero(v->value)) {
09770                ast_string_field_set(user, cid_num, v->value);
09771                ast_set_flag(user, IAX_HASCALLERID);
09772             } else {
09773                ast_string_field_set(user, cid_num, "");
09774                if (ast_strlen_zero(user->cid_name))
09775                   ast_clear_flag(user, IAX_HASCALLERID);
09776             }
09777          } else if (!strcasecmp(v->name, "accountcode")) {
09778             ast_string_field_set(user, accountcode, v->value);
09779          } else if (!strcasecmp(v->name, "mohinterpret")) {
09780             ast_string_field_set(user, mohinterpret, v->value);
09781          } else if (!strcasecmp(v->name, "mohsuggest")) {
09782             ast_string_field_set(user, mohsuggest, v->value);
09783          } else if (!strcasecmp(v->name, "language")) {
09784             ast_string_field_set(user, language, v->value);
09785          } else if (!strcasecmp(v->name, "amaflags")) {
09786             format = ast_cdr_amaflags2int(v->value);
09787             if (format < 0) {
09788                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09789             } else {
09790                user->amaflags = format;
09791             }
09792          } else if (!strcasecmp(v->name, "inkeys")) {
09793             ast_string_field_set(user, inkeys, v->value);
09794          } else if (!strcasecmp(v->name, "maxauthreq")) {
09795             user->maxauthreq = atoi(v->value);
09796             if (user->maxauthreq < 0)
09797                user->maxauthreq = 0;
09798          } else if (!strcasecmp(v->name, "adsi")) {
09799             user->adsi = ast_true(v->value);
09800          }/* else if (strcasecmp(v->name,"type")) */
09801          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09802          v = v->next;
09803          if (!v) {
09804             v = alt;
09805             alt = NULL;
09806          }
09807       }
09808       if (!user->authmethods) {
09809          if (!ast_strlen_zero(user->secret)) {
09810             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09811             if (!ast_strlen_zero(user->inkeys))
09812                user->authmethods |= IAX_AUTH_RSA;
09813          } else if (!ast_strlen_zero(user->inkeys)) {
09814             user->authmethods = IAX_AUTH_RSA;
09815          } else {
09816             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09817          }
09818       }
09819       ast_clear_flag(user, IAX_DELME);
09820    }
09821 cleanup:
09822    if (oldha)
09823       ast_free_ha(oldha);
09824    if (oldcon)
09825       free_context(oldcon);
09826    return user;
09827 }
09828 
09829 static int peer_delme_cb(void *obj, void *arg, int flags)
09830 {
09831    struct iax2_peer *peer = obj;
09832 
09833    ast_set_flag(peer, IAX_DELME);
09834 
09835    return 0;
09836 }
09837 
09838 static int user_delme_cb(void *obj, void *arg, int flags)
09839 {
09840    struct iax2_user *user = obj;
09841 
09842    ast_set_flag(user, IAX_DELME);
09843 
09844    return 0;
09845 }
09846 
09847 static void delete_users(void)
09848 {
09849    struct iax2_registry *reg;
09850 
09851    ao2_callback(users, 0, user_delme_cb, NULL);
09852 
09853    AST_LIST_LOCK(&registrations);
09854    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09855       ast_sched_del(sched, reg->expire);
09856       if (reg->callno) {
09857          ast_mutex_lock(&iaxsl[reg->callno]);
09858          if (iaxs[reg->callno]) {
09859             iaxs[reg->callno]->reg = NULL;
09860             iax2_destroy(reg->callno);
09861          }
09862          ast_mutex_unlock(&iaxsl[reg->callno]);
09863       }
09864       if (reg->dnsmgr)
09865          ast_dnsmgr_release(reg->dnsmgr);
09866       free(reg);
09867    }
09868    AST_LIST_UNLOCK(&registrations);
09869 
09870    ao2_callback(peers, 0, peer_delme_cb, NULL);
09871 }
09872 
09873 static void prune_users(void)
09874 {
09875    struct iax2_user *user;
09876    struct ao2_iterator i;
09877 
09878    i = ao2_iterator_init(users, 0);
09879    while ((user = ao2_iterator_next(&i))) {
09880       if (ast_test_flag(user, IAX_DELME))
09881          ao2_unlink(users, user);
09882       user_unref(user);
09883    }
09884 }
09885 
09886 /* Prune peers who still are supposed to be deleted */
09887 static void prune_peers(void)
09888 {
09889    struct iax2_peer *peer;
09890    struct ao2_iterator i;
09891 
09892    i = ao2_iterator_init(peers, 0);
09893    while ((peer = ao2_iterator_next(&i))) {
09894       if (ast_test_flag(peer, IAX_DELME))
09895          unlink_peer(peer);
09896       peer_unref(peer);
09897    }
09898 }
09899 
09900 static void set_timing(void)
09901 {
09902 #ifdef HAVE_ZAPTEL
09903    int bs = trunkfreq * 8;
09904    if (timingfd > -1) {
09905       if (
09906 #ifdef ZT_TIMERACK
09907          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09908 #endif         
09909          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09910          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09911    }
09912 #endif
09913 }
09914 
09915 static void set_config_destroy(void)
09916 {
09917    strcpy(accountcode, "");
09918    strcpy(language, "");
09919    strcpy(mohinterpret, "default");
09920    strcpy(mohsuggest, "");
09921    amaflags = 0;
09922    delayreject = 0;
09923    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09924    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09925    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09926    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09927    delete_users();
09928 }
09929 
09930 /*! \brief Load configuration */
09931 static int set_config(char *config_file, int reload)
09932 {
09933    struct ast_config *cfg, *ucfg;
09934    int capability=iax2_capability;
09935    struct ast_variable *v;
09936    char *cat;
09937    const char *utype;
09938    const char *tosval;
09939    int format;
09940    int portno = IAX_DEFAULT_PORTNO;
09941    int  x;
09942    struct iax2_user *user;
09943    struct iax2_peer *peer;
09944    struct ast_netsock *ns;
09945 #if 0
09946    static unsigned short int last_port=0;
09947 #endif
09948 
09949    cfg = ast_config_load(config_file);
09950    
09951    if (!cfg) {
09952       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09953       return -1;
09954    }
09955 
09956    if (reload) {
09957       set_config_destroy();
09958    }
09959 
09960    /* Reset global codec prefs */   
09961    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09962    
09963    /* Reset Global Flags */
09964    memset(&globalflags, 0, sizeof(globalflags));
09965    ast_set_flag(&globalflags, IAX_RTUPDATE);
09966 
09967 #ifdef SO_NO_CHECK
09968    nochecksums = 0;
09969 #endif
09970 
09971    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09972    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09973 
09974    maxauthreq = 3;
09975 
09976    v = ast_variable_browse(cfg, "general");
09977 
09978    /* Seed initial tos value */
09979    tosval = ast_variable_retrieve(cfg, "general", "tos");
09980    if (tosval) {
09981       if (ast_str2tos(tosval, &tos))
09982          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09983    }
09984    while(v) {
09985       if (!strcasecmp(v->name, "bindport")){ 
09986          if (reload)
09987             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09988          else
09989             portno = atoi(v->value);
09990       } else if (!strcasecmp(v->name, "pingtime")) 
09991          ping_time = atoi(v->value);
09992       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09993          if (reload) {
09994             if (atoi(v->value) != iaxthreadcount)
09995                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09996          } else {
09997             iaxthreadcount = atoi(v->value);
09998             if (iaxthreadcount < 1) {
09999                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
10000                iaxthreadcount = 1;
10001             } else if (iaxthreadcount > 256) {
10002                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
10003                iaxthreadcount = 256;
10004             }
10005          }
10006       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
10007          if (reload) {
10008             AST_LIST_LOCK(&dynamic_list);
10009             iaxmaxthreadcount = atoi(v->value);
10010             AST_LIST_UNLOCK(&dynamic_list);
10011          } else {
10012             iaxmaxthreadcount = atoi(v->value);
10013             if (iaxmaxthreadcount < 0) {
10014                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
10015                iaxmaxthreadcount = 0;
10016             } else if (iaxmaxthreadcount > 256) {
10017                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
10018                iaxmaxthreadcount = 256;
10019             }
10020          }
10021       } else if (!strcasecmp(v->name, "nochecksums")) {
10022 #ifdef SO_NO_CHECK
10023          if (ast_true(v->value))
10024             nochecksums = 1;
10025          else
10026             nochecksums = 0;
10027 #else
10028          if (ast_true(v->value))
10029             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10030 #endif
10031       }
10032       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
10033          maxjitterbuffer = atoi(v->value);
10034       else if (!strcasecmp(v->name, "resyncthreshold")) 
10035          resyncthreshold = atoi(v->value);
10036       else if (!strcasecmp(v->name, "maxjitterinterps")) 
10037          maxjitterinterps = atoi(v->value);
10038       else if (!strcasecmp(v->name, "lagrqtime")) 
10039          lagrq_time = atoi(v->value);
10040       else if (!strcasecmp(v->name, "maxregexpire")) 
10041          max_reg_expire = atoi(v->value);
10042       else if (!strcasecmp(v->name, "minregexpire")) 
10043          min_reg_expire = atoi(v->value);
10044       else if (!strcasecmp(v->name, "bindaddr")) {
10045          if (reload) {
10046             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10047          } else {
10048             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10049                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10050             } else {
10051                if (option_verbose > 1) {
10052                   if (strchr(v->value, ':'))
10053                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10054                   else
10055                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10056                }
10057                if (defaultsockfd < 0) 
10058                   defaultsockfd = ast_netsock_sockfd(ns);
10059                ast_netsock_unref(ns);
10060             }
10061          }
10062       } else if (!strcasecmp(v->name, "authdebug"))
10063          authdebug = ast_true(v->value);
10064       else if (!strcasecmp(v->name, "encryption"))
10065          iax2_encryption = get_encrypt_methods(v->value);
10066       else if (!strcasecmp(v->name, "notransfer")) {
10067          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10068          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
10069          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
10070       } else if (!strcasecmp(v->name, "transfer")) {
10071          if (!strcasecmp(v->value, "mediaonly")) {
10072             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
10073          } else if (ast_true(v->value)) {
10074             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10075          } else 
10076             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10077       } else if (!strcasecmp(v->name, "codecpriority")) {
10078          if(!strcasecmp(v->value, "caller"))
10079             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10080          else if(!strcasecmp(v->value, "disabled"))
10081             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10082          else if(!strcasecmp(v->value, "reqonly")) {
10083             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10084             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10085          }
10086       } else if (!strcasecmp(v->name, "jitterbuffer"))
10087          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
10088       else if (!strcasecmp(v->name, "forcejitterbuffer"))
10089          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
10090       else if (!strcasecmp(v->name, "delayreject"))
10091          delayreject = ast_true(v->value);
10092       else if (!strcasecmp(v->name, "allowfwdownload"))
10093          ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10094       else if (!strcasecmp(v->name, "rtcachefriends"))
10095          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
10096       else if (!strcasecmp(v->name, "rtignoreregexpire"))
10097          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
10098       else if (!strcasecmp(v->name, "rtupdate"))
10099          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10100       else if (!strcasecmp(v->name, "trunktimestamps"))
10101          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10102       else if (!strcasecmp(v->name, "rtautoclear")) {
10103          int i = atoi(v->value);
10104          if(i > 0)
10105             global_rtautoclear = i;
10106          else
10107             i = 0;
10108          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
10109       } else if (!strcasecmp(v->name, "trunkfreq")) {
10110          trunkfreq = atoi(v->value);
10111          if (trunkfreq < 10)
10112             trunkfreq = 10;
10113       } else if (!strcasecmp(v->name, "autokill")) {
10114          if (sscanf(v->value, "%d", &x) == 1) {
10115             if (x >= 0)
10116                autokill = x;
10117             else
10118                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10119          } else if (ast_true(v->value)) {
10120             autokill = DEFAULT_MAXMS;
10121          } else {
10122             autokill = 0;
10123          }
10124       } else if (!strcasecmp(v->name, "bandwidth")) {
10125          if (!strcasecmp(v->value, "low")) {
10126             capability = IAX_CAPABILITY_LOWBANDWIDTH;
10127          } else if (!strcasecmp(v->value, "medium")) {
10128             capability = IAX_CAPABILITY_MEDBANDWIDTH;
10129          } else if (!strcasecmp(v->value, "high")) {
10130             capability = IAX_CAPABILITY_FULLBANDWIDTH;
10131          } else
10132             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10133       } else if (!strcasecmp(v->name, "allow")) {
10134          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10135       } else if (!strcasecmp(v->name, "disallow")) {
10136          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10137       } else if (!strcasecmp(v->name, "register")) {
10138          iax2_register(v->value, v->lineno);
10139       } else if (!strcasecmp(v->name, "iaxcompat")) {
10140          iaxcompat = ast_true(v->value);
10141       } else if (!strcasecmp(v->name, "regcontext")) {
10142          ast_copy_string(regcontext, v->value, sizeof(regcontext));
10143          /* Create context if it doesn't exist already */
10144          if (!ast_context_find(regcontext))
10145             ast_context_create(NULL, regcontext, "IAX2");
10146       } else if (!strcasecmp(v->name, "tos")) {
10147          if (ast_str2tos(v->value, &tos))
10148             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10149       } else if (!strcasecmp(v->name, "accountcode")) {
10150          ast_copy_string(accountcode, v->value, sizeof(accountcode));
10151       } else if (!strcasecmp(v->name, "mohinterpret")) {
10152          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10153       } else if (!strcasecmp(v->name, "mohsuggest")) {
10154          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10155       } else if (!strcasecmp(v->name, "amaflags")) {
10156          format = ast_cdr_amaflags2int(v->value);
10157          if (format < 0) {
10158             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10159          } else {
10160             amaflags = format;
10161          }
10162       } else if (!strcasecmp(v->name, "language")) {
10163          ast_copy_string(language, v->value, sizeof(language));
10164       } else if (!strcasecmp(v->name, "maxauthreq")) {
10165          maxauthreq = atoi(v->value);
10166          if (maxauthreq < 0)
10167             maxauthreq = 0;
10168       } else if (!strcasecmp(v->name, "adsi")) {
10169          adsi = ast_true(v->value);
10170       } /*else if (strcasecmp(v->name,"type")) */
10171       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
10172       v = v->next;
10173    }
10174    
10175    if (defaultsockfd < 0) {
10176       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10177          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10178       } else {
10179          if (option_verbose > 1)
10180             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10181          defaultsockfd = ast_netsock_sockfd(ns);
10182          ast_netsock_unref(ns);
10183       }
10184    }
10185    if (reload) {
10186       ast_netsock_release(outsock);
10187       outsock = ast_netsock_list_alloc();
10188       if (!outsock) {
10189          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10190          return -1;
10191       }
10192       ast_netsock_init(outsock);
10193    }
10194 
10195    if (min_reg_expire > max_reg_expire) {
10196       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10197          min_reg_expire, max_reg_expire, max_reg_expire);
10198       min_reg_expire = max_reg_expire;
10199    }
10200    iax2_capability = capability;
10201    
10202    ucfg = ast_config_load("users.conf");
10203    if (ucfg) {
10204       struct ast_variable *gen;
10205       int genhasiax;
10206       int genregisteriax;
10207       const char *hasiax, *registeriax;
10208       
10209       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10210       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10211       gen = ast_variable_browse(ucfg, "general");
10212       cat = ast_category_browse(ucfg, NULL);
10213       while (cat) {
10214          if (strcasecmp(cat, "general")) {
10215             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10216             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10217             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10218                /* Start with general parameters, then specific parameters, user and peer */
10219                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10220                if (user) {
10221                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10222                   user = user_unref(user);
10223                }
10224                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10225                if (peer) {
10226                   if (ast_test_flag(peer, IAX_DYNAMIC))
10227                      reg_source_db(peer);
10228                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10229                   peer = peer_unref(peer);
10230                }
10231             }
10232             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10233                char tmp[256];
10234                const char *host = ast_variable_retrieve(ucfg, cat, "host");
10235                const char *username = ast_variable_retrieve(ucfg, cat, "username");
10236                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10237                if (!host)
10238                   host = ast_variable_retrieve(ucfg, "general", "host");
10239                if (!username)
10240                   username = ast_variable_retrieve(ucfg, "general", "username");
10241                if (!secret)
10242                   secret = ast_variable_retrieve(ucfg, "general", "secret");
10243                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10244                   if (!ast_strlen_zero(secret))
10245                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10246                   else
10247                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10248                   iax2_register(tmp, 0);
10249                }
10250             }
10251          }
10252          cat = ast_category_browse(ucfg, cat);
10253       }
10254       ast_config_destroy(ucfg);
10255    }
10256    
10257    cat = ast_category_browse(cfg, NULL);
10258    while(cat) {
10259       if (strcasecmp(cat, "general")) {
10260          utype = ast_variable_retrieve(cfg, cat, "type");
10261          if (utype) {
10262             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10263                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10264                if (user) {
10265                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10266                   user = user_unref(user);
10267                }
10268             }
10269             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10270                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10271                if (peer) {
10272                   if (ast_test_flag(peer, IAX_DYNAMIC))
10273                      reg_source_db(peer);
10274                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10275                   peer = peer_unref(peer);
10276                }
10277             } else if (strcasecmp(utype, "user")) {
10278                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10279             }
10280          } else
10281             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10282       }
10283       cat = ast_category_browse(cfg, cat);
10284    }
10285    ast_config_destroy(cfg);
10286    set_timing();
10287    return 1;
10288 }
10289 
10290 static void poke_all_peers(void)
10291 {
10292    struct ao2_iterator i;
10293    struct iax2_peer *peer;
10294 
10295    i = ao2_iterator_init(peers, 0);
10296    while ((peer = ao2_iterator_next(&i))) {
10297       iax2_poke_peer(peer, 0);
10298       peer_unref(peer);
10299    }
10300 }
10301 static int reload_config(void)
10302 {
10303    char *config = "iax.conf";
10304    struct iax2_registry *reg;
10305 
10306    if (set_config(config, 1) > 0) {
10307       prune_peers();
10308       prune_users();
10309       AST_LIST_LOCK(&registrations);
10310       AST_LIST_TRAVERSE(&registrations, reg, entry)
10311          iax2_do_register(reg);
10312       AST_LIST_UNLOCK(&registrations);
10313       /* Qualify hosts, too */
10314       poke_all_peers();
10315    }
10316    reload_firmware(0);
10317    iax_provision_reload();
10318 
10319    return 0;
10320 }
10321 
10322 static int iax2_reload(int fd, int argc, char *argv[])
10323 {
10324    return reload_config();
10325 }
10326 
10327 static int reload(void)
10328 {
10329    return reload_config();
10330 }
10331 
10332 static int cache_get_callno_locked(const char *data)
10333 {
10334    struct sockaddr_in sin;
10335    int x;
10336    int callno;
10337    struct iax_ie_data ied;
10338    struct create_addr_info cai;
10339    struct parsed_dial_string pds;
10340    char *tmpstr;
10341 
10342    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10343       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10344          look up entries for a single context */
10345       if (!ast_mutex_trylock(&iaxsl[x])) {
10346          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10347             return x;
10348          ast_mutex_unlock(&iaxsl[x]);
10349       }
10350    }
10351 
10352    /* No match found, we need to create a new one */
10353 
10354    memset(&cai, 0, sizeof(cai));
10355    memset(&ied, 0, sizeof(ied));
10356    memset(&pds, 0, sizeof(pds));
10357 
10358    tmpstr = ast_strdupa(data);
10359    parse_dial_string(tmpstr, &pds);
10360 
10361    if (ast_strlen_zero(pds.peer)) {
10362       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10363       return -1;
10364    }
10365 
10366    /* Populate our address from the given */
10367    if (create_addr(pds.peer, NULL, &sin, &cai))
10368       return -1;
10369 
10370    if (option_debug)
10371       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10372          pds.peer, pds.username, pds.password, pds.context);
10373 
10374    callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10375    if (callno < 1) {
10376       ast_log(LOG_WARNING, "Unable to create call\n");
10377       return -1;
10378    }
10379 
10380    ast_string_field_set(iaxs[callno], dproot, data);
10381    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10382 
10383    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10384    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10385    /* the string format is slightly different from a standard dial string,
10386       because the context appears in the 'exten' position
10387    */
10388    if (pds.exten)
10389       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10390    if (pds.username)
10391       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10392    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10393    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10394    /* Keep password handy */
10395    if (pds.password)
10396       ast_string_field_set(iaxs[callno], secret, pds.password);
10397    if (pds.key)
10398       ast_string_field_set(iaxs[callno], outkey, pds.key);
10399    /* Start the call going */
10400    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10401 
10402    return callno;
10403 }
10404 
10405 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10406 {
10407    struct iax2_dpcache *dp, *prev = NULL, *next;
10408    struct timeval tv;
10409    int x;
10410    int com[2];
10411    int timeout;
10412    int old=0;
10413    int outfd;
10414    int abort;
10415    int callno;
10416    struct ast_channel *c;
10417    struct ast_frame *f;
10418    gettimeofday(&tv, NULL);
10419    dp = dpcache;
10420    while(dp) {
10421       next = dp->next;
10422       /* Expire old caches */
10423       if (ast_tvcmp(tv, dp->expiry) > 0) {
10424             /* It's expired, let it disappear */
10425             if (prev)
10426                prev->next = dp->next;
10427             else
10428                dpcache = dp->next;
10429             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10430                /* Free memory and go again */
10431                free(dp);
10432             } else {
10433                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);
10434             }
10435             dp = next;
10436             continue;
10437       }
10438       /* We found an entry that matches us! */
10439       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10440          break;
10441       prev = dp;
10442       dp = next;
10443    }
10444    if (!dp) {
10445       /* No matching entry.  Create a new one. */
10446       /* First, can we make a callno? */
10447       callno = cache_get_callno_locked(data);
10448       if (callno < 0) {
10449          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10450          return NULL;
10451       }
10452       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10453          ast_mutex_unlock(&iaxsl[callno]);
10454          return NULL;
10455       }
10456       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10457       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10458       gettimeofday(&dp->expiry, NULL);
10459       dp->orig = dp->expiry;
10460       /* Expires in 30 mins by default */
10461       dp->expiry.tv_sec += iaxdefaultdpcache;
10462       dp->next = dpcache;
10463       dp->flags = CACHE_FLAG_PENDING;
10464       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10465          dp->waiters[x] = -1;
10466       dpcache = dp;
10467       dp->peer = iaxs[callno]->dpentries;
10468       iaxs[callno]->dpentries = dp;
10469       /* Send the request if we're already up */
10470       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10471          iax2_dprequest(dp, callno);
10472       ast_mutex_unlock(&iaxsl[callno]);
10473    }
10474    /* By here we must have a dp */
10475    if (dp->flags & CACHE_FLAG_PENDING) {
10476       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10477          for a reply to come back so long as it's pending */
10478       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10479          /* Find an empty slot */
10480          if (dp->waiters[x] < 0)
10481             break;
10482       }
10483       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10484          ast_log(LOG_WARNING, "No more waiter positions available\n");
10485          return NULL;
10486       }
10487       if (pipe(com)) {
10488          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10489          return NULL;
10490       }
10491       dp->waiters[x] = com[1];
10492       /* Okay, now we wait */
10493       timeout = iaxdefaulttimeout * 1000;
10494       /* Temporarily unlock */
10495       ast_mutex_unlock(&dpcache_lock);
10496       /* Defer any dtmf */
10497       if (chan)
10498          old = ast_channel_defer_dtmf(chan);
10499       abort = 0;
10500       while(timeout) {
10501          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10502          if (outfd > -1) {
10503             break;
10504          }
10505          if (c) {
10506             f = ast_read(c);
10507             if (f)
10508                ast_frfree(f);
10509             else {
10510                /* Got hung up on, abort! */
10511                break;
10512                abort = 1;
10513             }
10514          }
10515       }
10516       if (!timeout) {
10517          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10518       }
10519       ast_mutex_lock(&dpcache_lock);
10520       dp->waiters[x] = -1;
10521       close(com[1]);
10522       close(com[0]);
10523       if (abort) {
10524          /* Don't interpret anything, just abort.  Not sure what th epoint
10525            of undeferring dtmf on a hung up channel is but hey whatever */
10526          if (!old && chan)
10527             ast_channel_undefer_dtmf(chan);
10528          return NULL;
10529       }
10530       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10531          /* Now to do non-independent analysis the results of our wait */
10532          if (dp->flags & CACHE_FLAG_PENDING) {
10533             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10534                pending.  Don't let it take as long to timeout. */
10535             dp->flags &= ~CACHE_FLAG_PENDING;
10536             dp->flags |= CACHE_FLAG_TIMEOUT;
10537             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10538                systems without leaving it unavailable once the server comes back online */
10539             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10540             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10541                if (dp->waiters[x] > -1)
10542                   write(dp->waiters[x], "asdf", 4);
10543          }
10544       }
10545       /* Our caller will obtain the rest */
10546       if (!old && chan)
10547          ast_channel_undefer_dtmf(chan);
10548    }
10549    return dp;  
10550 }
10551 
10552 /*! \brief Part of the IAX2 switch interface */
10553 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10554 {
10555    struct iax2_dpcache *dp;
10556    int res = 0;
10557 #if 0
10558    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10559 #endif
10560    if ((priority != 1) && (priority != 2))
10561       return 0;
10562    ast_mutex_lock(&dpcache_lock);
10563    dp = find_cache(chan, data, context, exten, priority);
10564    if (dp) {
10565       if (dp->flags & CACHE_FLAG_EXISTS)
10566          res= 1;
10567    }
10568    ast_mutex_unlock(&dpcache_lock);
10569    if (!dp) {
10570       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10571    }
10572    return res;
10573 }
10574 
10575 /*! \brief part of the IAX2 dial plan switch interface */
10576 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10577 {
10578    int res = 0;
10579    struct iax2_dpcache *dp;
10580 #if 0
10581    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10582 #endif
10583    if ((priority != 1) && (priority != 2))
10584       return 0;
10585    ast_mutex_lock(&dpcache_lock);
10586    dp = find_cache(chan, data, context, exten, priority);
10587    if (dp) {
10588       if (dp->flags & CACHE_FLAG_CANEXIST)
10589          res= 1;
10590    }
10591    ast_mutex_unlock(&dpcache_lock);
10592    if (!dp) {
10593       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10594    }
10595    return res;
10596 }
10597 
10598 /*! \brief Part of the IAX2 Switch interface */
10599 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10600 {
10601    int res = 0;
10602    struct iax2_dpcache *dp;
10603 #if 0
10604    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10605 #endif
10606    if ((priority != 1) && (priority != 2))
10607       return 0;
10608    ast_mutex_lock(&dpcache_lock);
10609    dp = find_cache(chan, data, context, exten, priority);
10610    if (dp) {
10611       if (dp->flags & CACHE_FLAG_MATCHMORE)
10612          res= 1;
10613    }
10614    ast_mutex_unlock(&dpcache_lock);
10615    if (!dp) {
10616       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10617    }
10618    return res;
10619 }
10620 
10621 /*! \brief Execute IAX2 dialplan switch */
10622 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10623 {
10624    char odata[256];
10625    char req[256];
10626    char *ncontext;
10627    struct iax2_dpcache *dp;
10628    struct ast_app *dial;
10629 #if 0
10630    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);
10631 #endif
10632    if (priority == 2) {
10633       /* Indicate status, can be overridden in dialplan */
10634       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10635       if (dialstatus) {
10636          dial = pbx_findapp(dialstatus);
10637          if (dial) 
10638             pbx_exec(chan, dial, "");
10639       }
10640       return -1;
10641    } else if (priority != 1)
10642       return -1;
10643    ast_mutex_lock(&dpcache_lock);
10644    dp = find_cache(chan, data, context, exten, priority);
10645    if (dp) {
10646       if (dp->flags & CACHE_FLAG_EXISTS) {
10647          ast_copy_string(odata, data, sizeof(odata));
10648          ncontext = strchr(odata, '/');
10649          if (ncontext) {
10650             *ncontext = '\0';
10651             ncontext++;
10652             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10653          } else {
10654             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10655          }
10656          if (option_verbose > 2)
10657             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10658       } else {
10659          ast_mutex_unlock(&dpcache_lock);
10660          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10661          return -1;
10662       }
10663    }
10664    ast_mutex_unlock(&dpcache_lock);
10665    dial = pbx_findapp("Dial");
10666    if (dial) {
10667       return pbx_exec(chan, dial, req);
10668    } else {
10669       ast_log(LOG_WARNING, "No dial application registered\n");
10670    }
10671    return -1;
10672 }
10673 
10674 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10675 {
10676    struct iax2_peer *peer;
10677    char *peername, *colname;
10678 
10679    peername = ast_strdupa(data);
10680 
10681    /* if our channel, return the IP address of the endpoint of current channel */
10682    if (!strcmp(peername,"CURRENTCHANNEL")) {
10683            unsigned short callno;
10684       if (chan->tech != &iax2_tech)
10685          return -1;
10686       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10687       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10688       return 0;
10689    }
10690 
10691    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10692       *colname++ = '\0';
10693    else if ((colname = strchr(peername, '|')))
10694       *colname++ = '\0';
10695    else
10696       colname = "ip";
10697 
10698    if (!(peer = find_peer(peername, 1)))
10699       return -1;
10700 
10701    if (!strcasecmp(colname, "ip")) {
10702       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10703    } else  if (!strcasecmp(colname, "status")) {
10704       peer_status(peer, buf, len); 
10705    } else  if (!strcasecmp(colname, "mailbox")) {
10706       ast_copy_string(buf, peer->mailbox, len);
10707    } else  if (!strcasecmp(colname, "context")) {
10708       ast_copy_string(buf, peer->context, len);
10709    } else  if (!strcasecmp(colname, "expire")) {
10710       snprintf(buf, len, "%d", peer->expire);
10711    } else  if (!strcasecmp(colname, "dynamic")) {
10712       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10713    } else  if (!strcasecmp(colname, "callerid_name")) {
10714       ast_copy_string(buf, peer->cid_name, len);
10715    } else  if (!strcasecmp(colname, "callerid_num")) {
10716       ast_copy_string(buf, peer->cid_num, len);
10717    } else  if (!strcasecmp(colname, "codecs")) {
10718       ast_getformatname_multiple(buf, len -1, peer->capability);
10719    } else  if (!strncasecmp(colname, "codec[", 6)) {
10720       char *codecnum, *ptr;
10721       int index = 0, codec = 0;
10722       
10723       codecnum = strchr(colname, '[');
10724       *codecnum = '\0';
10725       codecnum++;
10726       if ((ptr = strchr(codecnum, ']'))) {
10727          *ptr = '\0';
10728       }
10729       index = atoi(codecnum);
10730       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10731          ast_copy_string(buf, ast_getformatname(codec), len);
10732       }
10733    }
10734 
10735    peer_unref(peer);
10736 
10737    return 0;
10738 }
10739 
10740 struct ast_custom_function iaxpeer_function = {
10741    .name = "IAXPEER",
10742    .synopsis = "Gets IAX peer information",
10743    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10744    .read = function_iaxpeer,
10745    .desc = "If peername specified, valid items are:\n"
10746    "- ip (default)          The IP address.\n"
10747    "- status                The peer's status (if qualify=yes)\n"
10748    "- mailbox               The configured mailbox.\n"
10749    "- context               The configured context.\n"
10750    "- expire                The epoch time of the next expire.\n"
10751    "- dynamic               Is it dynamic? (yes/no).\n"
10752    "- callerid_name         The configured Caller ID name.\n"
10753    "- callerid_num          The configured Caller ID number.\n"
10754    "- codecs                The configured codecs.\n"
10755    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10756    "\n"
10757    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10758    "\n"
10759 };
10760 
10761 
10762 /*! \brief Part of the device state notification system ---*/
10763 static int iax2_devicestate(void *data) 
10764 {
10765    struct parsed_dial_string pds;
10766    char *tmp = ast_strdupa(data);
10767    struct iax2_peer *p;
10768    int res = AST_DEVICE_INVALID;
10769 
10770    memset(&pds, 0, sizeof(pds));
10771    parse_dial_string(tmp, &pds);
10772 
10773    if (ast_strlen_zero(pds.peer)) {
10774       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10775       return res;
10776    }
10777    
10778    if (option_debug > 2)
10779       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10780 
10781    /* SLD: FIXME: second call to find_peer during registration */
10782    if (!(p = find_peer(pds.peer, 1)))
10783       return res;
10784 
10785    res = AST_DEVICE_UNAVAILABLE;
10786    if (option_debug > 2) 
10787       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10788          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10789    
10790    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10791        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10792       /* Peer is registered, or have default IP address
10793          and a valid registration */
10794       if (p->historicms == 0 || p->historicms <= p->maxms)
10795          /* let the core figure out whether it is in use or not */
10796          res = AST_DEVICE_UNKNOWN;  
10797    }
10798 
10799    peer_unref(p);
10800 
10801    return res;
10802 }
10803 
10804 static struct ast_switch iax2_switch = 
10805 {
10806    name:          "IAX2",
10807    description:      "IAX Remote Dialplan Switch",
10808    exists:        iax2_exists,
10809    canmatch:      iax2_canmatch,
10810    exec:       iax2_exec,
10811    matchmore:     iax2_matchmore,
10812 };
10813 
10814 static char show_stats_usage[] =
10815 "Usage: iax2 show stats\n"
10816 "       Display statistics on IAX channel driver.\n";
10817 
10818 static char show_cache_usage[] =
10819 "Usage: iax2 show cache\n"
10820 "       Display currently cached IAX Dialplan results.\n";
10821 
10822 static char show_peer_usage[] =
10823 "Usage: iax2 show peer <name>\n"
10824 "       Display details on specific IAX peer\n";
10825 
10826 static char prune_realtime_usage[] =
10827 "Usage: iax2 prune realtime [<peername>|all]\n"
10828 "       Prunes object(s) from the cache\n";
10829 
10830 static char iax2_reload_usage[] =
10831 "Usage: iax2 reload\n"
10832 "       Reloads IAX configuration from iax.conf\n";
10833 
10834 static char show_prov_usage[] =
10835 "Usage: iax2 provision <host> <template> [forced]\n"
10836 "       Provisions the given peer or IP address using a template\n"
10837 "       matching either 'template' or '*' if the template is not\n"
10838 "       found.  If 'forced' is specified, even empty provisioning\n"
10839 "       fields will be provisioned as empty fields.\n";
10840 
10841 static char show_users_usage[] = 
10842 "Usage: iax2 show users [like <pattern>]\n"
10843 "       Lists all known IAX2 users.\n"
10844 "       Optional regular expression pattern is used to filter the user list.\n";
10845 
10846 static char show_channels_usage[] = 
10847 "Usage: iax2 show channels\n"
10848 "       Lists all currently active IAX channels.\n";
10849 
10850 static char show_netstats_usage[] = 
10851 "Usage: iax2 show netstats\n"
10852 "       Lists network status for all currently active IAX channels.\n";
10853 
10854 static char show_threads_usage[] = 
10855 "Usage: iax2 show threads\n"
10856 "       Lists status of IAX helper threads\n";
10857 
10858 static char show_peers_usage[] = 
10859 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10860 "       Lists all known IAX2 peers.\n"
10861 "       Optional 'registered' argument lists only peers with known addresses.\n"
10862 "       Optional regular expression pattern is used to filter the peer list.\n";
10863 
10864 static char show_firmware_usage[] = 
10865 "Usage: iax2 show firmware\n"
10866 "       Lists all known IAX firmware images.\n";
10867 
10868 static char show_reg_usage[] =
10869 "Usage: iax2 show registry\n"
10870 "       Lists all registration requests and status.\n";
10871 
10872 static char debug_usage[] = 
10873 "Usage: iax2 set debug\n"
10874 "       Enables dumping of IAX packets for debugging purposes\n";
10875 
10876 static char no_debug_usage[] = 
10877 "Usage: iax2 set debug off\n"
10878 "       Disables dumping of IAX packets for debugging purposes\n";
10879 
10880 static char debug_trunk_usage[] =
10881 "Usage: iax2 set debug trunk\n"
10882 "       Requests current status of IAX trunking\n";
10883 
10884 static char no_debug_trunk_usage[] =
10885 "Usage: iax2 set debug trunk off\n"
10886 "       Requests current status of IAX trunking\n";
10887 
10888 static char debug_jb_usage[] =
10889 "Usage: iax2 set debug jb\n"
10890 "       Enables jitterbuffer debugging information\n";
10891 
10892 static char no_debug_jb_usage[] =
10893 "Usage: iax2 set debug jb off\n"
10894 "       Disables jitterbuffer debugging information\n";
10895 
10896 static char iax2_test_losspct_usage[] =
10897 "Usage: iax2 test losspct <percentage>\n"
10898 "       For testing, throws away <percentage> percent of incoming packets\n";
10899 
10900 #ifdef IAXTESTS
10901 static char iax2_test_late_usage[] =
10902 "Usage: iax2 test late <ms>\n"
10903 "       For testing, count the next frame as <ms> ms late\n";
10904 
10905 static char iax2_test_resync_usage[] =
10906 "Usage: iax2 test resync <ms>\n"
10907 "       For testing, adjust all future frames by <ms> ms\n";
10908 
10909 static char iax2_test_jitter_usage[] =
10910 "Usage: iax2 test jitter <ms> <pct>\n"
10911 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10912 #endif /* IAXTESTS */
10913 
10914 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10915    { "iax2", "trunk", "debug", NULL },
10916    iax2_do_trunk_debug, NULL,
10917    NULL };
10918 
10919 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10920    { "iax2", "jb", "debug", NULL },
10921    iax2_do_jb_debug, NULL,
10922    NULL };
10923 
10924 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10925    { "iax2", "no", "debug", NULL },
10926    iax2_no_debug, NULL,
10927    NULL };
10928 
10929 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10930    { "iax2", "no", "trunk", "debug", NULL },
10931    iax2_no_trunk_debug, NULL,
10932    NULL };
10933 
10934 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10935    { "iax2", "no", "jb", "debug", NULL },
10936    iax2_no_jb_debug, NULL,
10937    NULL };
10938 
10939 static struct ast_cli_entry cli_iax2[] = {
10940    { { "iax2", "show", "cache", NULL },
10941    iax2_show_cache, "Display IAX cached dialplan",
10942    show_cache_usage, NULL, },
10943 
10944    { { "iax2", "show", "channels", NULL },
10945    iax2_show_channels, "List active IAX channels",
10946    show_channels_usage, NULL, },
10947 
10948    { { "iax2", "show", "firmware", NULL },
10949    iax2_show_firmware, "List available IAX firmwares",
10950    show_firmware_usage, NULL, },
10951 
10952    { { "iax2", "show", "netstats", NULL },
10953    iax2_show_netstats, "List active IAX channel netstats",
10954    show_netstats_usage, NULL, },
10955 
10956    { { "iax2", "show", "peers", NULL },
10957    iax2_show_peers, "List defined IAX peers",
10958    show_peers_usage, NULL, },
10959 
10960    { { "iax2", "show", "registry", NULL },
10961    iax2_show_registry, "Display IAX registration status",
10962    show_reg_usage, NULL, },
10963 
10964    { { "iax2", "show", "stats", NULL },
10965    iax2_show_stats, "Display IAX statistics",
10966    show_stats_usage, NULL, },
10967 
10968    { { "iax2", "show", "threads", NULL },
10969    iax2_show_threads, "Display IAX helper thread info",
10970    show_threads_usage, NULL, },
10971 
10972    { { "iax2", "show", "users", NULL },
10973    iax2_show_users, "List defined IAX users",
10974    show_users_usage, NULL, },
10975 
10976    { { "iax2", "prune", "realtime", NULL },
10977    iax2_prune_realtime, "Prune a cached realtime lookup",
10978    prune_realtime_usage, complete_iax2_show_peer },
10979 
10980    { { "iax2", "reload", NULL },
10981    iax2_reload, "Reload IAX configuration",
10982    iax2_reload_usage },
10983 
10984    { { "iax2", "show", "peer", NULL },
10985    iax2_show_peer, "Show details on specific IAX peer",
10986    show_peer_usage, complete_iax2_show_peer },
10987 
10988    { { "iax2", "set", "debug", NULL },
10989    iax2_do_debug, "Enable IAX debugging",
10990    debug_usage },
10991 
10992    { { "iax2", "set", "debug", "trunk", NULL },
10993    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10994    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10995 
10996    { { "iax2", "set", "debug", "jb", NULL },
10997    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10998    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10999 
11000    { { "iax2", "set", "debug", "off", NULL },
11001    iax2_no_debug, "Disable IAX debugging",
11002    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
11003 
11004    { { "iax2", "set", "debug", "trunk", "off", NULL },
11005    iax2_no_trunk_debug, "Disable IAX trunk debugging",
11006    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
11007 
11008    { { "iax2", "set", "debug", "jb", "off", NULL },
11009    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
11010    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
11011 
11012    { { "iax2", "test", "losspct", NULL },
11013    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
11014    iax2_test_losspct_usage },
11015 
11016    { { "iax2", "provision", NULL },
11017    iax2_prov_cmd, "Provision an IAX device",
11018    show_prov_usage, iax2_prov_complete_template_3rd },
11019 
11020 #ifdef IAXTESTS
11021    { { "iax2", "test", "late", NULL },
11022    iax2_test_late, "Test the receipt of a late frame",
11023    iax2_test_late_usage },
11024 
11025    { { "iax2", "test", "resync", NULL },
11026    iax2_test_resync, "Test a resync in received timestamps",
11027    iax2_test_resync_usage },
11028 
11029    { { "iax2", "test", "jitter", NULL },
11030    iax2_test_jitter, "Simulates jitter for testing",
11031    iax2_test_jitter_usage },
11032 #endif /* IAXTESTS */
11033 };
11034 
11035 static int __unload_module(void)
11036 {
11037    struct iax2_thread *thread = NULL;
11038    int x;
11039 
11040    /* Make sure threads do not hold shared resources when they are canceled */
11041    
11042    /* Grab the sched lock resource to keep it away from threads about to die */
11043    /* Cancel the network thread, close the net socket */
11044    if (netthreadid != AST_PTHREADT_NULL) {
11045       AST_LIST_LOCK(&iaxq.queue);
11046       ast_mutex_lock(&sched_lock);
11047       pthread_cancel(netthreadid);
11048       ast_cond_signal(&sched_cond);
11049       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
11050       AST_LIST_UNLOCK(&iaxq.queue);
11051       pthread_join(netthreadid, NULL);
11052    }
11053    if (schedthreadid != AST_PTHREADT_NULL) {
11054       ast_mutex_lock(&sched_lock);  
11055       pthread_cancel(schedthreadid);
11056       ast_cond_signal(&sched_cond);
11057       ast_mutex_unlock(&sched_lock);   
11058       pthread_join(schedthreadid, NULL);
11059    }
11060    
11061    /* Call for all threads to halt */
11062    AST_LIST_LOCK(&idle_list);
11063    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11064       AST_LIST_REMOVE_CURRENT(&idle_list, list);
11065       pthread_cancel(thread->threadid);
11066    }
11067    AST_LIST_TRAVERSE_SAFE_END
11068    AST_LIST_UNLOCK(&idle_list);
11069 
11070    AST_LIST_LOCK(&active_list);
11071    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11072       AST_LIST_REMOVE_CURRENT(&active_list, list);
11073       pthread_cancel(thread->threadid);
11074    }
11075    AST_LIST_TRAVERSE_SAFE_END
11076    AST_LIST_UNLOCK(&active_list);
11077 
11078    AST_LIST_LOCK(&dynamic_list);
11079         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11080       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11081       pthread_cancel(thread->threadid);
11082         }
11083    AST_LIST_TRAVERSE_SAFE_END
11084         AST_LIST_UNLOCK(&dynamic_list);
11085 
11086    AST_LIST_HEAD_DESTROY(&iaxq.queue);
11087 
11088    /* Wait for threads to exit */
11089    while(0 < iaxactivethreadcount)
11090       usleep(10000);
11091    
11092    ast_netsock_release(netsock);
11093    ast_netsock_release(outsock);
11094    for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11095       if (iaxs[x]) {
11096          iax2_destroy(x);
11097       }
11098    }
11099    ast_manager_unregister( "IAXpeers" );
11100    ast_manager_unregister( "IAXnetstats" );
11101    ast_unregister_application(papp);
11102    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11103    ast_unregister_switch(&iax2_switch);
11104    ast_channel_unregister(&iax2_tech);
11105    delete_users();
11106    iax_provision_unload();
11107    sched_context_destroy(sched);
11108    reload_firmware(1);
11109 
11110    ast_mutex_destroy(&waresl.lock);
11111 
11112    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11113       ast_mutex_destroy(&iaxsl[x]);
11114    }
11115 
11116    ao2_ref(peers, -1);
11117    ao2_ref(users, -1);
11118    ao2_ref(iax_peercallno_pvts, -1);
11119 
11120    return 0;
11121 }
11122 
11123 static int unload_module(void)
11124 {
11125    ast_custom_function_unregister(&iaxpeer_function);
11126    return __unload_module();
11127 }
11128 
11129 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11130 {
11131    struct iax2_peer *peer = obj;
11132 
11133    if (peer->sockfd < 0)
11134       peer->sockfd = defaultsockfd;
11135 
11136    return 0;
11137 }
11138 
11139 static int pvt_hash_cb(const void *obj, const int flags)
11140 {
11141    const struct chan_iax2_pvt *pvt = obj;
11142 
11143    return pvt->peercallno;
11144 }
11145 
11146 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11147 {
11148    struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11149 
11150    /* The frames_received field is used to hold whether we're matching
11151     * against a full frame or not ... */
11152 
11153    return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 
11154       pvt2->frames_received) ? CMP_MATCH : 0;
11155 }
11156 
11157 /*! \brief Load IAX2 module, load configuraiton ---*/
11158 static int load_module(void)
11159 {
11160    char *config = "iax.conf";
11161    int res = 0;
11162    int x;
11163    struct iax2_registry *reg = NULL;
11164 
11165    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11166    if (!peers)
11167       return AST_MODULE_LOAD_FAILURE;
11168    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11169    if (!users) {
11170       ao2_ref(peers, -1);
11171       return AST_MODULE_LOAD_FAILURE;
11172    }
11173    iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11174    if (!iax_peercallno_pvts) {
11175       ao2_ref(peers, -1);
11176       ao2_ref(users, -1);
11177       return AST_MODULE_LOAD_FAILURE;
11178    }
11179 
11180    ast_custom_function_register(&iaxpeer_function);
11181 
11182    iax_set_output(iax_debug_output);
11183    iax_set_error(iax_error_output);
11184    jb_setoutput(jb_error_output, jb_warning_output, NULL);
11185    
11186 #ifdef HAVE_ZAPTEL
11187 #ifdef ZT_TIMERACK
11188    timingfd = open("/dev/zap/timer", O_RDWR);
11189    if (timingfd < 0)
11190 #endif
11191       timingfd = open("/dev/zap/pseudo", O_RDWR);
11192    if (timingfd < 0) 
11193       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11194 #endif      
11195 
11196    memset(iaxs, 0, sizeof(iaxs));
11197 
11198    for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11199       ast_mutex_init(&iaxsl[x]);
11200    }
11201    
11202    ast_cond_init(&sched_cond, NULL);
11203 
11204    io = io_context_create();
11205    sched = sched_context_create();
11206    
11207    if (!io || !sched) {
11208       ast_log(LOG_ERROR, "Out of memory\n");
11209       return -1;
11210    }
11211 
11212    netsock = ast_netsock_list_alloc();
11213    if (!netsock) {
11214       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11215       return -1;
11216    }
11217    ast_netsock_init(netsock);
11218 
11219    outsock = ast_netsock_list_alloc();
11220    if (!outsock) {
11221       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11222       return -1;
11223    }
11224    ast_netsock_init(outsock);
11225 
11226    ast_mutex_init(&waresl.lock);
11227 
11228    AST_LIST_HEAD_INIT(&iaxq.queue);
11229    
11230    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11231 
11232    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11233    
11234    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11235    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11236 
11237    if(set_config(config, 0) == -1)
11238       return AST_MODULE_LOAD_DECLINE;
11239 
11240    if (ast_channel_register(&iax2_tech)) {
11241       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11242       __unload_module();
11243       return -1;
11244    }
11245 
11246    if (ast_register_switch(&iax2_switch)) 
11247       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11248 
11249    res = start_network_thread();
11250    if (!res) {
11251       if (option_verbose > 1) 
11252          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11253    } else {
11254       ast_log(LOG_ERROR, "Unable to start network thread\n");
11255       ast_netsock_release(netsock);
11256       ast_netsock_release(outsock);
11257    }
11258 
11259    AST_LIST_LOCK(&registrations);
11260    AST_LIST_TRAVERSE(&registrations, reg, entry)
11261       iax2_do_register(reg);
11262    AST_LIST_UNLOCK(&registrations); 
11263 
11264    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11265    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11266 
11267    reload_firmware(0);
11268    iax_provision_reload();
11269    return res;
11270 }
11271 
11272 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11273       .load = load_module,
11274       .unload = unload_module,
11275       .reload = reload,
11276           );

Generated on Thu Oct 8 21:57:22 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.8