Mon Mar 31 07:37:57 2008

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  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Implementation of Inter-Asterisk eXchange Version 2
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \par See also
00026  * \arg \ref Config_iax
00027  *
00028  * \ingroup channel_drivers
00029  */
00030 
00031 /*** MODULEINFO
00032    <use>zaptel</use>
00033         <depend>res_features</depend>
00034  ***/
00035 
00036 #include "asterisk.h"
00037 
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
00039 
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061 
00062 #ifdef HAVE_ZAPTEL
00063 #include <sys/ioctl.h>
00064 #include <zaptel/zaptel.h>
00065 #endif
00066 
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h" 
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099 
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104 
00105 /* Define SCHED_MULTITHREADED to run the scheduler in a special
00106    multithreaded mode. */
00107 #define SCHED_MULTITHREADED
00108 
00109 /* Define DEBUG_SCHED_MULTITHREADED to keep track of where each
00110    thread is actually doing. */
00111 #define DEBUG_SCHED_MULTITHREAD
00112 
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116 
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120 
00121 
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124 
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130 /* Flag to use with trunk calls, keeping these calls high up.  It halves our effective use
00131    but keeps the division between trunked and non-trunked better. */
00132 #define TRUNK_CALL_START   0x4000
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 maxtrunkcall = TRUNK_CALL_START;
00155 static int maxnontrunkcall = 1;
00156 static int maxjitterbuffer=1000;
00157 static int resyncthreshold=1000;
00158 static int maxjitterinterps=10;
00159 static int trunkfreq = 20;
00160 static int authdebug = 1;
00161 static int autokill = 0;
00162 static int iaxcompat = 0;
00163 
00164 static int iaxdefaultdpcache=10 * 60;  /* Cache dialplan entries for 10 minutes by default */
00165 
00166 static int iaxdefaulttimeout = 5;      /* Default to wait no more than 5 seconds for a reply to come back */
00167 
00168 static unsigned int tos = 0;
00169 
00170 static int min_reg_expire;
00171 static int max_reg_expire;
00172 
00173 static int timingfd = -1;           /* Timing file descriptor */
00174 
00175 static struct ast_netsock_list *netsock;
00176 static struct ast_netsock_list *outsock;     /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
00177 static int defaultsockfd = -1;
00178 
00179 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00180 
00181 /* Ethernet, etc */
00182 #define IAX_CAPABILITY_FULLBANDWIDTH   0xFFFF
00183 /* T1, maybe ISDN */
00184 #define IAX_CAPABILITY_MEDBANDWIDTH    (IAX_CAPABILITY_FULLBANDWIDTH &  \
00185                 ~AST_FORMAT_SLINEAR &        \
00186                 ~AST_FORMAT_ULAW &        \
00187                 ~AST_FORMAT_ALAW &        \
00188                 ~AST_FORMAT_G722) 
00189 /* A modem */
00190 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH &      \
00191                 ~AST_FORMAT_G726 &        \
00192                 ~AST_FORMAT_G726_AAL2 &      \
00193                 ~AST_FORMAT_ADPCM)
00194 
00195 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH &      \
00196                 ~AST_FORMAT_G723_1)
00197 
00198 
00199 #define DEFAULT_MAXMS      2000     /* Must be faster than 2 seconds by default */
00200 #define DEFAULT_FREQ_OK    60 * 1000   /* How often to check for the host to be up */
00201 #define DEFAULT_FREQ_NOTOK 10 * 1000   /* How often to check, if the host is down... */
00202 
00203 static   struct io_context *io;
00204 static   struct sched_context *sched;
00205 
00206 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00207 
00208 static int iaxdebug = 0;
00209 
00210 static int iaxtrunkdebug = 0;
00211 
00212 static int test_losspct = 0;
00213 #ifdef IAXTESTS
00214 static int test_late = 0;
00215 static int test_resync = 0;
00216 static int test_jit = 0;
00217 static int test_jitpct = 0;
00218 #endif /* IAXTESTS */
00219 
00220 static char accountcode[AST_MAX_ACCOUNT_CODE];
00221 static char mohinterpret[MAX_MUSICCLASS];
00222 static char mohsuggest[MAX_MUSICCLASS];
00223 static int amaflags = 0;
00224 static int adsi = 0;
00225 static int delayreject = 0;
00226 static int iax2_encryption = 0;
00227 
00228 static struct ast_flags globalflags = { 0 };
00229 
00230 static pthread_t netthreadid = AST_PTHREADT_NULL;
00231 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00232 AST_MUTEX_DEFINE_STATIC(sched_lock);
00233 static ast_cond_t sched_cond;
00234 
00235 enum {
00236    IAX_STATE_STARTED =     (1 << 0),
00237    IAX_STATE_AUTHENTICATED =  (1 << 1),
00238    IAX_STATE_TBD =      (1 << 2),
00239    IAX_STATE_UNCHANGED =      (1 << 3),
00240 } iax2_state;
00241 
00242 struct iax2_context {
00243    char context[AST_MAX_CONTEXT];
00244    struct iax2_context *next;
00245 };
00246 
00247 enum {
00248    IAX_HASCALLERID =    (1 << 0),   /*!< CallerID has been specified */
00249    IAX_DELME =    (1 << 1),   /*!< Needs to be deleted */
00250    IAX_TEMPONLY =    (1 << 2),   /*!< Temporary (realtime) */
00251    IAX_TRUNK =    (1 << 3),   /*!< Treat as a trunk */
00252    IAX_NOTRANSFER =  (1 << 4),   /*!< Don't native bridge */
00253    IAX_USEJITTERBUF =   (1 << 5),   /*!< Use jitter buffer */
00254    IAX_DYNAMIC =     (1 << 6),   /*!< dynamic peer */
00255    IAX_SENDANI =     (1 << 7),   /*!< Send ANI along with CallerID */
00256         /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */
00257    IAX_ALREADYGONE = (1 << 9),   /*!< Already disconnected */
00258    IAX_PROVISION =      (1 << 10),  /*!< This is a provisioning request */
00259    IAX_QUELCH =      (1 << 11),  /*!< Whether or not we quelch audio */
00260    IAX_ENCRYPTED =      (1 << 12),  /*!< Whether we should assume encrypted tx/rx */
00261    IAX_KEYPOPULATED =   (1 << 13),  /*!< Whether we have a key populated */
00262    IAX_CODEC_USER_FIRST =  (1 << 14),  /*!< are we willing to let the other guy choose the codec? */
00263    IAX_CODEC_NOPREFS =     (1 << 15),  /*!< Force old behaviour by turning off prefs */
00264    IAX_CODEC_NOCAP =    (1 << 16),  /*!< only consider requested format and ignore capabilities*/
00265    IAX_RTCACHEFRIENDS =    (1 << 17),  /*!< let realtime stay till your reload */
00266    IAX_RTUPDATE =       (1 << 18),  /*!< Send a realtime update */
00267    IAX_RTAUTOCLEAR =    (1 << 19),  /*!< erase me on expire */ 
00268    IAX_FORCEJITTERBUF = (1 << 20),  /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 
00269    IAX_RTIGNOREREGEXPIRE = (1 << 21),  /*!< When using realtime, ignore registration expiration */
00270    IAX_TRUNKTIMESTAMPS =   (1 << 22),  /*!< Send trunk timestamps */
00271    IAX_TRANSFERMEDIA =  (1 << 23),      /*!< When doing IAX2 transfers, transfer media only */
00272    IAX_MAXAUTHREQ =        (1 << 24),      /*!< Maximum outstanding AUTHREQ restriction is in place */
00273    IAX_DELAYPBXSTART =  (1 << 25),  /*!< Don't start a PBX on the channel until the peer sends us a
00274                        response, so that we've achieved a three-way handshake with
00275                        them before sending voice or anything else*/
00276 } iax2_flags;
00277 
00278 static int global_rtautoclear = 120;
00279 
00280 static int reload_config(void);
00281 static int iax2_reload(int fd, int argc, char *argv[]);
00282 
00283 
00284 struct iax2_user {
00285    AST_DECLARE_STRING_FIELDS(
00286       AST_STRING_FIELD(name);
00287       AST_STRING_FIELD(secret);
00288       AST_STRING_FIELD(dbsecret);
00289       AST_STRING_FIELD(accountcode);
00290       AST_STRING_FIELD(mohinterpret);
00291       AST_STRING_FIELD(mohsuggest);
00292       AST_STRING_FIELD(inkeys);               /*!< Key(s) this user can use to authenticate to us */
00293       AST_STRING_FIELD(language);
00294       AST_STRING_FIELD(cid_num);
00295       AST_STRING_FIELD(cid_name);
00296    );
00297    
00298    int authmethods;
00299    int encmethods;
00300    int amaflags;
00301    int adsi;
00302    unsigned int flags;
00303    int capability;
00304    int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
00305    int curauthreq; /*!< Current number of outstanding AUTHREQs */
00306    struct ast_codec_pref prefs;
00307    struct ast_ha *ha;
00308    struct iax2_context *contexts;
00309    struct ast_variable *vars;
00310 };
00311 
00312 struct iax2_peer {
00313    AST_DECLARE_STRING_FIELDS(
00314       AST_STRING_FIELD(name);
00315       AST_STRING_FIELD(username);
00316       AST_STRING_FIELD(secret);
00317       AST_STRING_FIELD(dbsecret);
00318       AST_STRING_FIELD(outkey);      /*!< What key we use to talk to this peer */
00319 
00320       AST_STRING_FIELD(regexten);     /*!< Extension to register (if regcontext is used) */
00321       AST_STRING_FIELD(context);      /*!< For transfers only */
00322       AST_STRING_FIELD(peercontext);  /*!< Context to pass to peer */
00323       AST_STRING_FIELD(mailbox);     /*!< Mailbox */
00324       AST_STRING_FIELD(mohinterpret);
00325       AST_STRING_FIELD(mohsuggest);
00326       AST_STRING_FIELD(inkeys);     /*!< Key(s) this peer can use to authenticate to us */
00327       /* Suggested caller id if registering */
00328       AST_STRING_FIELD(cid_num);    /*!< Default context (for transfer really) */
00329       AST_STRING_FIELD(cid_name);      /*!< Default context (for transfer really) */
00330       AST_STRING_FIELD(zonetag);    /*!< Time Zone */
00331    );
00332    struct ast_codec_pref prefs;
00333    struct ast_dnsmgr_entry *dnsmgr;    /*!< DNS refresh manager */
00334    struct sockaddr_in addr;
00335    int formats;
00336    int sockfd;             /*!< Socket to use for transmission */
00337    struct in_addr mask;
00338    int adsi;
00339    unsigned int flags;
00340 
00341    /* Dynamic Registration fields */
00342    struct sockaddr_in defaddr;         /*!< Default address if there is one */
00343    int authmethods;           /*!< Authentication methods (IAX_AUTH_*) */
00344    int encmethods;               /*!< Encryption methods (IAX_ENCRYPT_*) */
00345 
00346    int expire;             /*!< Schedule entry for expiry */
00347    int expiry;             /*!< How soon to expire */
00348    int capability;               /*!< Capability */
00349 
00350    /* Qualification */
00351    int callno;             /*!< Call number of POKE request */
00352    int pokeexpire;               /*!< Scheduled qualification-related task (ie iax2_poke_peer_s or iax2_poke_noanswer) */
00353    int lastms;             /*!< How long last response took (in ms), or -1 for no response */
00354    int maxms;              /*!< Max ms we will accept for the host to be up, 0 to not monitor */
00355 
00356    int pokefreqok;               /*!< How often to check if the host is up */
00357    int pokefreqnotok;            /*!< How often to check when the host has been determined to be down */
00358    int historicms;               /*!< How long recent average responses took */
00359    int smoothing;             /*!< Sample over how many units to determine historic ms */
00360    
00361    struct ast_ha *ha;
00362 };
00363 
00364 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00365 
00366 static struct iax2_trunk_peer {
00367    ast_mutex_t lock;
00368    int sockfd;
00369    struct sockaddr_in addr;
00370    struct timeval txtrunktime;      /*!< Transmit trunktime */
00371    struct timeval rxtrunktime;      /*!< Receive trunktime */
00372    struct timeval lasttxtime;    /*!< Last transmitted trunktime */
00373    struct timeval trunkact;      /*!< Last trunk activity */
00374    unsigned int lastsent;        /*!< Last sent time */
00375    /* Trunk data and length */
00376    unsigned char *trunkdata;
00377    unsigned int trunkdatalen;
00378    unsigned int trunkdataalloc;
00379    struct iax2_trunk_peer *next;
00380    int trunkerror;
00381    int calls;
00382 } *tpeers = NULL;
00383 
00384 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00385 
00386 struct iax_firmware {
00387    struct iax_firmware *next;
00388    int fd;
00389    int mmaplen;
00390    int dead;
00391    struct ast_iax2_firmware_header *fwh;
00392    unsigned char *buf;
00393 };
00394 
00395 enum iax_reg_state {
00396    REG_STATE_UNREGISTERED = 0,
00397    REG_STATE_REGSENT,
00398    REG_STATE_AUTHSENT,
00399    REG_STATE_REGISTERED,
00400    REG_STATE_REJECTED,
00401    REG_STATE_TIMEOUT,
00402    REG_STATE_NOAUTH
00403 };
00404 
00405 enum iax_transfer_state {
00406    TRANSFER_NONE = 0,
00407    TRANSFER_BEGIN,
00408    TRANSFER_READY,
00409    TRANSFER_RELEASED,
00410    TRANSFER_PASSTHROUGH,
00411    TRANSFER_MBEGIN,
00412    TRANSFER_MREADY,
00413    TRANSFER_MRELEASED,
00414    TRANSFER_MPASSTHROUGH,
00415    TRANSFER_MEDIA,
00416    TRANSFER_MEDIAPASS
00417 };
00418 
00419 struct iax2_registry {
00420    struct sockaddr_in addr;      /*!< Who we connect to for registration purposes */
00421    char username[80];
00422    char secret[80];        /*!< Password or key name in []'s */
00423    char random[80];
00424    int expire;          /*!< Sched ID of expiration */
00425    int refresh;            /*!< How often to refresh */
00426    enum iax_reg_state regstate;
00427    int messages;           /*!< Message count, low 8 bits = new, high 8 bits = old */
00428    int callno;          /*!< Associated call number if applicable */
00429    struct sockaddr_in us;        /*!< Who the server thinks we are */
00430    struct ast_dnsmgr_entry *dnsmgr; /*!< DNS refresh manager */
00431    AST_LIST_ENTRY(iax2_registry) entry;
00432 };
00433 
00434 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00435 
00436 /* Don't retry more frequently than every 10 ms, or less frequently than every 5 seconds */
00437 #define MIN_RETRY_TIME     100
00438 #define MAX_RETRY_TIME     10000
00439 
00440 #define MAX_JITTER_BUFFER  50
00441 #define MIN_JITTER_BUFFER  10
00442 
00443 #define DEFAULT_TRUNKDATA  640 * 10 /*!< 40ms, uncompressed linear * 10 channels */
00444 #define MAX_TRUNKDATA      640 * 200   /*!< 40ms, uncompressed linear * 200 channels */
00445 
00446 #define MAX_TIMESTAMP_SKEW 160      /*!< maximum difference between actual and predicted ts for sending */
00447 
00448 /* If consecutive voice frame timestamps jump by more than this many milliseconds, then jitter buffer will resync */
00449 #define TS_GAP_FOR_JB_RESYNC  5000
00450 
00451 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00452 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00453 static int iaxdynamicthreadcount = 0;
00454 static int iaxactivethreadcount = 0;
00455 
00456 struct iax_rr {
00457    int jitter;
00458    int losspct;
00459    int losscnt;
00460    int packets;
00461    int delay;
00462    int dropped;
00463    int ooo;
00464 };
00465 
00466 struct chan_iax2_pvt {
00467    /*! Socket to send/receive on for this call */
00468    int sockfd;
00469    /*! Last received voice format */
00470    int voiceformat;
00471    /*! Last received video format */
00472    int videoformat;
00473    /*! Last sent voice format */
00474    int svoiceformat;
00475    /*! Last sent video format */
00476    int svideoformat;
00477    /*! What we are capable of sending */
00478    int capability;
00479    /*! Last received timestamp */
00480    unsigned int last;
00481    /*! Last sent timestamp - never send the same timestamp twice in a single call */
00482    unsigned int lastsent;
00483    /*! Timestamp of the last video frame sent */
00484    unsigned int lastvsent;
00485    /*! Next outgoing timestamp if everything is good */
00486    unsigned int nextpred;
00487    /*! True if the last voice we transmitted was not silence/CNG */
00488    int notsilenttx;
00489    /*! Ping time */
00490    unsigned int pingtime;
00491    /*! Max time for initial response */
00492    int maxtime;
00493    /*! Peer Address */
00494    struct sockaddr_in addr;
00495    /*! Actual used codec preferences */
00496    struct ast_codec_pref prefs;
00497    /*! Requested codec preferences */
00498    struct ast_codec_pref rprefs;
00499    /*! Our call number */
00500    unsigned short callno;
00501    /*! Peer callno */
00502    unsigned short peercallno;
00503    /*! Negotiated format, this is only used to remember what format was
00504        chosen for an unauthenticated call so that the channel can get
00505        created later using the right format */
00506    int chosenformat;
00507    /*! Peer selected format */
00508    int peerformat;
00509    /*! Peer capability */
00510    int peercapability;
00511    /*! timeval that we base our transmission on */
00512    struct timeval offset;
00513    /*! timeval that we base our delivery on */
00514    struct timeval rxcore;
00515    /*! The jitterbuffer */
00516         jitterbuf *jb;
00517    /*! active jb read scheduler id */
00518         int jbid;                       
00519    /*! LAG */
00520    int lag;
00521    /*! Error, as discovered by the manager */
00522    int error;
00523    /*! Owner if we have one */
00524    struct ast_channel *owner;
00525    /*! What's our state? */
00526    struct ast_flags state;
00527    /*! Expiry (optional) */
00528    int expiry;
00529    /*! Next outgoing sequence number */
00530    unsigned char oseqno;
00531    /*! Next sequence number they have not yet acknowledged */
00532    unsigned char rseqno;
00533    /*! Next incoming sequence number */
00534    unsigned char iseqno;
00535    /*! Last incoming sequence number we have acknowledged */
00536    unsigned char aseqno;
00537 
00538    AST_DECLARE_STRING_FIELDS(
00539       /*! Peer name */
00540       AST_STRING_FIELD(peer);
00541       /*! Default Context */
00542       AST_STRING_FIELD(context);
00543       /*! Caller ID if available */
00544       AST_STRING_FIELD(cid_num);
00545       AST_STRING_FIELD(cid_name);
00546       /*! Hidden Caller ID (i.e. ANI) if appropriate */
00547       AST_STRING_FIELD(ani);
00548       /*! DNID */
00549       AST_STRING_FIELD(dnid);
00550       /*! RDNIS */
00551       AST_STRING_FIELD(rdnis);
00552       /*! Requested Extension */
00553       AST_STRING_FIELD(exten);
00554       /*! Expected Username */
00555       AST_STRING_FIELD(username);
00556       /*! Expected Secret */
00557       AST_STRING_FIELD(secret);
00558       /*! MD5 challenge */
00559       AST_STRING_FIELD(challenge);
00560       /*! Public keys permitted keys for incoming authentication */
00561       AST_STRING_FIELD(inkeys);
00562       /*! Private key for outgoing authentication */
00563       AST_STRING_FIELD(outkey);
00564       /*! Preferred language */
00565       AST_STRING_FIELD(language);
00566       /*! Hostname/peername for naming purposes */
00567       AST_STRING_FIELD(host);
00568 
00569       AST_STRING_FIELD(dproot);
00570       AST_STRING_FIELD(accountcode);
00571       AST_STRING_FIELD(mohinterpret);
00572       AST_STRING_FIELD(mohsuggest);
00573    );
00574    
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 */
00582    aes_decrypt_ctx dcx;
00583    /*! 32 bytes of semi-random data */
00584    unsigned char semirand[32];
00585    /*! Associated registry */
00586    struct iax2_registry *reg;
00587    /*! Associated peer for poking */
00588    struct iax2_peer *peerpoke;
00589    /*! IAX_ flags */
00590    unsigned int flags;
00591    int adsi;
00592 
00593    /*! Transferring status */
00594    enum iax_transfer_state transferring;
00595    /*! Transfer identifier */
00596    int transferid;
00597    /*! Who we are IAX transfering to */
00598    struct sockaddr_in transfer;
00599    /*! What's the new call number for the transfer */
00600    unsigned short transfercallno;
00601    /*! Transfer decrypt AES-128 Key */
00602    aes_encrypt_ctx tdcx;
00603 
00604    /*! Status of knowledge of peer ADSI capability */
00605    int peeradsicpe;
00606 
00607    /*! Who we are bridged to */
00608    unsigned short bridgecallno;
00609    
00610    int pingid;       /*!< Transmit PING request */
00611    int lagid;        /*!< Retransmit lag request */
00612    int autoid;       /*!< Auto hangup for Dialplan requestor */
00613    int authid;       /*!< Authentication rejection ID */
00614    int authfail;        /*!< Reason to report failure */
00615    int initid;       /*!< Initial peer auto-congest ID (based on qualified peers) */
00616    int calling_ton;
00617    int calling_tns;
00618    int calling_pres;
00619    int amaflags;
00620    struct iax2_dpcache *dpentries;
00621    struct ast_variable *vars;
00622    /*! last received remote rr */
00623    struct iax_rr remote_rr;
00624    /*! Current base time: (just for stats) */
00625    int min;
00626    /*! Dropped frame count: (just for stats) */
00627    int frames_dropped;
00628    /*! received frame count: (just for stats) */
00629    int frames_received;
00630 };
00631 
00632 static struct ast_iax2_queue {
00633    AST_LIST_HEAD(, iax_frame) queue;
00634    int count;
00635 } iaxq;
00636 
00637 /*!
00638  * This module will get much higher performance when doing a lot of
00639  * user and peer lookups if the number of buckets is increased from 1.
00640  * However, to maintain old behavior for Asterisk 1.4, these are set to
00641  * 1 by default.  When using multiple buckets, search order through these
00642  * containers is considered random, so you will not be able to depend on
00643  * the order the entires are specified in iax.conf for matching order. */
00644 #ifdef LOW_MEMORY
00645 #define MAX_PEER_BUCKETS 1
00646 /* #define MAX_PEER_BUCKETS 17 */
00647 #else
00648 #define MAX_PEER_BUCKETS 1
00649 /* #define MAX_PEER_BUCKETS 563 */
00650 #endif
00651 static struct ao2_container *peers;
00652 
00653 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00654 static struct ao2_container *users;
00655 
00656 static struct ast_firmware_list {
00657    struct iax_firmware *wares;
00658    ast_mutex_t lock;
00659 } waresl;
00660 
00661 /*! Extension exists */
00662 #define CACHE_FLAG_EXISTS     (1 << 0)
00663 /*! Extension is nonexistent */
00664 #define CACHE_FLAG_NONEXISTENT      (1 << 1)
00665 /*! Extension can exist */
00666 #define CACHE_FLAG_CANEXIST      (1 << 2)
00667 /*! Waiting to hear back response */
00668 #define CACHE_FLAG_PENDING    (1 << 3)
00669 /*! Timed out */
00670 #define CACHE_FLAG_TIMEOUT    (1 << 4)
00671 /*! Request transmitted */
00672 #define CACHE_FLAG_TRANSMITTED      (1 << 5)
00673 /*! Timeout */
00674 #define CACHE_FLAG_UNKNOWN    (1 << 6)
00675 /*! Matchmore */
00676 #define CACHE_FLAG_MATCHMORE     (1 << 7)
00677 
00678 static struct iax2_dpcache {
00679    char peercontext[AST_MAX_CONTEXT];
00680    char exten[AST_MAX_EXTENSION];
00681    struct timeval orig;
00682    struct timeval expiry;
00683    int flags;
00684    unsigned short callno;
00685    int waiters[256];
00686    struct iax2_dpcache *next;
00687    struct iax2_dpcache *peer; /*!< For linking in peers */
00688 } *dpcache;
00689 
00690 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00691 
00692 static void reg_source_db(struct iax2_peer *p);
00693 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00694 
00695 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00696 
00697 #define IAX_IOSTATE_IDLE      0
00698 #define IAX_IOSTATE_READY     1
00699 #define IAX_IOSTATE_PROCESSING   2
00700 #define IAX_IOSTATE_SCHEDREADY   3
00701 
00702 #define IAX_TYPE_POOL    1
00703 #define IAX_TYPE_DYNAMIC 2
00704 
00705 struct iax2_pkt_buf {
00706    AST_LIST_ENTRY(iax2_pkt_buf) entry;
00707    size_t len;
00708    unsigned char buf[1];
00709 };
00710 
00711 struct iax2_thread {
00712    AST_LIST_ENTRY(iax2_thread) list;
00713    int type;
00714    int iostate;
00715 #ifdef SCHED_MULTITHREADED
00716    void (*schedfunc)(const void *);
00717    const void *scheddata;
00718 #endif
00719 #ifdef DEBUG_SCHED_MULTITHREAD
00720    char curfunc[80];
00721 #endif   
00722    int actions;
00723    pthread_t threadid;
00724    int threadnum;
00725    struct sockaddr_in iosin;
00726    unsigned char readbuf[4096]; 
00727    unsigned char *buf;
00728    ssize_t buf_len;
00729    size_t buf_size;
00730    int iofd;
00731    time_t checktime;
00732    ast_mutex_t lock;
00733    ast_cond_t cond;
00734    unsigned int ready_for_signal:1;
00735    /*! if this thread is processing a full frame,
00736      some information about that frame will be stored
00737      here, so we can avoid dispatching any more full
00738      frames for that callno to other threads */
00739    struct {
00740       unsigned short callno;
00741       struct sockaddr_in sin;
00742       unsigned char type;
00743       unsigned char csub;
00744    } ffinfo;
00745    /*! Queued up full frames for processing.  If more full frames arrive for
00746     *  a call which this thread is already processing a full frame for, they
00747     *  are queued up here. */
00748    AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00749 };
00750 
00751 /* Thread lists */
00752 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00753 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00754 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00755 
00756 static void *iax2_process_thread(void *data);
00757 
00758 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00759 {
00760    ast_mutex_lock(lock);
00761    ast_cond_signal(cond);
00762    ast_mutex_unlock(lock);
00763 }
00764 
00765 static void iax_debug_output(const char *data)
00766 {
00767    if (iaxdebug)
00768       ast_verbose("%s", data);
00769 }
00770 
00771 static void iax_error_output(const char *data)
00772 {
00773    ast_log(LOG_WARNING, "%s", data);
00774 }
00775 
00776 static void jb_error_output(const char *fmt, ...)
00777 {
00778    va_list args;
00779    char buf[1024];
00780 
00781    va_start(args, fmt);
00782    vsnprintf(buf, 1024, fmt, args);
00783    va_end(args);
00784 
00785    ast_log(LOG_ERROR, buf);
00786 }
00787 
00788 static void jb_warning_output(const char *fmt, ...)
00789 {
00790    va_list args;
00791    char buf[1024];
00792 
00793    va_start(args, fmt);
00794    vsnprintf(buf, 1024, fmt, args);
00795    va_end(args);
00796 
00797    ast_log(LOG_WARNING, buf);
00798 }
00799 
00800 static void jb_debug_output(const char *fmt, ...)
00801 {
00802    va_list args;
00803    char buf[1024];
00804 
00805    va_start(args, fmt);
00806    vsnprintf(buf, 1024, fmt, args);
00807    va_end(args);
00808 
00809    ast_verbose(buf);
00810 }
00811 
00812 /* XXX We probably should use a mutex when working with this XXX */
00813 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00814 static ast_mutex_t iaxsl[IAX_MAX_CALLS];
00815 static struct timeval lastused[IAX_MAX_CALLS];
00816 
00817 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);
00818 static int expire_registry(const void *data);
00819 static int iax2_answer(struct ast_channel *c);
00820 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00821 static int iax2_devicestate(void *data);
00822 static int iax2_digit_begin(struct ast_channel *c, char digit);
00823 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00824 static int iax2_do_register(struct iax2_registry *reg);
00825 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00826 static int iax2_hangup(struct ast_channel *c);
00827 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00828 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00829 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00830 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00831 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00832 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00833 static int iax2_sendtext(struct ast_channel *c, const char *text);
00834 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00835 static int iax2_transfer(struct ast_channel *c, const char *dest);
00836 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00837 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00838 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00839 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00840 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00841 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00842 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00843 static struct ast_frame *iax2_read(struct ast_channel *c);
00844 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00845 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00846 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00847 static void prune_peers(void);
00848 
00849 static const struct ast_channel_tech iax2_tech = {
00850    .type = "IAX2",
00851    .description = tdesc,
00852    .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00853    .properties = AST_CHAN_TP_WANTSJITTER,
00854    .requester = iax2_request,
00855    .devicestate = iax2_devicestate,
00856    .send_digit_begin = iax2_digit_begin,
00857    .send_digit_end = iax2_digit_end,
00858    .send_text = iax2_sendtext,
00859    .send_image = iax2_sendimage,
00860    .send_html = iax2_sendhtml,
00861    .call = iax2_call,
00862    .hangup = iax2_hangup,
00863    .answer = iax2_answer,
00864    .read = iax2_read,
00865    .write = iax2_write,
00866    .write_video = iax2_write,
00867    .indicate = iax2_indicate,
00868    .setoption = iax2_setoption,
00869    .bridge = iax2_bridge,
00870    .transfer = iax2_transfer,
00871    .fixup = iax2_fixup,
00872 };
00873 
00874 /* WARNING: insert_idle_thread should only ever be called within the
00875  * context of an iax2_process_thread() thread.
00876  */
00877 static void insert_idle_thread(struct iax2_thread *thread)
00878 {
00879    if (thread->type == IAX_TYPE_DYNAMIC) {
00880       AST_LIST_LOCK(&dynamic_list);
00881       AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00882       AST_LIST_UNLOCK(&dynamic_list);
00883    } else {
00884       AST_LIST_LOCK(&idle_list);
00885       AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00886       AST_LIST_UNLOCK(&idle_list);
00887    }
00888 
00889    return;
00890 }
00891 
00892 static struct iax2_thread *find_idle_thread(void)
00893 {
00894    pthread_attr_t attr;
00895    struct iax2_thread *thread = NULL;
00896 
00897    /* Pop the head of the list off */
00898    AST_LIST_LOCK(&idle_list);
00899    thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00900    AST_LIST_UNLOCK(&idle_list);
00901 
00902    /* If no idle thread is available from the regular list, try dynamic */
00903    if (thread == NULL) {
00904       AST_LIST_LOCK(&dynamic_list);
00905       thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00906       /* Make sure we absolutely have a thread... if not, try to make one if allowed */
00907       if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00908          /* We need to MAKE a thread! */
00909          if ((thread = ast_calloc(1, sizeof(*thread)))) {
00910             thread->threadnum = iaxdynamicthreadcount;
00911             thread->type = IAX_TYPE_DYNAMIC;
00912             ast_mutex_init(&thread->lock);
00913             ast_cond_init(&thread->cond, NULL);
00914             pthread_attr_init(&attr);
00915             pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
00916             if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00917                free(thread);
00918                thread = NULL;
00919             } else {
00920                /* All went well and the thread is up, so increment our count */
00921                iaxdynamicthreadcount++;
00922                
00923                /* Wait for the thread to be ready before returning it to the caller */
00924                while (!thread->ready_for_signal)
00925                   usleep(1);
00926             }
00927          }
00928       }
00929       AST_LIST_UNLOCK(&dynamic_list);
00930    }
00931 
00932    /* this thread is not processing a full frame (since it is idle),
00933       so ensure that the field for the full frame call number is empty */
00934    if (thread)
00935       memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00936 
00937    return thread;
00938 }
00939 
00940 #ifdef SCHED_MULTITHREADED
00941 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00942 {
00943    struct iax2_thread *thread = NULL;
00944    static time_t lasterror;
00945    static time_t t;
00946 
00947    thread = find_idle_thread();
00948 
00949    if (thread != NULL) {
00950       thread->schedfunc = func;
00951       thread->scheddata = data;
00952       thread->iostate = IAX_IOSTATE_SCHEDREADY;
00953 #ifdef DEBUG_SCHED_MULTITHREAD
00954       ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00955 #endif
00956       signal_condition(&thread->lock, &thread->cond);
00957       return 0;
00958    }
00959    time(&t);
00960    if (t != lasterror && option_debug) 
00961       ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00962    lasterror = t;
00963 
00964    return -1;
00965 }
00966 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00967 #endif
00968 
00969 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00970 {
00971    int res;
00972 
00973    res = ast_sched_add(con, when, callback, data);
00974    signal_condition(&sched_lock, &sched_cond);
00975 
00976    return res;
00977 }
00978 
00979 static int send_ping(const void *data);
00980 
00981 static void __send_ping(const void *data)
00982 {
00983    int callno = (long)data;
00984    ast_mutex_lock(&iaxsl[callno]);
00985    if (iaxs[callno] && iaxs[callno]->pingid != -1) {
00986       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
00987       iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
00988    }
00989    ast_mutex_unlock(&iaxsl[callno]);
00990 }
00991 
00992 static int send_ping(const void *data)
00993 {
00994 #ifdef SCHED_MULTITHREADED
00995    if (schedule_action(__send_ping, data))
00996 #endif      
00997       __send_ping(data);
00998    return 0;
00999 }
01000 
01001 static int get_encrypt_methods(const char *s)
01002 {
01003    int e;
01004    if (!strcasecmp(s, "aes128"))
01005       e = IAX_ENCRYPT_AES128;
01006    else if (ast_true(s))
01007       e = IAX_ENCRYPT_AES128;
01008    else
01009       e = 0;
01010    return e;
01011 }
01012 
01013 static int send_lagrq(const void *data);
01014 
01015 static void __send_lagrq(const void *data)
01016 {
01017    int callno = (long)data;
01018    /* Ping only if it's real not if it's bridged */
01019    ast_mutex_lock(&iaxsl[callno]);
01020    if (iaxs[callno] && iaxs[callno]->lagid > -1) {
01021       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01022       iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01023    }
01024    ast_mutex_unlock(&iaxsl[callno]);
01025 }
01026 
01027 static int send_lagrq(const void *data)
01028 {
01029 #ifdef SCHED_MULTITHREADED
01030    if (schedule_action(__send_lagrq, data))
01031 #endif      
01032       __send_lagrq(data);
01033    return 0;
01034 }
01035 
01036 static unsigned char compress_subclass(int subclass)
01037 {
01038    int x;
01039    int power=-1;
01040    /* If it's 128 or smaller, just return it */
01041    if (subclass < IAX_FLAG_SC_LOG)
01042       return subclass;
01043    /* Otherwise find its power */
01044    for (x = 0; x < IAX_MAX_SHIFT; x++) {
01045       if (subclass & (1 << x)) {
01046          if (power > -1) {
01047             ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01048             return 0;
01049          } else
01050             power = x;
01051       }
01052    }
01053    return power | IAX_FLAG_SC_LOG;
01054 }
01055 
01056 static int uncompress_subclass(unsigned char csub)
01057 {
01058    /* If the SC_LOG flag is set, return 2^csub otherwise csub */
01059    if (csub & IAX_FLAG_SC_LOG) {
01060       /* special case for 'compressed' -1 */
01061       if (csub == 0xff)
01062          return -1;
01063       else
01064          return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01065    }
01066    else
01067       return csub;
01068 }
01069 
01070 /*!
01071  * \note The only member of the peer passed here guaranteed to be set is the name field
01072  */
01073 static int peer_hash_cb(const void *obj, const int flags)
01074 {
01075    const struct iax2_peer *peer = obj;
01076 
01077    return ast_str_hash(peer->name);
01078 }
01079 
01080 /*!
01081  * \note The only member of the peer passed here guaranteed to be set is the name field
01082  */
01083 static int peer_cmp_cb(void *obj, void *arg, int flags)
01084 {
01085    struct iax2_peer *peer = obj, *peer2 = arg;
01086 
01087    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01088 }
01089 
01090 /*!
01091  * \note The only member of the user passed here guaranteed to be set is the name field
01092  */
01093 static int user_hash_cb(const void *obj, const int flags)
01094 {
01095    const struct iax2_user *user = obj;
01096 
01097    return ast_str_hash(user->name);
01098 }
01099 
01100 /*!
01101  * \note The only member of the user passed here guaranteed to be set is the name field
01102  */
01103 static int user_cmp_cb(void *obj, void *arg, int flags)
01104 {
01105    struct iax2_user *user = obj, *user2 = arg;
01106 
01107    return !strcasecmp(user->name, user2->name) ? CMP_MATCH : 0;
01108 }
01109 
01110 /*!
01111  * \note This funtion calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
01112  *       so do not call it with a pvt lock held.
01113  */
01114 static struct iax2_peer *find_peer(const char *name, int realtime) 
01115 {
01116    struct iax2_peer *peer = NULL;
01117    struct iax2_peer tmp_peer = {
01118       .name = name,
01119    };
01120 
01121    peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01122 
01123    /* Now go for realtime if applicable */
01124    if(!peer && realtime)
01125       peer = realtime_peer(name, NULL);
01126 
01127    return peer;
01128 }
01129 
01130 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01131 {
01132    ao2_ref(peer, +1);
01133    return peer;
01134 }
01135 
01136 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01137 {
01138    ao2_ref(peer, -1);
01139    return NULL;
01140 }
01141 
01142 static inline struct iax2_user *user_ref(struct iax2_user *user)
01143 {
01144    ao2_ref(user, +1);
01145    return user;
01146 }
01147 
01148 static inline struct iax2_user *user_unref(struct iax2_user *user)
01149 {
01150    ao2_ref(user, -1);
01151    return NULL;
01152 }
01153 
01154 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01155 {
01156    struct iax2_peer *peer = NULL;
01157    int res = 0;
01158    struct ao2_iterator i;
01159 
01160    i = ao2_iterator_init(peers, 0);
01161    while ((peer = ao2_iterator_next(&i))) {
01162       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01163           (peer->addr.sin_port == sin.sin_port)) {
01164          ast_copy_string(host, peer->name, len);
01165          peer_unref(peer);
01166          res = 1;
01167          break;
01168       }
01169       peer_unref(peer);
01170    }
01171 
01172    if (!peer) {
01173       peer = realtime_peer(NULL, &sin);
01174       if (peer) {
01175          ast_copy_string(host, peer->name, len);
01176          peer_unref(peer);
01177          res = 1;
01178       }
01179    }
01180 
01181    return res;
01182 }
01183 
01184 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01185 {
01186    struct chan_iax2_pvt *tmp;
01187    jb_conf jbconf;
01188 
01189    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01190       return NULL;
01191 
01192    if (ast_string_field_init(tmp, 32)) {
01193       free(tmp);
01194       tmp = NULL;
01195       return NULL;
01196    }
01197       
01198    tmp->prefs = prefs;
01199    tmp->callno = 0;
01200    tmp->peercallno = 0;
01201    tmp->transfercallno = 0;
01202    tmp->bridgecallno = 0;
01203    tmp->pingid = -1;
01204    tmp->lagid = -1;
01205    tmp->autoid = -1;
01206    tmp->authid = -1;
01207    tmp->initid = -1;
01208 
01209    ast_string_field_set(tmp,exten, "s");
01210    ast_string_field_set(tmp,host, host);
01211 
01212    tmp->jb = jb_new();
01213    tmp->jbid = -1;
01214    jbconf.max_jitterbuf = maxjitterbuffer;
01215    jbconf.resync_threshold = resyncthreshold;
01216    jbconf.max_contig_interp = maxjitterinterps;
01217    jb_setconf(tmp->jb,&jbconf);
01218 
01219    return tmp;
01220 }
01221 
01222 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01223 {
01224    struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01225    if (new) {
01226       size_t afdatalen = new->afdatalen;
01227       memcpy(new, fr, sizeof(*new));
01228       iax_frame_wrap(new, &fr->af);
01229       new->afdatalen = afdatalen;
01230       new->data = NULL;
01231       new->datalen = 0;
01232       new->direction = DIRECTION_INGRESS;
01233       new->retrans = -1;
01234    }
01235    return new;
01236 }
01237 
01238 #define NEW_PREVENT  0
01239 #define NEW_ALLOW    1
01240 #define NEW_FORCE    2
01241 
01242 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur)
01243 {
01244    if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01245       (cur->addr.sin_port == sin->sin_port)) {
01246       /* This is the main host */
01247       if ((cur->peercallno == callno) ||
01248          ((dcallno == cur->callno) && !cur->peercallno)) {
01249          /* That's us.  Be sure we keep track of the peer call number */
01250          return 1;
01251       }
01252    }
01253    if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01254        (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01255       /* We're transferring */
01256       if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01257          return 1;
01258    }
01259    return 0;
01260 }
01261 
01262 static void update_max_trunk(void)
01263 {
01264    int max = TRUNK_CALL_START;
01265    int x;
01266    /* XXX Prolly don't need locks here XXX */
01267    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01268       if (iaxs[x])
01269          max = x + 1;
01270    }
01271    maxtrunkcall = max;
01272    if (option_debug && iaxdebug)
01273       ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01274 }
01275 
01276 static void update_max_nontrunk(void)
01277 {
01278    int max = 1;
01279    int x;
01280    /* XXX Prolly don't need locks here XXX */
01281    for (x=1;x<TRUNK_CALL_START - 1; x++) {
01282       if (iaxs[x])
01283          max = x + 1;
01284    }
01285    maxnontrunkcall = max;
01286    if (option_debug && iaxdebug)
01287       ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01288 }
01289 
01290 static int make_trunk(unsigned short callno, int locked)
01291 {
01292    int x;
01293    int res= 0;
01294    struct timeval now;
01295    if (iaxs[callno]->oseqno) {
01296       ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01297       return -1;
01298    }
01299    if (callno & TRUNK_CALL_START) {
01300       ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01301       return -1;
01302    }
01303    gettimeofday(&now, NULL);
01304    for (x=TRUNK_CALL_START;x<IAX_MAX_CALLS - 1; x++) {
01305       ast_mutex_lock(&iaxsl[x]);
01306       if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01307          iaxs[x] = iaxs[callno];
01308          iaxs[x]->callno = x;
01309          iaxs[callno] = NULL;
01310          /* Update the two timers that should have been started */
01311          AST_SCHED_DEL(sched, iaxs[x]->pingid);
01312          AST_SCHED_DEL(sched, iaxs[x]->lagid);
01313          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01314          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01315          if (locked)
01316             ast_mutex_unlock(&iaxsl[callno]);
01317          res = x;
01318          if (!locked)
01319             ast_mutex_unlock(&iaxsl[x]);
01320          break;
01321       }
01322       ast_mutex_unlock(&iaxsl[x]);
01323    }
01324    if (x >= IAX_MAX_CALLS - 1) {
01325       ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01326       return -1;
01327    }
01328    if (option_debug)
01329       ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01330    /* We move this call from a non-trunked to a trunked call */
01331    update_max_trunk();
01332    update_max_nontrunk();
01333    return res;
01334 }
01335 
01336 /*!
01337  * \note Calling this function while holding another pvt lock can cause a deadlock.
01338  */
01339 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd)
01340 {
01341    int res = 0;
01342    int x;
01343    struct timeval now;
01344    char host[80];
01345 
01346    if (new <= NEW_ALLOW) {
01347       /* Look for an existing connection first */
01348       for (x=1;(res < 1) && (x<maxnontrunkcall);x++) {
01349          ast_mutex_lock(&iaxsl[x]);
01350          if (iaxs[x]) {
01351             /* Look for an exact match */
01352             if (match(sin, callno, dcallno, iaxs[x])) {
01353                res = x;
01354             }
01355          }
01356          ast_mutex_unlock(&iaxsl[x]);
01357       }
01358       for (x=TRUNK_CALL_START;(res < 1) && (x<maxtrunkcall);x++) {
01359          ast_mutex_lock(&iaxsl[x]);
01360          if (iaxs[x]) {
01361             /* Look for an exact match */
01362             if (match(sin, callno, dcallno, iaxs[x])) {
01363                res = x;
01364             }
01365          }
01366          ast_mutex_unlock(&iaxsl[x]);
01367       }
01368    }
01369    if ((res < 1) && (new >= NEW_ALLOW)) {
01370       /* It may seem odd that we look through the peer list for a name for
01371        * this *incoming* call.  Well, it is weird.  However, users don't
01372        * have an IP address/port number that we can match against.  So,
01373        * this is just checking for a peer that has that IP/port and
01374        * assuming that we have a user of the same name.  This isn't always
01375        * correct, but it will be changed if needed after authentication. */
01376       if (!iax2_getpeername(*sin, host, sizeof(host)))
01377          snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01378       gettimeofday(&now, NULL);
01379       for (x=1;x<TRUNK_CALL_START;x++) {
01380          /* Find first unused call number that hasn't been used in a while */
01381          ast_mutex_lock(&iaxsl[x]);
01382          if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) break;
01383          ast_mutex_unlock(&iaxsl[x]);
01384       }
01385       /* We've still got lock held if we found a spot */
01386       if (x >= TRUNK_CALL_START) {
01387          ast_log(LOG_WARNING, "No more space\n");
01388          return 0;
01389       }
01390       iaxs[x] = new_iax(sin, host);
01391       update_max_nontrunk();
01392       if (iaxs[x]) {
01393          if (option_debug && iaxdebug)
01394             ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01395          iaxs[x]->sockfd = sockfd;
01396          iaxs[x]->addr.sin_port = sin->sin_port;
01397          iaxs[x]->addr.sin_family = sin->sin_family;
01398          iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01399          iaxs[x]->peercallno = callno;
01400          iaxs[x]->callno = x;
01401          iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01402          iaxs[x]->expiry = min_reg_expire;
01403          iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01404          iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01405          iaxs[x]->amaflags = amaflags;
01406          ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01407          
01408          ast_string_field_set(iaxs[x], accountcode, accountcode);
01409          ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01410          ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01411       } else {
01412          ast_log(LOG_WARNING, "Out of resources\n");
01413          ast_mutex_unlock(&iaxsl[x]);
01414          return 0;
01415       }
01416       ast_mutex_unlock(&iaxsl[x]);
01417       res = x;
01418    }
01419    return res;
01420 }
01421 
01422 static void iax2_frame_free(struct iax_frame *fr)
01423 {
01424    AST_SCHED_DEL(sched, fr->retrans);
01425    iax_frame_free(fr);
01426 }
01427 
01428 /*!
01429  * \brief Queue a frame to a call's owning asterisk channel
01430  *
01431  * \pre This function assumes that iaxsl[callno] is locked when called.
01432  *
01433  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01434  * was valid before calling it, it may no longer be valid after calling it.
01435  * This function may unlock and lock the mutex associated with this callno,
01436  * meaning that another thread may grab it and destroy the call.
01437  */
01438 static int iax2_queue_frame(int callno, struct ast_frame *f)
01439 {
01440    for (;;) {
01441       if (iaxs[callno] && iaxs[callno]->owner) {
01442          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01443             /* Avoid deadlock by pausing and trying again */
01444             ast_mutex_unlock(&iaxsl[callno]);
01445             usleep(1);
01446             ast_mutex_lock(&iaxsl[callno]);
01447          } else {
01448             ast_queue_frame(iaxs[callno]->owner, f);
01449             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01450             break;
01451          }
01452       } else
01453          break;
01454    }
01455    return 0;
01456 }
01457 
01458 /*!
01459  * \brief Queue a hangup frame on the ast_channel owner
01460  *
01461  * This function queues a hangup frame on the owner of the IAX2 pvt struct that
01462  * is active for the given call number.
01463  *
01464  * \pre Assumes lock for callno is already held.
01465  *
01466  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01467  * was valid before calling it, it may no longer be valid after calling it.
01468  * This function may unlock and lock the mutex associated with this callno,
01469  * meaning that another thread may grab it and destroy the call.
01470  */
01471 static int iax2_queue_hangup(int callno)
01472 {
01473    for (;;) {
01474       if (iaxs[callno] && iaxs[callno]->owner) {
01475          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01476             /* Avoid deadlock by pausing and trying again */
01477             ast_mutex_unlock(&iaxsl[callno]);
01478             usleep(1);
01479             ast_mutex_lock(&iaxsl[callno]);
01480          } else {
01481             ast_queue_hangup(iaxs[callno]->owner);
01482             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01483             break;
01484          }
01485       } else
01486          break;
01487    }
01488    return 0;
01489 }
01490 
01491 /*!
01492  * \brief Queue a control frame on the ast_channel owner
01493  *
01494  * This function queues a control frame on the owner of the IAX2 pvt struct that
01495  * is active for the given call number.
01496  *
01497  * \pre Assumes lock for callno is already held.
01498  *
01499  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01500  * was valid before calling it, it may no longer be valid after calling it.
01501  * This function may unlock and lock the mutex associated with this callno,
01502  * meaning that another thread may grab it and destroy the call.
01503  */
01504 static int iax2_queue_control_data(int callno, 
01505    enum ast_control_frame_type control, const void *data, size_t datalen)
01506 {
01507    for (;;) {
01508       if (iaxs[callno] && iaxs[callno]->owner) {
01509          if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01510             /* Avoid deadlock by pausing and trying again */
01511             ast_mutex_unlock(&iaxsl[callno]);
01512             usleep(1);
01513             ast_mutex_lock(&iaxsl[callno]);
01514          } else {
01515             ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01516             ast_mutex_unlock(&iaxs[callno]->owner->lock);
01517             break;
01518          }
01519       } else
01520          break;
01521    }
01522    return 0;
01523 }
01524 static void destroy_firmware(struct iax_firmware *cur)
01525 {
01526    /* Close firmware */
01527    if (cur->fwh) {
01528       munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01529    }
01530    close(cur->fd);
01531    free(cur);
01532 }
01533 
01534 static int try_firmware(char *s)
01535 {
01536    struct stat stbuf;
01537    struct iax_firmware *cur;
01538    int ifd;
01539    int fd;
01540    int res;
01541    
01542    struct ast_iax2_firmware_header *fwh, fwh2;
01543    struct MD5Context md5;
01544    unsigned char sum[16];
01545    unsigned char buf[1024];
01546    int len, chunk;
01547    char *s2;
01548    char *last;
01549    s2 = alloca(strlen(s) + 100);
01550    if (!s2) {
01551       ast_log(LOG_WARNING, "Alloca failed!\n");
01552       return -1;
01553    }
01554    last = strrchr(s, '/');
01555    if (last)
01556       last++;
01557    else
01558       last = s;
01559    snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01560    res = stat(s, &stbuf);
01561    if (res < 0) {
01562       ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01563       return -1;
01564    }
01565    /* Make sure it's not a directory */
01566    if (S_ISDIR(stbuf.st_mode))
01567       return -1;
01568    ifd = open(s, O_RDONLY);
01569    if (ifd < 0) {
01570       ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01571       return -1;
01572    }
01573    fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01574    if (fd < 0) {
01575       ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01576       close(ifd);
01577       return -1;
01578    }
01579    /* Unlink our newly created file */
01580    unlink(s2);
01581    
01582    /* Now copy the firmware into it */
01583    len = stbuf.st_size;
01584    while(len) {
01585       chunk = len;
01586       if (chunk > sizeof(buf))
01587          chunk = sizeof(buf);
01588       res = read(ifd, buf, chunk);
01589       if (res != chunk) {
01590          ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01591          close(ifd);
01592          close(fd);
01593          return -1;
01594       }
01595       res = write(fd, buf, chunk);
01596       if (res != chunk) {
01597          ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01598          close(ifd);
01599          close(fd);
01600          return -1;
01601       }
01602       len -= chunk;
01603    }
01604    close(ifd);
01605    /* Return to the beginning */
01606    lseek(fd, 0, SEEK_SET);
01607    if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01608       ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01609       close(fd);
01610       return -1;
01611    }
01612    if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01613       ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01614       close(fd);
01615       return -1;
01616    }
01617    if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01618       ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01619       close(fd);
01620       return -1;
01621    }
01622    if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01623       ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01624       close(fd);
01625       return -1;
01626    }
01627    fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 
01628    if (fwh == (void *) -1) {
01629       ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01630       close(fd);
01631       return -1;
01632    }
01633    MD5Init(&md5);
01634    MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01635    MD5Final(sum, &md5);
01636    if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01637       ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01638       munmap((void*)fwh, stbuf.st_size);
01639       close(fd);
01640       return -1;
01641    }
01642    cur = waresl.wares;
01643    while(cur) {
01644       if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01645          /* Found a candidate */
01646          if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01647             /* The version we have on loaded is older, load this one instead */
01648             break;
01649          /* This version is no newer than what we have.  Don't worry about it.
01650             We'll consider it a proper load anyhow though */
01651          munmap((void*)fwh, stbuf.st_size);
01652          close(fd);
01653          return 0;
01654       }
01655       cur = cur->next;
01656    }
01657    if (!cur) {
01658       /* Allocate a new one and link it */
01659       if ((cur = ast_calloc(1, sizeof(*cur)))) {
01660          cur->fd = -1;
01661          cur->next = waresl.wares;
01662          waresl.wares = cur;
01663       }
01664    }
01665    if (cur) {
01666       if (cur->fwh) {
01667          munmap((void*)cur->fwh, cur->mmaplen);
01668       }
01669       if (cur->fd > -1)
01670          close(cur->fd);
01671       cur->fwh = fwh;
01672       cur->fd = fd;
01673       cur->mmaplen = stbuf.st_size;
01674       cur->dead = 0;
01675    }
01676    return 0;
01677 }
01678 
01679 static int iax_check_version(char *dev)
01680 {
01681    int res = 0;
01682    struct iax_firmware *cur;
01683    if (!ast_strlen_zero(dev)) {
01684       ast_mutex_lock(&waresl.lock);
01685       cur = waresl.wares;
01686       while(cur) {
01687          if (!strcmp(dev, (char *)cur->fwh->devname)) {
01688             res = ntohs(cur->fwh->version);
01689             break;
01690          }
01691          cur = cur->next;
01692       }
01693       ast_mutex_unlock(&waresl.lock);
01694    }
01695    return res;
01696 }
01697 
01698 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01699 {
01700    int res = -1;
01701    unsigned int bs = desc & 0xff;
01702    unsigned int start = (desc >> 8) & 0xffffff;
01703    unsigned int bytes;
01704    struct iax_firmware *cur;
01705    if (!ast_strlen_zero((char *)dev) && bs) {
01706       start *= bs;
01707       ast_mutex_lock(&waresl.lock);
01708       cur = waresl.wares;
01709       while(cur) {
01710          if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01711             iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01712             if (start < ntohl(cur->fwh->datalen)) {
01713                bytes = ntohl(cur->fwh->datalen) - start;
01714                if (bytes > bs)
01715                   bytes = bs;
01716                iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
01717             } else {
01718                bytes = 0;
01719                iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
01720             }
01721             if (bytes == bs)
01722                res = 0;
01723             else
01724                res = 1;
01725             break;
01726          }
01727          cur = cur->next;
01728       }
01729       ast_mutex_unlock(&waresl.lock);
01730    }
01731    return res;
01732 }
01733 
01734 
01735 static void reload_firmware(int unload)
01736 {
01737    struct iax_firmware *cur, *curl, *curp;
01738    DIR *fwd;
01739    struct dirent *de;
01740    char dir[256];
01741    char fn[256];
01742    /* Mark all as dead */
01743    ast_mutex_lock(&waresl.lock);
01744    cur = waresl.wares;
01745    while(cur) {
01746       cur->dead = 1;
01747       cur = cur->next;
01748    }
01749 
01750    /* Now that we've freed them, load the new ones */
01751    if (!unload) {
01752       snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
01753       fwd = opendir(dir);
01754       if (fwd) {
01755          while((de = readdir(fwd))) {
01756             if (de->d_name[0] != '.') {
01757                snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
01758                if (!try_firmware(fn)) {
01759                   if (option_verbose > 1)
01760                      ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
01761                }
01762             }
01763          }
01764          closedir(fwd);
01765       } else 
01766          ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
01767    }
01768 
01769    /* Clean up leftovers */
01770    cur = waresl.wares;
01771    curp = NULL;
01772    while(cur) {
01773       curl = cur;
01774       cur = cur->next;
01775       if (curl->dead) {
01776          if (curp) {
01777             curp->next = cur;
01778          } else {
01779             waresl.wares = cur;
01780          }
01781          destroy_firmware(curl);
01782       } else {
01783          curp = cur;
01784       }
01785    }
01786    ast_mutex_unlock(&waresl.lock);
01787 }
01788 
01789 /*!
01790  * \note This function assumes that iaxsl[callno] is locked when called.
01791  *
01792  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
01793  * was valid before calling it, it may no longer be valid after calling it.
01794  * This function calls iax2_queue_frame(), which may unlock and lock the mutex 
01795  * associated with this callno, meaning that another thread may grab it and destroy the call.
01796  */
01797 static int __do_deliver(void *data)
01798 {
01799    /* Just deliver the packet by using queueing.  This is called by
01800      the IAX thread with the iaxsl lock held. */
01801    struct iax_frame *fr = data;
01802    fr->retrans = -1;
01803    ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
01804    if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
01805       iax2_queue_frame(fr->callno, &fr->af);
01806    /* Free our iax frame */
01807    iax2_frame_free(fr);
01808    /* And don't run again */
01809    return 0;
01810 }
01811 
01812 static int handle_error(void)
01813 {
01814    /* XXX Ideally we should figure out why an error occured and then abort those
01815       rather than continuing to try.  Unfortunately, the published interface does
01816       not seem to work XXX */
01817 #if 0
01818    struct sockaddr_in *sin;
01819    int res;
01820    struct msghdr m;
01821    struct sock_extended_err e;
01822    m.msg_name = NULL;
01823    m.msg_namelen = 0;
01824    m.msg_iov = NULL;
01825    m.msg_control = &e;
01826    m.msg_controllen = sizeof(e);
01827    m.msg_flags = 0;
01828    res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
01829    if (res < 0)
01830       ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
01831    else {
01832       if (m.msg_controllen) {
01833          sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
01834          if (sin) 
01835             ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
01836          else
01837             ast_log(LOG_WARNING, "No address detected??\n");
01838       } else {
01839          ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
01840       }
01841    }
01842 #endif
01843    return 0;
01844 }
01845 
01846 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
01847 {
01848    int res;
01849    res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
01850                sizeof(*sin));
01851    if (res < 0) {
01852       if (option_debug)
01853          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01854       handle_error();
01855    } else
01856       res = 0;
01857    return res;
01858 }
01859 
01860 static int send_packet(struct iax_frame *f)
01861 {
01862    int res;
01863    int callno;
01864 
01865    if( f == NULL ) {
01866        ast_log(LOG_ERROR, "send_packet( NULL )\n");
01867        ast_backtrace();
01868        return -1;
01869    }
01870    
01871    callno = f->callno;
01872 
01873    /* Don't send if there was an error, but return error instead */
01874    if (!callno || !iaxs[callno] || iaxs[callno]->error)
01875        return -1;
01876    
01877    /* Called with iaxsl held */
01878    if (option_debug > 2 && iaxdebug)
01879       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));
01880    if (f->transfer) {
01881       if (iaxdebug)
01882          iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
01883       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
01884                sizeof(iaxs[callno]->transfer));
01885    } else {
01886       if (iaxdebug)
01887          iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
01888       res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
01889                sizeof(iaxs[callno]->addr));
01890    }
01891    if (res < 0) {
01892       if (option_debug && iaxdebug)
01893          ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
01894       handle_error();
01895    } else
01896       res = 0;
01897    return res;
01898 }
01899 
01900 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01901 {
01902    /* Decrement AUTHREQ count if needed */
01903    if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01904       struct iax2_user *user;
01905       struct iax2_user tmp_user = {
01906          .name = pvt->username,
01907       };
01908 
01909       user = ao2_find(users, &tmp_user, OBJ_POINTER);
01910       if (user) {
01911          ast_atomic_fetchadd_int(&user->curauthreq, -1);
01912          user_unref(user); 
01913       }
01914 
01915       ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01916    }
01917    /* No more pings or lagrq's */
01918    AST_SCHED_DEL(sched, pvt->pingid);
01919    AST_SCHED_DEL(sched, pvt->lagid);
01920    AST_SCHED_DEL(sched, pvt->autoid);
01921    AST_SCHED_DEL(sched, pvt->authid);
01922    AST_SCHED_DEL(sched, pvt->initid);
01923    AST_SCHED_DEL(sched, pvt->jbid);
01924 }
01925 
01926 /*!
01927  * \note Since this function calls iax2_queue_hangup(), the pvt struct
01928  *       for the given call number may disappear during its execution.
01929  */
01930 static int iax2_predestroy(int callno)
01931 {
01932    struct ast_channel *c;
01933    struct chan_iax2_pvt *pvt = iaxs[callno];
01934 
01935    if (!pvt)
01936       return -1;
01937    if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
01938       iax2_destroy_helper(pvt);
01939       ast_set_flag(pvt, IAX_ALREADYGONE); 
01940    }
01941    c = pvt->owner;
01942    if (c) {
01943       c->tech_pvt = NULL;
01944       iax2_queue_hangup(callno);
01945       pvt->owner = NULL;
01946       ast_module_unref(ast_module_info->self);
01947    }
01948    return 0;
01949 }
01950 
01951 static void iax2_destroy(int callno)
01952 {
01953    struct chan_iax2_pvt *pvt;
01954    struct iax_frame *cur;
01955    struct ast_channel *owner;
01956 
01957 retry:
01958    pvt = iaxs[callno];
01959    gettimeofday(&lastused[callno], NULL);
01960    
01961    owner = pvt ? pvt->owner : NULL;
01962 
01963    if (owner) {
01964       if (ast_mutex_trylock(&owner->lock)) {
01965          ast_log(LOG_NOTICE, "Avoiding IAX destroy deadlock\n");
01966          ast_mutex_unlock(&iaxsl[callno]);
01967          usleep(1);
01968          ast_mutex_lock(&iaxsl[callno]);
01969          goto retry;
01970       }
01971    }
01972    if (!owner)
01973       iaxs[callno] = NULL;
01974    if (pvt) {
01975       if (!owner)
01976          pvt->owner = NULL;
01977       iax2_destroy_helper(pvt);
01978 
01979       /* Already gone */
01980       ast_set_flag(pvt, IAX_ALREADYGONE); 
01981 
01982       if (owner) {
01983          /* If there's an owner, prod it to give up */
01984          /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup()
01985           * because we already hold the owner channel lock. */
01986          ast_queue_hangup(owner);
01987       }
01988 
01989       AST_LIST_LOCK(&iaxq.queue);
01990       AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01991          /* Cancel any pending transmissions */
01992          if (cur->callno == pvt->callno) 
01993             cur->retries = -1;
01994       }
01995       AST_LIST_UNLOCK(&iaxq.queue);
01996 
01997       if (pvt->reg)
01998          pvt->reg->callno = 0;
01999       if (!owner) {
02000          jb_frame frame;
02001          if (pvt->vars) {
02002              ast_variables_destroy(pvt->vars);
02003              pvt->vars = NULL;
02004          }
02005 
02006          while (jb_getall(pvt->jb, &frame) == JB_OK)
02007             iax2_frame_free(frame.data);
02008          jb_destroy(pvt->jb);
02009          /* gotta free up the stringfields */
02010          ast_string_field_free_memory(pvt);
02011          free(pvt);
02012       }
02013    }
02014    if (owner) {
02015       ast_mutex_unlock(&owner->lock);
02016    }
02017    if (callno & 0x4000)
02018       update_max_trunk();
02019 }
02020 
02021 static int update_packet(struct iax_frame *f)
02022 {
02023    /* Called with iaxsl lock held, and iaxs[callno] non-NULL */
02024    struct ast_iax2_full_hdr *fh = f->data;
02025    /* Mark this as a retransmission */
02026    fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02027    /* Update iseqno */
02028    f->iseqno = iaxs[f->callno]->iseqno;
02029    fh->iseqno = f->iseqno;
02030    return 0;
02031 }
02032 
02033 static int attempt_transmit(const void *data);
02034 static void __attempt_transmit(const void *data)
02035 {
02036    /* Attempt to transmit the frame to the remote peer...
02037       Called without iaxsl held. */
02038    struct iax_frame *f = (struct iax_frame *)data;
02039    int freeme=0;
02040    int callno = f->callno;
02041    /* Make sure this call is still active */
02042    if (callno) 
02043       ast_mutex_lock(&iaxsl[callno]);
02044    if (callno && iaxs[callno]) {
02045       if ((f->retries < 0) /* Already ACK'd */ ||
02046           (f->retries >= max_retries) /* Too many attempts */) {
02047             /* Record an error if we've transmitted too many times */
02048             if (f->retries >= max_retries) {
02049                if (f->transfer) {
02050                   /* Transfer timeout */
02051                   send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02052                } else if (f->final) {
02053                   if (f->final) 
02054                      iax2_destroy(callno);
02055                } else {
02056                   if (iaxs[callno]->owner)
02057                      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);
02058                   iaxs[callno]->error = ETIMEDOUT;
02059                   if (iaxs[callno]->owner) {
02060                      struct ast_frame fr = { 0, };
02061                      /* Hangup the fd */
02062                      fr.frametype = AST_FRAME_CONTROL;
02063                      fr.subclass = AST_CONTROL_HANGUP;
02064                      iax2_queue_frame(callno, &fr); // XXX
02065                      /* Remember, owner could disappear */
02066                      if (iaxs[callno] && iaxs[callno]->owner)
02067                         iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02068                   } else {
02069                      if (iaxs[callno]->reg) {
02070                         memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02071                         iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02072                         iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02073                      }
02074                      iax2_destroy(callno);
02075                   }
02076                }
02077 
02078             }
02079             freeme++;
02080       } else {
02081          /* Update it if it needs it */
02082          update_packet(f);
02083          /* Attempt transmission */
02084          send_packet(f);
02085          f->retries++;
02086          /* Try again later after 10 times as long */
02087          f->retrytime *= 10;
02088          if (f->retrytime > MAX_RETRY_TIME)
02089             f->retrytime = MAX_RETRY_TIME;
02090          /* Transfer messages max out at one second */
02091          if (f->transfer && (f->retrytime > 1000))
02092             f->retrytime = 1000;
02093          f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02094       }
02095    } else {
02096       /* Make sure it gets freed */
02097       f->retries = -1;
02098       freeme++;
02099    }
02100    if (callno)
02101       ast_mutex_unlock(&iaxsl[callno]);
02102    /* Do not try again */
02103    if (freeme) {
02104       /* Don't attempt delivery, just remove it from the queue */
02105       AST_LIST_LOCK(&iaxq.queue);
02106       AST_LIST_REMOVE(&iaxq.queue, f, list);
02107       iaxq.count--;
02108       AST_LIST_UNLOCK(&iaxq.queue);
02109       f->retrans = -1;
02110       /* Free the IAX frame */
02111       iax2_frame_free(f);
02112    }
02113 }
02114 
02115 static int attempt_transmit(const void *data)
02116 {
02117 #ifdef SCHED_MULTITHREADED
02118    if (schedule_action(__attempt_transmit, data))
02119 #endif      
02120       __attempt_transmit(data);
02121    return 0;
02122 }
02123 
02124 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02125 {
02126    struct iax2_peer *peer;
02127 
02128    if (argc != 4)
02129         return RESULT_SHOWUSAGE;
02130    if (!strcmp(argv[3],"all")) {
02131       reload_config();
02132       ast_cli(fd, "OK cache is flushed.\n");
02133    } else if ((peer = find_peer(argv[3], 0))) {
02134       if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02135          ast_set_flag(peer, IAX_RTAUTOCLEAR);
02136          expire_registry(peer_ref(peer));
02137          ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02138       } else {
02139          ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02140       }
02141       peer_unref(peer);
02142    } else {
02143       ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02144    }
02145    
02146    return RESULT_SUCCESS;
02147 }
02148 
02149 static int iax2_test_losspct(int fd, int argc, char *argv[])
02150 {
02151        if (argc != 4)
02152                return RESULT_SHOWUSAGE;
02153 
02154        test_losspct = atoi(argv[3]);
02155 
02156        return RESULT_SUCCESS;
02157 }
02158 
02159 #ifdef IAXTESTS
02160 static int iax2_test_late(int fd, int argc, char *argv[])
02161 {
02162    if (argc != 4)
02163       return RESULT_SHOWUSAGE;
02164 
02165    test_late = atoi(argv[3]);
02166 
02167    return RESULT_SUCCESS;
02168 }
02169 
02170 static int iax2_test_resync(int fd, int argc, char *argv[])
02171 {
02172    if (argc != 4)
02173       return RESULT_SHOWUSAGE;
02174 
02175    test_resync = atoi(argv[3]);
02176 
02177    return RESULT_SUCCESS;
02178 }
02179 
02180 static int iax2_test_jitter(int fd, int argc, char *argv[])
02181 {
02182    if (argc < 4 || argc > 5)
02183       return RESULT_SHOWUSAGE;
02184 
02185    test_jit = atoi(argv[3]);
02186    if (argc == 5) 
02187       test_jitpct = atoi(argv[4]);
02188 
02189    return RESULT_SUCCESS;
02190 }
02191 #endif /* IAXTESTS */
02192 
02193 /*! \brief  peer_status: Report Peer status in character string */
02194 /*    returns 1 if peer is online, -1 if unmonitored */
02195 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02196 {
02197    int res = 0;
02198    if (peer->maxms) {
02199       if (peer->lastms < 0) {
02200          ast_copy_string(status, "UNREACHABLE", statuslen);
02201       } else if (peer->lastms > peer->maxms) {
02202          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02203          res = 1;
02204       } else if (peer->lastms) {
02205          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02206          res = 1;
02207       } else {
02208          ast_copy_string(status, "UNKNOWN", statuslen);
02209       }
02210    } else { 
02211       ast_copy_string(status, "Unmonitored", statuslen);
02212       res = -1;
02213    }
02214    return res;
02215 }
02216 
02217 /*! \brief Show one peer in detail */
02218 static int iax2_show_peer(int fd, int argc, char *argv[])
02219 {
02220    char status[30];
02221    char cbuf[256];
02222    struct iax2_peer *peer;
02223    char codec_buf[512];
02224    int x = 0, codec = 0, load_realtime = 0;
02225 
02226    if (argc < 4)
02227       return RESULT_SHOWUSAGE;
02228 
02229    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02230 
02231    peer = find_peer(argv[3], load_realtime);
02232    if (peer) {
02233       ast_cli(fd,"\n\n");
02234       ast_cli(fd, "  * Name       : %s\n", peer->name);
02235       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02236       ast_cli(fd, "  Context      : %s\n", peer->context);
02237       ast_cli(fd, "  Mailbox      : %s\n", peer->mailbox);
02238       ast_cli(fd, "  Dynamic      : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02239       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02240       ast_cli(fd, "  Expire       : %d\n", peer->expire);
02241       ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
02242       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));
02243       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02244       ast_cli(fd, "  Username     : %s\n", peer->username);
02245       ast_cli(fd, "  Codecs       : ");
02246       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02247       ast_cli(fd, "%s\n", codec_buf);
02248 
02249       ast_cli(fd, "  Codec Order  : (");
02250       for(x = 0; x < 32 ; x++) {
02251          codec = ast_codec_pref_index(&peer->prefs,x);
02252          if(!codec)
02253             break;
02254          ast_cli(fd, "%s", ast_getformatname(codec));
02255          if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02256             ast_cli(fd, "|");
02257       }
02258 
02259       if (!x)
02260          ast_cli(fd, "none");
02261       ast_cli(fd, ")\n");
02262 
02263       ast_cli(fd, "  Status       : ");
02264       peer_status(peer, status, sizeof(status));   
02265       ast_cli(fd, "%s\n",status);
02266       ast_cli(fd, "  Qualify      : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02267       ast_cli(fd,"\n");
02268       peer_unref(peer);
02269    } else {
02270       ast_cli(fd,"Peer %s not found.\n", argv[3]);
02271       ast_cli(fd,"\n");
02272    }
02273 
02274    return RESULT_SUCCESS;
02275 }
02276 
02277 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02278 {
02279    int which = 0;
02280    struct iax2_peer *peer;
02281    char *res = NULL;
02282    int wordlen = strlen(word);
02283    struct ao2_iterator i;
02284 
02285    /* 0 - iax2; 1 - show; 2 - peer; 3 - <peername> */
02286    if (pos != 3)
02287       return NULL;
02288 
02289    i = ao2_iterator_init(peers, 0);
02290    while ((peer = ao2_iterator_next(&i))) {
02291       if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02292          res = ast_strdup(peer->name);
02293          peer_unref(peer);
02294          break;
02295       }
02296       peer_unref(peer);
02297    }
02298 
02299    return res;
02300 }
02301 
02302 static int iax2_show_stats(int fd, int argc, char *argv[])
02303 {
02304    struct iax_frame *cur;
02305    int cnt = 0, dead=0, final=0;
02306 
02307    if (argc != 3)
02308       return RESULT_SHOWUSAGE;
02309 
02310    AST_LIST_LOCK(&iaxq.queue);
02311    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02312       if (cur->retries < 0)
02313          dead++;
02314       if (cur->final)
02315          final++;
02316       cnt++;
02317    }
02318    AST_LIST_UNLOCK(&iaxq.queue);
02319 
02320    ast_cli(fd, "    IAX Statistics\n");
02321    ast_cli(fd, "---------------------\n");
02322    ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02323    ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02324    
02325    return RESULT_SUCCESS;
02326 }
02327 
02328 static int iax2_show_cache(int fd, int argc, char *argv[])
02329 {
02330    struct iax2_dpcache *dp;
02331    char tmp[1024], *pc;
02332    int s;
02333    int x,y;
02334    struct timeval tv;
02335    gettimeofday(&tv, NULL);
02336    ast_mutex_lock(&dpcache_lock);
02337    dp = dpcache;
02338    ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02339    while(dp) {
02340       s = dp->expiry.tv_sec - tv.tv_sec;
02341       tmp[0] = '\0';
02342       if (dp->flags & CACHE_FLAG_EXISTS)
02343          strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02344       if (dp->flags & CACHE_FLAG_NONEXISTENT)
02345          strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02346       if (dp->flags & CACHE_FLAG_CANEXIST)
02347          strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02348       if (dp->flags & CACHE_FLAG_PENDING)
02349          strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02350       if (dp->flags & CACHE_FLAG_TIMEOUT)
02351          strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02352       if (dp->flags & CACHE_FLAG_TRANSMITTED)
02353          strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02354       if (dp->flags & CACHE_FLAG_MATCHMORE)
02355          strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02356       if (dp->flags & CACHE_FLAG_UNKNOWN)
02357          strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02358       /* Trim trailing pipe */
02359       if (!ast_strlen_zero(tmp))
02360          tmp[strlen(tmp) - 1] = '\0';
02361       else
02362          ast_copy_string(tmp, "(none)", sizeof(tmp));
02363       y=0;
02364       pc = strchr(dp->peercontext, '@');
02365       if (!pc)
02366          pc = dp->peercontext;
02367       else
02368          pc++;
02369       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02370          if (dp->waiters[x] > -1)
02371             y++;
02372       if (s > 0)
02373          ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02374       else
02375          ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02376       dp = dp->next;
02377    }
02378    ast_mutex_unlock(&dpcache_lock);
02379    return RESULT_SUCCESS;
02380 }
02381 
02382 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02383 
02384 static void unwrap_timestamp(struct iax_frame *fr)
02385 {
02386    int x;
02387 
02388    if ( (fr->ts & 0xFFFF0000) == (iaxs[fr->callno]->last & 0xFFFF0000) ) {
02389       x = fr->ts - iaxs[fr->callno]->last;
02390       if (x < -50000) {
02391          /* Sudden big jump backwards in timestamp:
02392             What likely happened here is that miniframe timestamp has circled but we haven't
02393             gotten the update from the main packet.  We'll just pretend that we did, and
02394             update the timestamp appropriately. */
02395          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) + 0x10000) | (fr->ts & 0xFFFF);
02396          if (option_debug && iaxdebug)
02397             ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02398       }
02399       if (x > 50000) {
02400          /* Sudden apparent big jump forwards in timestamp:
02401             What's likely happened is this is an old miniframe belonging to the previous
02402             top-16-bit timestamp that has turned up out of order.
02403             Adjust the timestamp appropriately. */
02404          fr->ts = ( (iaxs[fr->callno]->last & 0xFFFF0000) - 0x10000) | (fr->ts & 0xFFFF);
02405          if (option_debug && iaxdebug)
02406             ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02407       }
02408    }
02409 }
02410 
02411 static int get_from_jb(const void *p);
02412 
02413 static void update_jbsched(struct chan_iax2_pvt *pvt)
02414 {
02415    int when;
02416    
02417    when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02418    
02419    when = jb_next(pvt->jb) - when;
02420 
02421    AST_SCHED_DEL(sched, pvt->jbid);
02422 
02423    if(when <= 0) {
02424       /* XXX should really just empty until when > 0.. */
02425       when = 1;
02426    }
02427    
02428    pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02429 }
02430 
02431 static void __get_from_jb(const void *p) 
02432 {
02433    int callno = PTR_TO_CALLNO(p);
02434    struct chan_iax2_pvt *pvt = NULL;
02435    struct iax_frame *fr;
02436    jb_frame frame;
02437    int ret;
02438    long now;
02439    long next;
02440    struct timeval tv;
02441    
02442    /* Make sure we have a valid private structure before going on */
02443    ast_mutex_lock(&iaxsl[callno]);
02444    pvt = iaxs[callno];
02445    if (!pvt) {
02446       /* No go! */
02447       ast_mutex_unlock(&iaxsl[callno]);
02448       return;
02449    }
02450     
02451     if( pvt->jb == NULL ) {
02452    ast_log( LOG_ERROR, "__get_from_jb(): why p->jb is null?\n" );
02453    ast_backtrace();
02454    return;
02455     }
02456 
02457    pvt->jbid = -1;
02458    
02459    gettimeofday(&tv,NULL);
02460    /* round up a millisecond since ast_sched_runq does; */
02461    /* prevents us from spinning while waiting for our now */
02462    /* to catch up with runq's now */
02463    tv.tv_usec += 1000;
02464    
02465    now = ast_tvdiff_ms(tv, pvt->rxcore);
02466    
02467    if(now >= (next = jb_next(pvt->jb))) {
02468       ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02469       switch(ret) {
02470       case JB_OK:
02471          fr = frame.data;
02472          __do_deliver(fr);
02473          /* __do_deliver() can cause the call to disappear */
02474          pvt = iaxs[callno];
02475          break;
02476       case JB_INTERP:
02477       {
02478          struct ast_frame af = { 0, };
02479          
02480          /* create an interpolation frame */
02481          af.frametype = AST_FRAME_VOICE;
02482          af.subclass = pvt->voiceformat;
02483          af.samples  = frame.ms * 8;
02484          af.src  = "IAX2 JB interpolation";
02485          af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02486          af.offset = AST_FRIENDLY_OFFSET;
02487          
02488          /* queue the frame:  For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame,
02489           * which we'd need to malloc, and then it would free it.  That seems like a drag */
02490          if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02491             iax2_queue_frame(callno, &af);
02492             /* iax2_queue_frame() could cause the call to disappear */
02493             pvt = iaxs[callno];
02494          }
02495       }
02496          break;
02497       case JB_DROP:
02498          iax2_frame_free(frame.data);
02499          break;
02500       case JB_NOFRAME:
02501       case JB_EMPTY:
02502          /* do nothing */
02503          break;
02504       default:
02505          /* shouldn't happen */
02506          break;
02507       }
02508    }
02509    if (pvt)
02510       update_jbsched(pvt);
02511    ast_mutex_unlock(&iaxsl[callno]);
02512 }
02513 
02514 static int get_from_jb(const void *data)
02515 {
02516 #ifdef SCHED_MULTITHREADED
02517    if (schedule_action(__get_from_jb, data))
02518 #endif      
02519       __get_from_jb(data);
02520    return 0;
02521 }
02522 
02523 /*!
02524  * \note This function assumes fr->callno is locked
02525  *
02526  * \note IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno]
02527  * was valid before calling it, it may no longer be valid after calling it.
02528  */
02529 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02530 {
02531    int type, len;
02532    int ret;
02533    int needfree = 0;
02534    struct ast_channel *owner = NULL;
02535    struct ast_channel *bridge = NULL;
02536    
02537    /* Attempt to recover wrapped timestamps */
02538    unwrap_timestamp(fr);
02539 
02540    /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */
02541    if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02542       fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02543    else {
02544 #if 0
02545       if (option_debug)
02546          ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02547 #endif
02548       fr->af.delivery = ast_tv(0,0);
02549    }
02550 
02551    type = JB_TYPE_CONTROL;
02552    len = 0;
02553 
02554    if(fr->af.frametype == AST_FRAME_VOICE) {
02555       type = JB_TYPE_VOICE;
02556       len = ast_codec_get_samples(&fr->af) / 8;
02557    } else if(fr->af.frametype == AST_FRAME_CNG) {
02558       type = JB_TYPE_SILENCE;
02559    }
02560 
02561    if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02562       if (tsout)
02563          *tsout = fr->ts;
02564       __do_deliver(fr);
02565       return -1;
02566    }
02567 
02568    if ((owner = iaxs[fr->callno]->owner))
02569       bridge = ast_bridged_channel(owner);
02570 
02571    /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to
02572     * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */
02573    if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02574       jb_frame frame;
02575 
02576       /* deliver any frames in the jb */
02577       while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02578          __do_deliver(frame.data);
02579          /* __do_deliver() can make the call disappear */
02580          if (!iaxs[fr->callno])
02581             return -1;
02582       }
02583 
02584       jb_reset(iaxs[fr->callno]->jb);
02585 
02586       AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02587 
02588       /* deliver this frame now */
02589       if (tsout)
02590          *tsout = fr->ts;
02591       __do_deliver(fr);
02592       return -1;
02593    }
02594 
02595    /* insert into jitterbuffer */
02596    /* TODO: Perhaps we could act immediately if it's not droppable and late */
02597    ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02598          calc_rxstamp(iaxs[fr->callno],fr->ts));
02599    if (ret == JB_DROP) {
02600       needfree++;
02601    } else if (ret == JB_SCHED) {
02602       update_jbsched(iaxs[fr->callno]);
02603    }
02604    if (tsout)
02605       *tsout = fr->ts;
02606    if (needfree) {
02607       /* Free our iax frame */
02608       iax2_frame_free(fr);
02609       return -1;
02610    }
02611    return 0;
02612 }
02613 
02614 static int iax2_transmit(struct iax_frame *fr)
02615 {
02616    /* Lock the queue and place this packet at the end */
02617    /* By setting this to 0, the network thread will send it for us, and
02618       queue retransmission if necessary */
02619    fr->sentyet = 0;
02620    AST_LIST_LOCK(&iaxq.queue);
02621    AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02622    iaxq.count++;
02623    AST_LIST_UNLOCK(&iaxq.queue);
02624    /* Wake up the network and scheduler thread */
02625    if (netthreadid != AST_PTHREADT_NULL)
02626       pthread_kill(netthreadid, SIGURG);
02627    signal_condition(&sched_lock, &sched_cond);
02628    return 0;
02629 }
02630 
02631 
02632 
02633 static int iax2_digit_begin(struct ast_channel *c, char digit)
02634 {
02635    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02636 }
02637 
02638 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02639 {
02640    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02641 }
02642 
02643 static int iax2_sendtext(struct ast_channel *c, const char *text)
02644 {
02645    
02646    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02647       0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02648 }
02649 
02650 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02651 {
02652    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02653 }
02654 
02655 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02656 {
02657    return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02658 }
02659 
02660 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02661 {
02662    unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02663    ast_mutex_lock(&iaxsl[callno]);
02664    if (iaxs[callno])
02665       iaxs[callno]->owner = newchan;
02666    else
02667       ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02668    ast_mutex_unlock(&iaxsl[callno]);
02669    return 0;
02670 }
02671 
02672 /*!
02673  * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
02674  *       so do not call this with a pvt lock held.
02675  */
02676 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02677 {
02678    struct ast_variable *var = NULL;
02679    struct ast_variable *tmp;
02680    struct iax2_peer *peer=NULL;
02681    time_t regseconds = 0, nowtime;
02682    int dynamic=0;
02683 
02684    if (peername) {
02685       var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02686       if (!var && sin)
02687          var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02688    } else if (sin) {
02689       char porta[25];
02690       sprintf(porta, "%d", ntohs(sin->sin_port));
02691       var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02692       if (var) {
02693          /* We'll need the peer name in order to build the structure! */
02694          for (tmp = var; tmp; tmp = tmp->next) {
02695             if (!strcasecmp(tmp->name, "name"))
02696                peername = tmp->value;
02697          }
02698       }
02699    }
02700    if (!var && peername) { /* Last ditch effort */
02701       var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02702       /*!\note
02703        * If this one loaded something, then we need to ensure that the host
02704        * field matched.  The only reason why we can't have this as a criteria
02705        * is because we only have the IP address and the host field might be
02706        * set as a name (and the reverse PTR might not match).
02707        */
02708       if (var && sin) {
02709          for (tmp = var; tmp; tmp = tmp->next) {
02710             if (!strcasecmp(tmp->name, "host")) {
02711                struct ast_hostent ahp;
02712                struct hostent *hp;
02713                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02714                   /* No match */
02715                   ast_variables_destroy(var);
02716                   var = NULL;
02717                }
02718                break;
02719             }
02720          }
02721       }
02722    }
02723    if (!var)
02724       return NULL;
02725 
02726    peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02727    
02728    if (!peer) {
02729       ast_variables_destroy(var);
02730       return NULL;
02731    }
02732 
02733    for (tmp = var; tmp; tmp = tmp->next) {
02734       /* Make sure it's not a user only... */
02735       if (!strcasecmp(tmp->name, "type")) {
02736          if (strcasecmp(tmp->value, "friend") &&
02737              strcasecmp(tmp->value, "peer")) {
02738             /* Whoops, we weren't supposed to exist! */
02739             peer = peer_unref(peer);
02740             break;
02741          } 
02742       } else if (!strcasecmp(tmp->name, "regseconds")) {
02743          ast_get_time_t(tmp->value, &regseconds, 0, NULL);
02744       } else if (!strcasecmp(tmp->name, "ipaddr")) {
02745          inet_aton(tmp->value, &(peer->addr.sin_addr));
02746       } else if (!strcasecmp(tmp->name, "port")) {
02747          peer->addr.sin_port = htons(atoi(tmp->value));
02748       } else if (!strcasecmp(tmp->name, "host")) {
02749          if (!strcasecmp(tmp->value, "dynamic"))
02750             dynamic = 1;
02751       }
02752    }
02753 
02754    ast_variables_destroy(var);
02755 
02756    if (!peer)
02757       return NULL;
02758 
02759    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02760       ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02761       if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02762          if (peer->expire > -1) {
02763             if (!ast_sched_del(sched, peer->expire)) {
02764                peer->expire = -1;
02765                peer_unref(peer);
02766             }
02767          }
02768          peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02769          if (peer->expire == -1)
02770             peer_unref(peer);
02771       }
02772       ao2_link(peers, peer);
02773       if (ast_test_flag(peer, IAX_DYNAMIC))
02774          reg_source_db(peer);
02775    } else {
02776       ast_set_flag(peer, IAX_TEMPONLY);   
02777    }
02778 
02779    if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02780       time(&nowtime);
02781       if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02782          memset(&peer->addr, 0, sizeof(peer->addr));
02783          realtime_update_peer(peer->name, &peer->addr, 0);
02784          if (option_debug)
02785             ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02786                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02787       }
02788       else {
02789          if (option_debug)
02790             ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02791                   peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02792       }
02793    }
02794 
02795    return peer;
02796 }
02797 
02798 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02799 {
02800    struct ast_variable *var;
02801    struct ast_variable *tmp;
02802    struct iax2_user *user=NULL;
02803 
02804    var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02805    if (!var)
02806       var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02807    if (!var && sin) {
02808       char porta[6];
02809       snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02810       var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02811       if (!var)
02812          var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02813    }
02814    if (!var) { /* Last ditch effort */
02815       var = ast_load_realtime("iaxusers", "name", username, NULL);
02816       /*!\note
02817        * If this one loaded something, then we need to ensure that the host
02818        * field matched.  The only reason why we can't have this as a criteria
02819        * is because we only have the IP address and the host field might be
02820        * set as a name (and the reverse PTR might not match).
02821        */
02822       if (var) {
02823          for (tmp = var; tmp; tmp = tmp->next) {
02824             if (!strcasecmp(tmp->name, "host")) {
02825                struct ast_hostent ahp;
02826                struct hostent *hp;
02827                if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02828                   /* No match */
02829                   ast_variables_destroy(var);
02830                   var = NULL;
02831                }
02832                break;
02833             }
02834          }
02835       }
02836    }
02837    if (!var)
02838       return NULL;
02839 
02840    tmp = var;
02841    while(tmp) {
02842       /* Make sure it's not a peer only... */
02843       if (!strcasecmp(tmp->name, "type")) {
02844          if (strcasecmp(tmp->value, "friend") &&
02845              strcasecmp(tmp->value, "user")) {
02846             return NULL;
02847          } 
02848       }
02849       tmp = tmp->next;
02850    }
02851 
02852    user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02853 
02854    ast_variables_destroy(var);
02855 
02856    if (!user)
02857       return NULL;
02858 
02859    if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02860       ast_set_flag(user, IAX_RTCACHEFRIENDS);
02861       ao2_link(users, user);
02862    } else {
02863       ast_set_flag(user, IAX_TEMPONLY);   
02864    }
02865 
02866    return user;
02867 }
02868 
02869 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02870 {
02871    char port[10];
02872    char regseconds[20];
02873    
02874    snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02875    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02876    ast_update_realtime("iaxpeers", "name", peername, 
02877       "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 
02878       "regseconds", regseconds, NULL);
02879 }
02880 
02881 struct create_addr_info {
02882    int capability;
02883    unsigned int flags;
02884    int maxtime;
02885    int encmethods;
02886    int found;
02887    int sockfd;
02888    int adsi;
02889    char username[80];
02890    char secret[80];
02891    char outkey[80];
02892    char timezone[80];
02893    char prefs[32];
02894    char context[AST_MAX_CONTEXT];
02895    char peercontext[AST_MAX_CONTEXT];
02896    char mohinterpret[MAX_MUSICCLASS];
02897    char mohsuggest[MAX_MUSICCLASS];
02898 };
02899 
02900 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
02901 {
02902    struct ast_hostent ahp;
02903    struct hostent *hp;
02904    struct iax2_peer *peer;
02905    int res = -1;
02906    struct ast_codec_pref ourprefs;
02907 
02908    ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02909    cai->sockfd = defaultsockfd;
02910    cai->maxtime = 0;
02911    sin->sin_family = AF_INET;
02912 
02913    if (!(peer = find_peer(peername, 1))) {
02914       cai->found = 0;
02915 
02916       hp = ast_gethostbyname(peername, &ahp);
02917       if (hp) {
02918          memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02919          sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02920          /* use global iax prefs for unknown peer/user */
02921          /* But move the calling channel's native codec to the top of the preference list */
02922          memcpy(&ourprefs, &prefs, sizeof(ourprefs));
02923          if (c)
02924             ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
02925          ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
02926          return 0;
02927       } else {
02928          ast_log(LOG_WARNING, "No such host: %s\n", peername);
02929          return -1;
02930       }
02931    }
02932 
02933    cai->found = 1;
02934    
02935    /* if the peer has no address (current or default), return failure */
02936    if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
02937       goto return_unref;
02938 
02939    /* if the peer is being monitored and is currently unreachable, return failure */
02940    if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
02941       goto return_unref;
02942 
02943    ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02944    cai->maxtime = peer->maxms;
02945    cai->capability = peer->capability;
02946    cai->encmethods = peer->encmethods;
02947    cai->sockfd = peer->sockfd;
02948    cai->adsi = peer->adsi;
02949    memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
02950    /* Move the calling channel's native codec to the top of the preference list */
02951    if (c) {
02952       ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
02953       ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
02954    }
02955    ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
02956    ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02957    ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02958    ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02959    ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02960    ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02961    ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
02962    ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
02963    if (ast_strlen_zero(peer->dbsecret)) {
02964       ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02965    } else {
02966       char *family;
02967       char *key = NULL;
02968 
02969       family = ast_strdupa(peer->dbsecret);
02970       key = strchr(family, '/');
02971       if (key)
02972          *key++ = '\0';
02973       if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02974          ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02975          goto return_unref;
02976       }
02977    }
02978 
02979    if (peer->addr.sin_addr.s_addr) {
02980       sin->sin_addr = peer->addr.sin_addr;
02981       sin->sin_port = peer->addr.sin_port;
02982    } else {
02983       sin->sin_addr = peer->defaddr.sin_addr;
02984       sin->sin_port = peer->defaddr.sin_port;
02985    }
02986 
02987    res = 0;
02988 
02989 return_unref:
02990    peer_unref(peer);
02991 
02992    return res;
02993 }
02994 
02995 static void __auto_congest(const void *nothing)
02996 {
02997    int callno = PTR_TO_CALLNO(nothing);
02998    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02999    ast_mutex_lock(&iaxsl[callno]);
03000    if (iaxs[callno]) {
03001       iaxs[callno]->initid = -1;
03002       iax2_queue_frame(callno, &f);
03003       ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03004    }
03005    ast_mutex_unlock(&iaxsl[callno]);
03006 }
03007 
03008 static int auto_congest(const void *data)
03009 {
03010 #ifdef SCHED_MULTITHREADED
03011    if (schedule_action(__auto_congest, data))
03012 #endif      
03013       __auto_congest(data);
03014    return 0;
03015 }
03016 
03017 static unsigned int iax2_datetime(const char *tz)
03018 {
03019    time_t t;
03020    struct tm tm;
03021    unsigned int tmp;
03022    time(&t);
03023    if (!ast_strlen_zero(tz))
03024       ast_localtime(&t, &tm, tz);
03025    else
03026       ast_localtime(&t, &tm, NULL);
03027    tmp  = (tm.tm_sec >> 1) & 0x1f;        /* 5 bits of seconds */
03028    tmp |= (tm.tm_min & 0x3f) << 5;        /* 6 bits of minutes */
03029    tmp |= (tm.tm_hour & 0x1f) << 11;      /* 5 bits of hours */
03030    tmp |= (tm.tm_mday & 0x1f) << 16;      /* 5 bits of day of month */
03031    tmp |= ((tm.tm_mon + 1) & 0xf) << 21;     /* 4 bits of month */
03032    tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */
03033    return tmp;
03034 }
03035 
03036 struct parsed_dial_string {
03037    char *username;
03038    char *password;
03039    char *key;
03040    char *peer;
03041    char *port;
03042    char *exten;
03043    char *context;
03044    char *options;
03045 };
03046 
03047 /*!
03048  * \brief Parses an IAX dial string into its component parts.
03049  * \param data the string to be parsed
03050  * \param pds pointer to a \c struct \c parsed_dial_string to be filled in
03051  * \return nothing
03052  *
03053  * This function parses the string and fills the structure
03054  * with pointers to its component parts. The input string
03055  * will be modified.
03056  *
03057  * \note This function supports both plaintext passwords and RSA
03058  * key names; if the password string is formatted as '[keyname]',
03059  * then the keyname will be placed into the key field, and the
03060  * password field will be set to NULL.
03061  *
03062  * \note The dial string format is:
03063  *       [username[:password]@]peer[:port][/exten[@@context]][/options]
03064  */
03065 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03066 {
03067    if (ast_strlen_zero(data))
03068       return;
03069 
03070    pds->peer = strsep(&data, "/");
03071    pds->exten = strsep(&data, "/");
03072    pds->options = data;
03073 
03074    if (pds->exten) {
03075       data = pds->exten;
03076       pds->exten = strsep(&data, "@");
03077       pds->context = data;
03078    }
03079 
03080    if (strchr(pds->peer, '@')) {
03081       data = pds->peer;
03082       pds->username = strsep(&data, "@");
03083       pds->peer = data;
03084    }
03085 
03086    if (pds->username) {
03087       data = pds->username;
03088       pds->username = strsep(&data, ":");
03089       pds->password = data;
03090    }
03091 
03092    data = pds->peer;
03093    pds->peer = strsep(&data, ":");
03094    pds->port = data;
03095 
03096    /* check for a key name wrapped in [] in the secret position, if found,
03097       move it to the key field instead
03098    */
03099    if (pds->password && (pds->password[0] == '[')) {
03100       pds->key = ast_strip_quoted(pds->password, "[", "]");
03101       pds->password = NULL;
03102    }
03103 }
03104 
03105 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03106 {
03107    struct sockaddr_in sin;
03108    char *l=NULL, *n=NULL, *tmpstr;
03109    struct iax_ie_data ied;
03110    char *defaultrdest = "s";
03111    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03112    struct parsed_dial_string pds;
03113    struct create_addr_info cai;
03114 
03115    if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03116       ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03117       return -1;
03118    }
03119 
03120    memset(&cai, 0, sizeof(cai));
03121    cai.encmethods = iax2_encryption;
03122 
03123    memset(&pds, 0, sizeof(pds));
03124    tmpstr = ast_strdupa(dest);
03125    parse_dial_string(tmpstr, &pds);
03126 
03127    if (ast_strlen_zero(pds.peer)) {
03128       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03129       return -1;
03130    }
03131 
03132    if (!pds.exten)
03133       pds.exten = defaultrdest;
03134 
03135    if (create_addr(pds.peer, c, &sin, &cai)) {
03136       ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03137       return -1;
03138    }
03139 
03140    if (!pds.username && !ast_strlen_zero(cai.username))
03141       pds.username = cai.username;
03142    if (!pds.password && !ast_strlen_zero(cai.secret))
03143       pds.password = cai.secret;
03144    if (!pds.key && !ast_strlen_zero(cai.outkey))
03145       pds.key = cai.outkey;
03146    if (!pds.context && !ast_strlen_zero(cai.peercontext))
03147       pds.context = cai.peercontext;
03148 
03149    /* Keep track of the context for outgoing calls too */
03150    ast_copy_string(c->context, cai.context, sizeof(c->context));
03151 
03152    if (pds.port)
03153       sin.sin_port = htons(atoi(pds.port));
03154 
03155    l = c->cid.cid_num;
03156    n = c->cid.cid_name;
03157 
03158    /* Now build request */ 
03159    memset(&ied, 0, sizeof(ied));
03160 
03161    /* On new call, first IE MUST be IAX version of caller */
03162    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03163    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03164    if (pds.options && strchr(pds.options, 'a')) {
03165       /* Request auto answer */
03166       iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03167    }
03168 
03169    iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03170 
03171    if (l) {
03172       iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03173       iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03174    } else {
03175       if (n)
03176          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03177       else
03178          iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03179    }
03180 
03181    iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03182    iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03183 
03184    if (n)
03185       iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03186    if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03187       iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03188 
03189    if (!ast_strlen_zero(c->language))
03190       iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03191    if (!ast_strlen_zero(c->cid.cid_dnid))
03192       iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03193    if (!ast_strlen_zero(c->cid.cid_rdnis))
03194       iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03195 
03196    if (pds.context)
03197       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03198 
03199    if (pds.username)
03200       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03201 
03202    if (cai.encmethods)
03203       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03204 
03205    ast_mutex_lock(&iaxsl[callno]);
03206 
03207    if (!ast_strlen_zero(c->context))
03208       ast_string_field_set(iaxs[callno], context, c->context);
03209 
03210    if (pds.username)
03211       ast_string_field_set(iaxs[callno], username, pds.username);
03212 
03213    iaxs[callno]->encmethods = cai.encmethods;
03214 
03215    iaxs[callno]->adsi = cai.adsi;
03216    
03217    ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03218    ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03219 
03220    if (pds.key)
03221       ast_string_field_set(iaxs[callno], outkey, pds.key);
03222    if (pds.password)
03223       ast_string_field_set(iaxs[callno], secret, pds.password);
03224 
03225    iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03226    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03227    iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03228    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03229 
03230    if (iaxs[callno]->maxtime) {
03231       /* Initialize pingtime and auto-congest time */
03232       iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03233       iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03234    } else if (autokill) {
03235       iaxs[callno]->pingtime = autokill / 2;
03236       iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03237    }
03238 
03239    /* send the command using the appropriate socket for this peer */
03240    iaxs[callno]->sockfd = cai.sockfd;
03241 
03242    /* Transmit the string in a "NEW" request */
03243    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03244 
03245    ast_mutex_unlock(&iaxsl[callno]);
03246    ast_setstate(c, AST_STATE_RINGING);
03247    
03248    return 0;
03249 }
03250 
03251 static int iax2_hangup(struct ast_channel *c) 
03252 {
03253    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03254    int alreadygone;
03255    struct iax_ie_data ied;
03256    memset(&ied, 0, sizeof(ied));
03257    ast_mutex_lock(&iaxsl[callno]);
03258    if (callno && iaxs[callno]) {
03259       if (option_debug)
03260          ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
03261       alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03262       /* Send the hangup unless we have had a transmission error or are already gone */
03263       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03264       if (!iaxs[callno]->error && !alreadygone) {
03265          send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
03266          if (!iaxs[callno]) {
03267             ast_mutex_unlock(&iaxsl[callno]);
03268             return 0;
03269          }
03270       }
03271       /* Explicitly predestroy it */
03272       iax2_predestroy(callno);
03273       /* If we were already gone to begin with, destroy us now */
03274       if (alreadygone && iaxs[callno]) {
03275          if (option_debug)
03276             ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03277          iax2_destroy(callno);
03278       }
03279    }
03280    ast_mutex_unlock(&iaxsl[callno]);
03281    if (option_verbose > 2) 
03282       ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03283    return 0;
03284 }
03285 
03286 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03287 {
03288    struct ast_option_header *h;
03289    int res;
03290 
03291    switch (option) {
03292    case AST_OPTION_TXGAIN:
03293    case AST_OPTION_RXGAIN:
03294       /* these two cannot be sent, because they require a result */
03295       errno = ENOSYS;
03296       return -1;
03297    default:
03298       if (!(h = ast_malloc(datalen + sizeof(*h))))
03299          return -1;
03300 
03301       h->flag = AST_OPTION_FLAG_REQUEST;
03302       h->option = htons(option);
03303       memcpy(h->data, data, datalen);
03304       res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03305                  AST_CONTROL_OPTION, 0, (unsigned char *) h,
03306                  datalen + sizeof(*h), -1);
03307       free(h);
03308       return res;
03309    }
03310 }
03311 
03312 static struct ast_frame *iax2_read(struct ast_channel *c) 
03313 {
03314    ast_log(LOG_NOTICE, "I should never be called!\n");
03315    return &ast_null_frame;
03316 }
03317 
03318 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03319 {
03320    int res;
03321    struct iax_ie_data ied0;
03322    struct iax_ie_data ied1;
03323    unsigned int transferid = (unsigned int)ast_random();
03324    memset(&ied0, 0, sizeof(ied0));
03325    iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03326    iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03327    iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03328 
03329    memset(&ied1, 0, sizeof(ied1));
03330    iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03331    iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03332    iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03333    
03334    res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03335    if (res)
03336       return -1;
03337    res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03338    if (res)
03339       return -1;
03340    iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03341    iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03342    return 0;
03343 }
03344 
03345 static void lock_both(unsigned short callno0, unsigned short callno1)
03346 {
03347    ast_mutex_lock(&iaxsl[callno0]);
03348    while (ast_mutex_trylock(&iaxsl[callno1])) {
03349       ast_mutex_unlock(&iaxsl[callno0]);
03350       usleep(10);
03351       ast_mutex_lock(&iaxsl[callno0]);
03352    }
03353 }
03354 
03355 static void unlock_both(unsigned short callno0, unsigned short callno1)
03356 {
03357    ast_mutex_unlock(&iaxsl[callno1]);
03358    ast_mutex_unlock(&iaxsl[callno0]);
03359 }
03360 
03361 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)
03362 {
03363    struct ast_channel *cs[3];
03364    struct ast_channel *who, *other;
03365    int to = -1;
03366    int res = -1;
03367    int transferstarted=0;
03368    struct ast_frame *f;
03369    unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03370    unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03371    struct timeval waittimer = {0, 0}, tv;
03372 
03373    lock_both(callno0, callno1);
03374    if (!iaxs[callno0] || !iaxs[callno1]) {
03375       unlock_both(callno0, callno1);
03376       return AST_BRIDGE_FAILED;
03377    }
03378    /* Put them in native bridge mode */
03379    if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03380       iaxs[callno0]->bridgecallno = callno1;
03381       iaxs[callno1]->bridgecallno = callno0;
03382    }
03383    unlock_both(callno0, callno1);
03384 
03385    /* If not, try to bridge until we can execute a transfer, if we can */
03386    cs[0] = c0;
03387    cs[1] = c1;
03388    for (/* ever */;;) {
03389       /* Check in case we got masqueraded into */
03390       if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03391          if (option_verbose > 2)
03392             ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03393          /* Remove from native mode */
03394          if (c0->tech == &iax2_tech) {
03395             ast_mutex_lock(&iaxsl[callno0]);
03396             iaxs[callno0]->bridgecallno = 0;
03397             ast_mutex_unlock(&iaxsl[callno0]);
03398          }
03399          if (c1->tech == &iax2_tech) {
03400             ast_mutex_lock(&iaxsl[callno1]);
03401             iaxs[callno1]->bridgecallno = 0;
03402             ast_mutex_unlock(&iaxsl[callno1]);
03403          }
03404          return AST_BRIDGE_FAILED_NOWARN;
03405       }
03406       if (c0->nativeformats != c1->nativeformats) {
03407          if (option_verbose > 2) {
03408             char buf0[255];
03409             char buf1[255];
03410             ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03411             ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03412             ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03413          }
03414          /* Remove from native mode */
03415          lock_both(callno0, callno1);
03416          if (iaxs[callno0])
03417             iaxs[callno0]->bridgecallno = 0;
03418          if (iaxs[callno1])
03419             iaxs[callno1]->bridgecallno = 0;
03420          unlock_both(callno0, callno1);
03421          return AST_BRIDGE_FAILED_NOWARN;
03422       }
03423       /* check if transfered and if we really want native bridging */
03424       if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03425          /* Try the transfer */
03426          if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03427                      ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03428             ast_log(LOG_WARNING, "Unable to start the transfer\n");
03429          transferstarted = 1;
03430       }
03431       if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03432          /* Call has been transferred.  We're no longer involved */
03433          gettimeofday(&tv, NULL);
03434          if (ast_tvzero(waittimer)) {
03435             waittimer = tv;
03436          } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03437             c0->_softhangup |= AST_SOFTHANGUP_DEV;
03438             c1->_softhangup |= AST_SOFTHANGUP_DEV;
03439             *fo = NULL;
03440             *rc = c0;
03441             res = AST_BRIDGE_COMPLETE;
03442             break;
03443          }
03444       }
03445       to = 1000;
03446       who = ast_waitfor_n(cs, 2, &to);
03447       if (timeoutms > -1) {
03448          timeoutms -= (1000 - to);
03449          if (timeoutms < 0)
03450             timeoutms = 0;
03451       }
03452       if (!who) {
03453          if (!timeoutms) {
03454             res = AST_BRIDGE_RETRY;
03455             break;
03456          }
03457          if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03458             res = AST_BRIDGE_FAILED;
03459             break;
03460          }
03461          continue;
03462       }
03463       f = ast_read(who);
03464       if (!f) {
03465          *fo = NULL;
03466          *rc = who;
03467          res = AST_BRIDGE_COMPLETE;
03468          break;
03469       }
03470       if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03471          *fo = f;
03472          *rc = who;
03473          res =  AST_BRIDGE_COMPLETE;
03474          break;
03475       }
03476       other = (who == c0) ? c1 : c0;  /* the 'other' channel */
03477       if ((f->frametype == AST_FRAME_VOICE) ||
03478           (f->frametype == AST_FRAME_TEXT) ||
03479           (f->frametype == AST_FRAME_VIDEO) || 
03480           (f->frametype == AST_FRAME_IMAGE) ||
03481           (f->frametype == AST_FRAME_DTMF)) {
03482          /* monitored dtmf take out of the bridge.
03483           * check if we monitor the specific source.
03484           */
03485          int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03486          if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03487             *rc = who;
03488             *fo = f;
03489             res = AST_BRIDGE_COMPLETE;
03490             /* Remove from native mode */
03491             break;
03492          }
03493          /* everything else goes to the other side */
03494          ast_write(other, f);
03495       }
03496       ast_frfree(f);
03497       /* Swap who gets priority */
03498       cs[2] = cs[0];
03499       cs[0] = cs[1];
03500       cs[1] = cs[2];
03501    }
03502    lock_both(callno0, callno1);
03503    if(iaxs[callno0])
03504       iaxs[callno0]->bridgecallno = 0;
03505    if(iaxs[callno1])
03506       iaxs[callno1]->bridgecallno = 0;
03507    unlock_both(callno0, callno1);
03508    return res;
03509 }
03510 
03511 static int iax2_answer(struct ast_channel *c)
03512 {
03513    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03514    if (option_debug)
03515       ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03516    return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03517 }
03518 
03519 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03520 {
03521    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03522    struct chan_iax2_pvt *pvt;
03523    int res = 0;
03524 
03525    if (option_debug && iaxdebug)
03526       ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03527 
03528    ast_mutex_lock(&iaxsl[callno]);
03529    pvt = iaxs[callno];
03530 
03531    switch (condition) {
03532    case AST_CONTROL_HOLD:
03533       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03534          ast_moh_start(c, data, pvt->mohinterpret);
03535          goto done;
03536       }
03537       break;
03538    case AST_CONTROL_UNHOLD:
03539       if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03540          ast_moh_stop(c);
03541          goto done;
03542       }
03543    }
03544 
03545    res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03546 
03547 done:
03548    ast_mutex_unlock(&iaxsl[callno]);
03549 
03550    return res;
03551 }
03552    
03553 static int iax2_transfer(struct ast_channel *c, const char *dest)
03554 {
03555    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03556    struct iax_ie_data ied;
03557    char tmp[256], *context;
03558    ast_copy_string(tmp, dest, sizeof(tmp));
03559    context = strchr(tmp, '@');
03560    if (context) {
03561       *context = '\0';
03562       context++;
03563    }
03564    memset(&ied, 0, sizeof(ied));
03565    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03566    if (context)
03567       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03568    if (option_debug)
03569       ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03570    return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03571 }
03572    
03573 static int iax2_getpeertrunk(struct sockaddr_in sin)
03574 {
03575    struct iax2_peer *peer;
03576    int res = 0;
03577    struct ao2_iterator i;
03578 
03579    i = ao2_iterator_init(peers, 0);
03580    while ((peer = ao2_iterator_next(&i))) {
03581       if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03582           (peer->addr.sin_port == sin.sin_port)) {
03583          res = ast_test_flag(peer, IAX_TRUNK);
03584          peer_unref(peer);
03585          break;
03586       }
03587       peer_unref(peer);
03588    }
03589 
03590    return res;
03591 }
03592 
03593 /*! \brief  Create new call, interface with the PBX core */
03594 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03595 {
03596    struct ast_channel *tmp;
03597    struct chan_iax2_pvt *i;
03598    struct ast_variable *v = NULL;
03599 
03600    if (!(i = iaxs[callno])) {
03601       ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03602       return NULL;
03603    }
03604 
03605    /* Don't hold call lock */
03606    ast_mutex_unlock(&iaxsl[callno]);
03607    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);
03608    ast_mutex_lock(&iaxsl[callno]);
03609    if (!tmp)
03610       return NULL;
03611    tmp->tech = &iax2_tech;
03612    /* We can support any format by default, until we get restricted */
03613    tmp->nativeformats = capability;
03614    tmp->readformat = ast_best_codec(capability);
03615    tmp->writeformat = ast_best_codec(capability);
03616    tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03617 
03618    /* Don't use ast_set_callerid() here because it will
03619     * generate a NewCallerID event before the NewChannel event */
03620    if (!ast_strlen_zero(i->ani))
03621       tmp->cid.cid_ani = ast_strdup(i->ani);
03622    else
03623       tmp->cid.cid_ani = ast_strdup(i->cid_num);
03624    tmp->cid.cid_dnid = ast_strdup(i->dnid);
03625    tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03626    tmp->cid.cid_pres = i->calling_pres;
03627    tmp->cid.cid_ton = i->calling_ton;
03628    tmp->cid.cid_tns = i->calling_tns;
03629    if (!ast_strlen_zero(i->language))
03630       ast_string_field_set(tmp, language, i->language);
03631    if (!ast_strlen_zero(i->accountcode))
03632       ast_string_field_set(tmp, accountcode, i->accountcode);
03633    if (i->amaflags)
03634       tmp->amaflags = i->amaflags;
03635    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03636    ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03637    if (i->adsi)
03638       tmp->adsicpe = i->peeradsicpe;
03639    else
03640       tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03641    i->owner = tmp;
03642    i->capability = capability;
03643 
03644    for (v = i->vars ; v ; v = v->next)
03645       pbx_builtin_setvar_helper(tmp, v->name, v->value);
03646 
03647    if (state != AST_STATE_DOWN) {
03648       if (ast_pbx_start(tmp)) {
03649          ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03650          ast_hangup(tmp);
03651          i->owner = NULL;
03652          return NULL;
03653       }
03654    }
03655 
03656    ast_module_ref(ast_module_info->self);
03657    
03658    return tmp;
03659 }
03660 
03661 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03662 {
03663    unsigned long int mssincetx; /* unsigned to handle overflows */
03664    long int ms, pred;
03665 
03666    tpeer->trunkact = *tv;
03667    mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03668    if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03669       /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */
03670       tpeer->txtrunktime = *tv;
03671       tpeer->lastsent = 999999;
03672    }
03673    /* Update last transmit time now */
03674    tpeer->lasttxtime = *tv;
03675    
03676    /* Calculate ms offset */
03677    ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03678    /* Predict from last value */
03679    pred = tpeer->lastsent + sampms;
03680    if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03681       ms = pred;
03682    
03683    /* We never send the same timestamp twice, so fudge a little if we must */
03684    if (ms == tpeer->lastsent)
03685       ms = tpeer->lastsent + 1;
03686    tpeer->lastsent = ms;
03687    return ms;
03688 }
03689 
03690 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03691 {
03692    long ms; /* NOT unsigned */
03693    if (ast_tvzero(iaxs[callno]->rxcore)) {
03694       /* Initialize rxcore time if appropriate */
03695       gettimeofday(&iaxs[callno]->rxcore, NULL);
03696       /* Round to nearest 20ms so traces look pretty */
03697       iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03698    }
03699    /* Calculate difference between trunk and channel */
03700    ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03701    /* Return as the sum of trunk time and the difference between trunk and real time */
03702    return ms + ts;
03703 }
03704 
03705 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03706 {
03707    int ms;
03708    int voice = 0;
03709    int genuine = 0;
03710    int adjust;
03711    struct timeval *delivery = NULL;
03712 
03713 
03714    /* What sort of frame do we have?: voice is self-explanatory
03715       "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK
03716       non-genuine frames are CONTROL frames [ringing etc], DTMF
03717       The "genuine" distinction is needed because genuine frames must get a clock-based timestamp,
03718       the others need a timestamp slaved to the voice frames so that they go in sequence
03719    */
03720    if (f) {
03721       if (f->frametype == AST_FRAME_VOICE) {
03722          voice = 1;
03723          delivery = &f->delivery;
03724       } else if (f->frametype == AST_FRAME_IAX) {
03725          genuine = 1;
03726       } else if (f->frametype == AST_FRAME_CNG) {
03727          p->notsilenttx = 0;  
03728       }
03729    }
03730    if (ast_tvzero(p->offset)) {
03731       gettimeofday(&p->offset, NULL);
03732       /* Round to nearest 20ms for nice looking traces */
03733       p->offset.tv_usec -= p->offset.tv_usec % 20000;
03734    }
03735    /* If the timestamp is specified, just send it as is */
03736    if (ts)
03737       return ts;
03738    /* If we have a time that the frame arrived, always use it to make our timestamp */
03739    if (delivery && !ast_tvzero(*delivery)) {
03740       ms = ast_tvdiff_ms(*delivery, p->offset);
03741       if (option_debug > 2 && iaxdebug)
03742          ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03743    } else {
03744       ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03745       if (ms < 0)
03746          ms = 0;
03747       if (voice) {
03748          /* On a voice frame, use predicted values if appropriate */
03749          if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03750             /* Adjust our txcore, keeping voice and non-voice synchronized */
03751             /* AN EXPLANATION:
03752                When we send voice, we usually send "calculated" timestamps worked out
03753                on the basis of the number of samples sent. When we send other frames,
03754                we usually send timestamps worked out from the real clock.
03755                The problem is that they can tend to drift out of step because the 
03756                   source channel's clock and our clock may not be exactly at the same rate.
03757                We fix this by continuously "tweaking" p->offset.  p->offset is "time zero"
03758                for this call.  Moving it adjusts timestamps for non-voice frames.
03759                We make the adjustment in the style of a moving average.  Each time we
03760                adjust p->offset by 10% of the difference between our clock-derived
03761                timestamp and the predicted timestamp.  That's why you see "10000"
03762                below even though IAX2 timestamps are in milliseconds.
03763                The use of a moving average avoids offset moving too radically.
03764                Generally, "adjust" roams back and forth around 0, with offset hardly
03765                changing at all.  But if a consistent different starts to develop it
03766                will be eliminated over the course of 10 frames (200-300msecs) 
03767             */
03768             adjust = (ms - p->nextpred);
03769             if (adjust < 0)
03770                p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03771             else if (adjust > 0)
03772                p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03773 
03774             if (!p->nextpred) {
03775                p->nextpred = ms; /*f->samples / 8;*/
03776                if (p->nextpred <= p->lastsent)
03777                   p->nextpred = p->lastsent + 3;
03778             }
03779             ms = p->nextpred;
03780          } else {
03781                 /* in this case, just use the actual
03782             * time, since we're either way off
03783             * (shouldn't happen), or we're  ending a
03784             * silent period -- and seed the next
03785             * predicted time.  Also, round ms to the
03786             * next multiple of frame size (so our
03787             * silent periods are multiples of
03788             * frame size too) */
03789 
03790             if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03791                ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03792                   abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03793 
03794             if (f->samples >= 8) /* check to make sure we dont core dump */
03795             {
03796                int diff = ms % (f->samples / 8);
03797                if (diff)
03798                    ms += f->samples/8 - diff;
03799             }
03800 
03801             p->nextpred = ms;
03802             p->notsilenttx = 1;
03803          }
03804       } else if ( f->frametype == AST_FRAME_VIDEO ) {
03805          /*
03806          * IAX2 draft 03 says that timestamps MUST be in order.
03807          * It does not say anything about several frames having the same timestamp
03808          * When transporting video, we can have a frame that spans multiple iax packets
03809          * (so called slices), so it would make sense to use the same timestamp for all of
03810          * them
03811          * We do want to make sure that frames don't go backwards though
03812          */
03813          if ( (unsigned int)ms < p->lastsent )
03814             ms = p->lastsent;
03815       } else {
03816          /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless
03817             it's a genuine frame */
03818          if (genuine) {
03819             /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */
03820             if (ms <= p->lastsent)
03821                ms = p->lastsent + 3;
03822          } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03823             /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */
03824             ms = p->lastsent + 3;
03825          }
03826       }
03827    }
03828    p->lastsent = ms;
03829    if (voice)
03830       p->nextpred = p->nextpred + f->samples / 8;
03831    return ms;
03832 }
03833 
03834 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03835 {
03836    /* Returns where in "receive time" we are.  That is, how many ms
03837       since we received (or would have received) the frame with timestamp 0 */
03838    int ms;
03839 #ifdef IAXTESTS
03840    int jit;
03841 #endif /* IAXTESTS */
03842    /* Setup rxcore if necessary */
03843    if (ast_tvzero(p->rxcore)) {
03844       p->rxcore = ast_tvnow();
03845       if (option_debug && iaxdebug)
03846          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03847                p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03848       p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03849 #if 1
03850       if (option_debug && iaxdebug)
03851          ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03852                p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03853 #endif
03854    }
03855 
03856    ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03857 #ifdef IAXTESTS
03858    if (test_jit) {
03859       if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03860          jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03861          if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03862             jit = -jit;
03863          ms += jit;
03864       }
03865    }
03866    if (test_late) {
03867       ms += test_late;
03868       test_late = 0;
03869    }
03870 #endif /* IAXTESTS */
03871    return ms;
03872 }
03873 
03874 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03875 {
03876    struct iax2_trunk_peer *tpeer;
03877    
03878    /* Finds and locks trunk peer */
03879    ast_mutex_lock(&tpeerlock);
03880    for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
03881       /* We don't lock here because tpeer->addr *never* changes */
03882       if (!inaddrcmp(&tpeer->addr, sin)) {
03883          ast_mutex_lock(&tpeer->lock);
03884          break;
03885       }
03886    }
03887    if (!tpeer) {
03888       if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
03889          ast_mutex_init(&tpeer->lock);
03890          tpeer->lastsent = 9999;
03891          memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03892          tpeer->trunkact = ast_tvnow();
03893          ast_mutex_lock(&tpeer->lock);
03894          tpeer->next = tpeers;
03895          tpeer->sockfd = fd;
03896          tpeers = tpeer;
03897 #ifdef SO_NO_CHECK
03898          setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03899 #endif
03900          if (option_debug)
03901             ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03902       }
03903    }
03904    ast_mutex_unlock(&tpeerlock);
03905    return tpeer;
03906 }
03907 
03908 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03909 {
03910    struct ast_frame *f;
03911    struct iax2_trunk_peer *tpeer;
03912    void *tmp, *ptr;
03913    struct ast_iax2_meta_trunk_entry *met;
03914    struct ast_iax2_meta_trunk_mini *mtm;
03915 
03916    f = &fr->af;
03917    tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03918    if (tpeer) {
03919       if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03920          /* Need to reallocate space */
03921          if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03922             if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
03923                ast_mutex_unlock(&tpeer->lock);
03924                return -1;
03925             }
03926             
03927             tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03928             tpeer->trunkdata = tmp;
03929             if (option_debug)
03930                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);
03931          } else {
03932             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));
03933             ast_mutex_unlock(&tpeer->lock);
03934             return -1;
03935          }
03936       }
03937 
03938       /* Append to meta frame */
03939       ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03940       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03941          mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03942          mtm->len = htons(f->datalen);
03943          mtm->mini.callno = htons(pvt->callno);
03944          mtm->mini.ts = htons(0xffff & fr->ts);
03945          ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03946          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03947       } else {
03948          met = (struct ast_iax2_meta_trunk_entry *)ptr;
03949          /* Store call number and length in meta header */
03950          met->callno = htons(pvt->callno);
03951          met->len = htons(f->datalen);
03952          /* Advance pointers/decrease length past trunk entry header */
03953          ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03954          tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03955       }
03956       /* Copy actual trunk data */
03957       memcpy(ptr, f->data, f->datalen);
03958       tpeer->trunkdatalen += f->datalen;
03959 
03960       tpeer->calls++;
03961       ast_mutex_unlock(&tpeer->lock);
03962    }
03963    return 0;
03964 }
03965 
03966 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03967 {
03968    aes_encrypt_key128(digest, ecx);
03969    aes_decrypt_key128(digest, dcx);
03970 }
03971 
03972 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03973 {
03974 #if 0
03975    /* Debug with "fake encryption" */
03976    int x;
03977    if (len % 16)
03978       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03979    for (x=0;x<len;x++)
03980       dst[x] = src[x] ^ 0xff;
03981 #else 
03982    unsigned char lastblock[16] = { 0 };
03983    int x;
03984    while(len > 0) {
03985       aes_decrypt(src, dst, dcx);
03986       for (x=0;x<16;x++)
03987          dst[x] ^= lastblock[x];
03988       memcpy(lastblock, src, sizeof(lastblock));
03989       dst += 16;
03990       src += 16;
03991       len -= 16;
03992    }
03993 #endif
03994 }
03995 
03996 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03997 {
03998 #if 0
03999    /* Debug with "fake encryption" */
04000    int x;
04001    if (len % 16)
04002       ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04003    for (x=0;x<len;x++)
04004       dst[x] = src[x] ^ 0xff;
04005 #else
04006    unsigned char curblock[16] = { 0 };
04007    int x;
04008    while(len > 0) {
04009       for (x=0;x<16;x++)
04010          curblock[x] ^= src[x];
04011       aes_encrypt(curblock, dst, ecx);
04012       memcpy(curblock, dst, sizeof(curblock)); 
04013       dst += 16;
04014       src += 16;
04015       len -= 16;
04016    }
04017 #endif
04018 }
04019 
04020 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04021 {
04022    int padding;
04023    unsigned char *workspace;
04024 
04025    workspace = alloca(*datalen);
04026    memset(f, 0, sizeof(*f));
04027    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04028       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04029       if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04030          return -1;
04031       /* Decrypt */
04032       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04033 
04034       padding = 16 + (workspace[15] & 0xf);
04035       if (option_debug && iaxdebug)
04036          ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04037       if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04038          return -1;
04039 
04040       *datalen -= padding;
04041       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04042       f->frametype = fh->type;
04043       if (f->frametype == AST_FRAME_VIDEO) {
04044          f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04045       } else {
04046          f->subclass = uncompress_subclass(fh->csub);
04047       }
04048    } else {
04049       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04050       if (option_debug && iaxdebug)
04051          ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04052       if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04053          return -1;
04054       /* Decrypt */
04055       memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04056       padding = 16 + (workspace[15] & 0x0f);
04057       if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04058          return -1;
04059       *datalen -= padding;
04060       memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04061    }
04062    return 0;
04063 }
04064 
04065 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04066 {
04067    int padding;
04068    unsigned char *workspace;
04069    workspace = alloca(*datalen + 32);
04070    if (!workspace)
04071       return -1;
04072    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04073       struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04074       if (option_debug && iaxdebug)
04075          ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04076       padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04077       padding = 16 + (padding & 0xf);
04078       memcpy(workspace, poo, padding);
04079       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04080       workspace[15] &= 0xf0;
04081       workspace[15] |= (padding & 0xf);
04082       if (option_debug && iaxdebug)
04083          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]);
04084       *datalen += padding;
04085       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04086       if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04087          memcpy(poo, workspace + *datalen - 32, 32);
04088    } else {
04089       struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04090       if (option_debug && iaxdebug)
04091          ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04092       padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04093       padding = 16 + (padding & 0xf);
04094       memcpy(workspace, poo, padding);
04095       memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04096       workspace[15] &= 0xf0;
04097       workspace[15] |= (padding & 0x0f);
04098       *datalen += padding;
04099       memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04100       if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04101          memcpy(poo, workspace + *datalen - 32, 32);
04102    }
04103    return 0;
04104 }
04105 
04106 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04107 {
04108    int res=-1;
04109    if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04110       /* Search for possible keys, given secrets */
04111       struct MD5Context md5;
04112       unsigned char digest[16];
04113       char *tmppw, *stringp;
04114       
04115       tmppw = ast_strdupa(iaxs[callno]->secret);
04116       stringp = tmppw;
04117       while ((tmppw = strsep(&stringp, ";"))) {
04118          MD5Init(&md5);
04119          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04120          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04121          MD5Final(digest, &md5);
04122          build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04123          res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04124          if (!res) {
04125             ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04126             break;
04127          }
04128       }
04129    } else 
04130       res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04131    return res;
04132 }
04133 
04134 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04135 {
04136    /* Queue a packet for delivery on a given private structure.  Use "ts" for
04137       timestamp, or calculate if ts is 0.  Send immediately without retransmission
04138       or delayed, with retransmission */
04139    struct ast_iax2_full_hdr *fh;
04140    struct ast_iax2_mini_hdr *mh;
04141    struct ast_iax2_video_hdr *vh;
04142    struct {
04143       struct iax_frame fr2;
04144       unsigned char buffer[4096];
04145    } frb;
04146    struct iax_frame *fr;
04147    int res;
04148    int sendmini=0;
04149    unsigned int lastsent;
04150    unsigned int fts;
04151 
04152    frb.fr2.afdatalen = sizeof(frb.buffer);
04153 
04154    if (!pvt) {
04155       ast_log(LOG_WARNING, "No private structure for packet?\n");
04156       return -1;
04157    }
04158    
04159    lastsent = pvt->lastsent;
04160 
04161    /* Calculate actual timestamp */
04162    fts = calc_timestamp(pvt, ts, f);
04163 
04164    /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out
04165     * (the endpoint should detect the lost packet itself).  But, we want to do this here, so that we
04166     * increment the "predicted timestamps" for voice, if we're predecting */
04167    if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04168        return 0;
04169 
04170 
04171    if ((ast_test_flag(pvt, IAX_TRUNK) || 
04172          (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04173          ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04174       /* High two bytes are the same on timestamp, or sending on a trunk */ &&
04175        (f->frametype == AST_FRAME_VOICE) 
04176       /* is a voice frame */ &&
04177       (f->subclass == pvt->svoiceformat) 
04178       /* is the same type */ ) {
04179          /* Force immediate rather than delayed transmission */
04180          now = 1;
04181          /* Mark that mini-style frame is appropriate */
04182          sendmini = 1;
04183    }
04184    if ( f->frametype == AST_FRAME_VIDEO ) {
04185       /*
04186        * If the lower 15 bits of the timestamp roll over, or if
04187        * the video format changed then send a full frame.
04188        * Otherwise send a mini video frame
04189        */
04190       if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04191           ((f->subclass & ~0x1) == pvt->svideoformat)
04192          ) {
04193          now = 1;
04194          sendmini = 1;
04195       } else {
04196          now = 0;
04197          sendmini = 0;
04198       }
04199       pvt->lastvsent = fts;
04200    }
04201    /* Allocate an iax_frame */
04202    if (now) {
04203       fr = &frb.fr2;
04204    } else
04205       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));
04206    if (!fr) {
04207       ast_log(LOG_WARNING, "Out of memory\n");
04208       return -1;
04209    }
04210    /* Copy our prospective frame into our immediate or retransmitted wrapper */
04211    iax_frame_wrap(fr, f);
04212 
04213    fr->ts = fts;
04214    fr->callno = pvt->callno;
04215    fr->transfer = transfer;
04216    fr->final = final;
04217    if (!sendmini) {
04218       /* We need a full frame */
04219       if (seqno > -1)
04220          fr->oseqno = seqno;
04221       else
04222          fr->oseqno = pvt->oseqno++;
04223       fr->iseqno = pvt->iseqno;
04224       fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04225       fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04226       fh->ts = htonl(fr->ts);
04227       fh->oseqno = fr->oseqno;
04228       if (transfer) {
04229          fh->iseqno = 0;
04230       } else
04231          fh->iseqno = fr->iseqno;
04232       /* Keep track of the last thing we've acknowledged */
04233       if (!transfer)
04234          pvt->aseqno = fr->iseqno;
04235       fh->type = fr->af.frametype & 0xFF;
04236       if (fr->af.frametype == AST_FRAME_VIDEO)
04237          fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04238       else
04239          fh->csub = compress_subclass(fr->af.subclass);
04240       if (transfer) {
04241          fr->dcallno = pvt->transfercallno;
04242       } else
04243          fr->dcallno = pvt->peercallno;
04244       fh->dcallno = htons(fr->dcallno);
04245       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04246       fr->data = fh;
04247       fr->retries = 0;
04248       /* Retry after 2x the ping time has passed */
04249       fr->retrytime = pvt->pingtime * 2;
04250       if (fr->retrytime < MIN_RETRY_TIME)
04251          fr->retrytime = MIN_RETRY_TIME;
04252       if (fr->retrytime > MAX_RETRY_TIME)
04253          fr->retrytime = MAX_RETRY_TIME;
04254       /* Acks' don't get retried */
04255       if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04256          fr->retries = -1;
04257       else if (f->frametype == AST_FRAME_VOICE)
04258          pvt->svoiceformat = f->subclass;
04259       else if (f->frametype == AST_FRAME_VIDEO)
04260          pvt->svideoformat = f->subclass & ~0x1;
04261       if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04262          if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04263             if (iaxdebug) {
04264                if (fr->transfer)
04265                   iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04266                else
04267                   iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04268             }
04269             encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04270          } else
04271             ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04272       }
04273    
04274       if (now) {
04275          res = send_packet(fr);
04276       } else
04277          res = iax2_transmit(fr);
04278    } else {
04279       if (ast_test_flag(pvt, IAX_TRUNK)) {
04280          iax2_trunk_queue(pvt, fr);
04281          res = 0;
04282       } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04283          /* Video frame have no sequence number */
04284          fr->oseqno = -1;
04285          fr->iseqno = -1;
04286          vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04287          vh->zeros = 0;
04288          vh->callno = htons(0x8000 | fr->callno);
04289          vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04290          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04291          fr->data = vh;
04292          fr->retries = -1;
04293          res = send_packet(fr);        
04294       } else {
04295          /* Mini-frames have no sequence number */
04296          fr->oseqno = -1;
04297          fr->iseqno = -1;
04298          /* Mini frame will do */
04299          mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04300          mh->callno = htons(fr->callno);
04301          mh->ts = htons(fr->ts & 0xFFFF);
04302          fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04303          fr->data = mh;
04304          fr->retries = -1;
04305          if (pvt->transferring == TRANSFER_MEDIAPASS)
04306             fr->transfer = 1;
04307          if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04308             if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04309                encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04310             } else
04311                ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04312          }
04313          res = send_packet(fr);
04314       }
04315    }
04316    return res;
04317 }
04318 
04319 static int iax2_show_users(int fd, int argc, char *argv[])
04320 {
04321    regex_t regexbuf;
04322    int havepattern = 0;
04323 
04324 #define FORMAT "%-15.15s  %-20.20s  %-15.15s  %-15.15s  %-5.5s  %-5.10s\n"
04325 #define FORMAT2 "%-15.15s  %-20.20s  %-15.15d  %-15.15s  %-5.5s  %-5.10s\n"
04326 
04327    struct iax2_user *user = NULL;
04328    char auth[90];
04329    char *pstr = "";
04330    struct ao2_iterator i;
04331 
04332    switch (argc) {
04333    case 5:
04334       if (!strcasecmp(argv[3], "like")) {
04335          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04336             return RESULT_SHOWUSAGE;
04337          havepattern = 1;
04338       } else
04339          return RESULT_SHOWUSAGE;
04340    case 3:
04341       break;
04342    default:
04343       return RESULT_SHOWUSAGE;
04344    }
04345 
04346    ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04347    i = ao2_iterator_init(users, 0);
04348    for (user = ao2_iterator_next(&i); user; 
04349       user_unref(user), user = ao2_iterator_next(&i)) {
04350       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0))
04351          continue;
04352       
04353       if (!ast_strlen_zero(user->secret)) {
04354          ast_copy_string(auth,user->secret,sizeof(auth));
04355       } else if (!ast_strlen_zero(user->inkeys)) {
04356          snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04357       } else
04358          ast_copy_string(auth, "-no secret-", sizeof(auth));
04359       
04360       if(ast_test_flag(user,IAX_CODEC_NOCAP))
04361          pstr = "REQ Only";
04362       else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04363          pstr = "Disabled";
04364       else
04365          pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04366       
04367       ast_cli(fd, FORMAT2, user->name, auth, user->authmethods, 
04368          user->contexts ? user->contexts->context : context,
04369          user->ha ? "Yes" : "No", pstr);
04370    }
04371 
04372    if (havepattern)
04373       regfree(&regexbuf);
04374 
04375    return RESULT_SUCCESS;
04376 #undef FORMAT
04377 #undef FORMAT2
04378 }
04379 
04380 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04381 {
04382    regex_t regexbuf;
04383    int havepattern = 0;
04384    int total_peers = 0;
04385    int online_peers = 0;
04386    int offline_peers = 0;
04387    int unmonitored_peers = 0;
04388    struct ao2_iterator i;
04389 
04390 #define FORMAT2 "%-15.15s  %-15.15s %s  %-15.15s  %-8s  %s %-10s%s"
04391 #define FORMAT "%-15.15s  %-15.15s %s  %-15.15s  %-5d%s  %s %-10s%s"
04392 
04393    struct iax2_peer *peer = NULL;
04394    char name[256];
04395    int registeredonly=0;
04396    char *term = manager ? "\r\n" : "\n";
04397 
04398    switch (argc) {
04399    case 6:
04400       if (!strcasecmp(argv[3], "registered"))
04401          registeredonly = 1;
04402       else
04403          return RESULT_SHOWUSAGE;
04404       if (!strcasecmp(argv[4], "like")) {
04405          if (regcomp(&regexbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04406             return RESULT_SHOWUSAGE;
04407          havepattern = 1;
04408       } else
04409          return RESULT_SHOWUSAGE;
04410       break;
04411    case 5:
04412       if (!strcasecmp(argv[3], "like")) {
04413          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04414             return RESULT_SHOWUSAGE;
04415          havepattern = 1;
04416       } else
04417          return RESULT_SHOWUSAGE;
04418       break;
04419    case 4:
04420       if (!strcasecmp(argv[3], "registered"))
04421          registeredonly = 1;
04422       else
04423          return RESULT_SHOWUSAGE;
04424       break;
04425    case 3:
04426       break;
04427    default:
04428       return RESULT_SHOWUSAGE;
04429    }
04430 
04431 
04432    if (s)
04433       astman_append(s, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04434    else
04435       ast_cli(fd, FORMAT2, "Name/Username", "Host", "   ", "Mask", "Port", "   ", "Status", term);
04436 
04437    i = ao2_iterator_init(peers, 0);
04438    for (peer = ao2_iterator_next(&i); peer; 
04439       peer_unref(peer), peer = ao2_iterator_next(&i)) {
04440       char nm[20];
04441       char status[20];
04442       char srch[2000];
04443       int retstatus;
04444 
04445       if (registeredonly && !peer->addr.sin_addr.s_addr)
04446          continue;
04447       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0))
04448          continue;
04449 
04450       if (!ast_strlen_zero(peer->username))
04451          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04452       else
04453          ast_copy_string(name, peer->name, sizeof(name));
04454       
04455       retstatus = peer_status(peer, status, sizeof(status));
04456       if (retstatus > 0)
04457          online_peers++;
04458       else if (!retstatus)
04459          offline_peers++;
04460       else
04461          unmonitored_peers++;
04462       
04463       ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04464       
04465       snprintf(srch, sizeof(srch), FORMAT, name, 
04466           peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04467           ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04468           nm,
04469           ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04470           peer->encmethods ? "(E)" : "   ", status, term);
04471       
04472       if (s)
04473          astman_append(s, FORMAT, name, 
04474                   peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04475                   ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04476                   nm,
04477                   ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04478                   peer->encmethods ? "(E)" : "   ", status, term);
04479       else
04480          ast_cli(fd, FORMAT, name, 
04481             peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04482             ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04483             nm,
04484             ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : "   ",
04485             peer->encmethods ? "(E)" : "   ", status, term);
04486       total_peers++;
04487    }
04488 
04489    if (s)
04490       astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04491    else
04492       ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04493 
04494    if (havepattern)
04495       regfree(&regexbuf);
04496 
04497    return RESULT_SUCCESS;
04498 #undef FORMAT
04499 #undef FORMAT2
04500 }
04501 
04502 static int iax2_show_threads(int fd, int argc, char *argv[])
04503 {
04504    struct iax2_thread *thread = NULL;
04505    time_t t;
04506    int threadcount = 0, dynamiccount = 0;
04507    char type;
04508 
04509    if (argc != 3)
04510       return RESULT_SHOWUSAGE;
04511       
04512    ast_cli(fd, "IAX2 Thread Information\n");
04513    time(&t);
04514    ast_cli(fd, "Idle Threads:\n");
04515    AST_LIST_LOCK(&idle_list);
04516    AST_LIST_TRAVERSE(&idle_list, thread, list) {
04517 #ifdef DEBUG_SCHED_MULTITHREAD
04518       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04519          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04520 #else
04521       ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n", 
04522          thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04523 #endif
04524       threadcount++;
04525    }
04526    AST_LIST_UNLOCK(&idle_list);
04527    ast_cli(fd, "Active Threads:\n");
04528    AST_LIST_LOCK(&active_list);
04529    AST_LIST_TRAVERSE(&active_list, thread, list) {
04530       if (thread->type == IAX_TYPE_DYNAMIC)
04531          type = 'D';
04532       else
04533          type = 'P';
04534 #ifdef DEBUG_SCHED_MULTITHREAD
04535       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n", 
04536          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04537 #else
04538       ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 
04539          type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04540 #endif
04541       threadcount++;
04542    }
04543    AST_LIST_UNLOCK(&active_list);
04544    ast_cli(fd, "Dynamic Threads:\n");
04545         AST_LIST_LOCK(&dynamic_list);
04546         AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04547 #ifdef DEBUG_SCHED_MULTITHREAD
04548                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04549                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04550 #else
04551                 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04552                         thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04553 #endif
04554       dynamiccount++;
04555         }
04556         AST_LIST_UNLOCK(&dynamic_list);
04557    ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04558    return RESULT_SUCCESS;
04559 }
04560 
04561 static int iax2_show_peers(int fd, int argc, char *argv[])
04562 {
04563    return __iax2_show_peers(0, fd, NULL, argc, argv);
04564 }
04565 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04566 {
04567    ast_cli_netstats(s, -1, 0);
04568    astman_append(s, "\r\n");
04569    return RESULT_SUCCESS;
04570 }
04571 
04572 static int iax2_show_firmware(int fd, int argc, char *argv[])
04573 {
04574 #define FORMAT2 "%-15.15s  %-15.15s %-15.15s\n"
04575 #if !defined(__FreeBSD__)
04576 #define FORMAT "%-15.15s  %-15d %-15d\n"
04577 #else /* __FreeBSD__ */
04578 #define FORMAT "%-15.15s  %-15d %-15d\n" /* XXX 2.95 ? */
04579 #endif /* __FreeBSD__ */
04580    struct iax_firmware *cur;
04581    if ((argc != 3) && (argc != 4))
04582       return RESULT_SHOWUSAGE;
04583    ast_mutex_lock(&waresl.lock);
04584    
04585    ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04586    for (cur = waresl.wares;cur;cur = cur->next) {
04587       if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname))) 
04588          ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04589             (int)ntohl(cur->fwh->datalen));
04590    }
04591    ast_mutex_unlock(&waresl.lock);
04592    return RESULT_SUCCESS;
04593 #undef FORMAT
04594 #undef FORMAT2
04595 }
04596 
04597 /* JDG: callback to display iax peers in manager */
04598 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04599 {
04600    char *a[] = { "iax2", "show", "users" };
04601    int ret;
04602    const char *id = astman_get_header(m,"ActionID");
04603 
04604    if (!ast_strlen_zero(id))
04605       astman_append(s, "ActionID: %s\r\n",id);
04606    ret = __iax2_show_peers(1, -1, s, 3, a );
04607    astman_append(s, "\r\n\r\n" );
04608    return ret;
04609 } /* /JDG */
04610 
04611 static char *regstate2str(int regstate)
04612 {
04613    switch(regstate) {
04614    case REG_STATE_UNREGISTERED:
04615       return "Unregistered";
04616    case REG_STATE_REGSENT:
04617       return "Request Sent";
04618    case REG_STATE_AUTHSENT:
04619       return "Auth. Sent";
04620    case REG_STATE_REGISTERED:
04621       return "Registered";
04622    case REG_STATE_REJECTED:
04623       return "Rejected";
04624    case REG_STATE_TIMEOUT:
04625       return "Timeout";
04626    case REG_STATE_NOAUTH:
04627       return "No Authentication";
04628    default:
04629       return "Unknown";
04630    }
04631 }
04632 
04633 static int iax2_show_registry(int fd, int argc, char *argv[])
04634 {
04635 #define FORMAT2 "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8.8s  %s\n"
04636 #define FORMAT  "%-20.20s  %-6.6s  %-10.10s  %-20.20s %8d  %s\n"
04637    struct iax2_registry *reg = NULL;
04638 
04639    char host[80];
04640    char perceived[80];
04641    if (argc != 3)
04642       return RESULT_SHOWUSAGE;
04643    ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04644    AST_LIST_LOCK(&registrations);
04645    AST_LIST_TRAVERSE(&registrations, reg, entry) {
04646       snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04647       if (reg->us.sin_addr.s_addr) 
04648          snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04649       else
04650          ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04651       ast_cli(fd, FORMAT, host, 
04652                (reg->dnsmgr) ? "Y" : "N", 
04653                reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04654    }
04655    AST_LIST_UNLOCK(&registrations);
04656    return RESULT_SUCCESS;
04657 #undef FORMAT
04658 #undef FORMAT2
04659 }
04660 
04661 static int iax2_show_channels(int fd, int argc, char *argv[])
04662 {
04663 #define FORMAT2 "%-20.20s  %-15.15s  %-10.10s  %-11.11s  %-11.11s  %-7.7s  %-6.6s  %-6.6s  %s\n"
04664 #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"
04665 #define FORMATB "%-20.20s  %-15.15s  %-10.10s  %5.5d/%5.5d  %5.5d/%5.5d  [Native Bridged to ID=%5.5d]\n"
04666    int x;
04667    int numchans = 0;
04668 
04669    if (argc != 3)
04670       return RESULT_SHOWUSAGE;
04671    ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04672    for (x=0;x<IAX_MAX_CALLS;x++) {
04673       ast_mutex_lock(&iaxsl[x]);
04674       if (iaxs[x]) {
04675          int lag, jitter, localdelay;
04676          jb_info jbinfo;
04677          
04678          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04679             jb_getinfo(iaxs[x]->jb, &jbinfo);
04680             jitter = jbinfo.jitter;
04681             localdelay = jbinfo.current - jbinfo.min;
04682          } else {
04683             jitter = -1;
04684             localdelay = 0;
04685          }
04686          lag = iaxs[x]->remote_rr.delay;
04687          ast_cli(fd, FORMAT,
04688             iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04689             ast_inet_ntoa(iaxs[x]->addr.sin_addr), 
04690             S_OR(iaxs[x]->username, "(None)"),
04691             iaxs[x]->callno, iaxs[x]->peercallno,
04692             iaxs[x]->oseqno, iaxs[x]->iseqno,
04693             lag,
04694             jitter,
04695             localdelay,
04696             ast_getformatname(iaxs[x]->voiceformat) );
04697          numchans++;
04698       }
04699       ast_mutex_unlock(&iaxsl[x]);
04700    }
04701    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04702    return RESULT_SUCCESS;
04703 #undef FORMAT
04704 #undef FORMAT2
04705 #undef FORMATB
04706 }
04707 
04708 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04709 {
04710    int x;
04711    int numchans = 0;
04712    for (x=0;x<IAX_MAX_CALLS;x++) {
04713       ast_mutex_lock(&iaxsl[x]);
04714       if (iaxs[x]) {
04715          int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04716          char *fmt;
04717          jb_info jbinfo;
04718          
04719          if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04720             jb_getinfo(iaxs[x]->jb, &jbinfo);
04721             localjitter = jbinfo.jitter;
04722             localdelay = jbinfo.current - jbinfo.min;
04723             locallost = jbinfo.frames_lost;
04724             locallosspct = jbinfo.losspct/1000;
04725             localdropped = jbinfo.frames_dropped;
04726             localooo = jbinfo.frames_ooo;
04727          } else {
04728             localjitter = -1;
04729             localdelay = 0;
04730             locallost = -1;
04731             locallosspct = -1;
04732             localdropped = 0;
04733             localooo = -1;
04734          }
04735          if (limit_fmt)
04736             fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04737          else
04738             fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04739          if (s)
04740             
04741             astman_append(s, fmt,
04742                      iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04743                      iaxs[x]->pingtime,
04744                      localjitter, 
04745                      localdelay,
04746                      locallost,
04747                      locallosspct,
04748                      localdropped,
04749                      localooo,
04750                      iaxs[x]->frames_received/1000,
04751                      iaxs[x]->remote_rr.jitter,
04752                      iaxs[x]->remote_rr.delay,
04753                      iaxs[x]->remote_rr.losscnt,
04754                      iaxs[x]->remote_rr.losspct,
04755                      iaxs[x]->remote_rr.dropped,
04756                      iaxs[x]->remote_rr.ooo,
04757                      iaxs[x]->remote_rr.packets/1000);
04758          else
04759             ast_cli(fd, fmt,
04760                iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04761                iaxs[x]->pingtime,
04762                localjitter, 
04763                localdelay,
04764                locallost,
04765                locallosspct,
04766                localdropped,
04767                localooo,
04768                iaxs[x]->frames_received/1000,
04769                iaxs[x]->remote_rr.jitter,
04770                iaxs[x]->remote_rr.delay,
04771                iaxs[x]->remote_rr.losscnt,
04772                iaxs[x]->remote_rr.losspct,
04773                iaxs[x]->remote_rr.dropped,
04774                iaxs[x]->remote_rr.ooo,
04775                iaxs[x]->remote_rr.packets/1000
04776                );
04777          numchans++;
04778       }
04779       ast_mutex_unlock(&iaxsl[x]);
04780    }
04781    return numchans;
04782 }
04783 
04784 static int iax2_show_netstats(int fd, int argc, char *argv[])
04785 {
04786    int numchans = 0;
04787    if (argc != 3)
04788       return RESULT_SHOWUSAGE;
04789    ast_cli(fd, "                                -------- LOCAL ---------------------  -------- REMOTE --------------------\n");
04790    ast_cli(fd, "Channel                    RTT  Jit  Del  Lost   %%  Drop  OOO  Kpkts  Jit  Del  Lost   %%  Drop  OOO  Kpkts\n");
04791    numchans = ast_cli_netstats(NULL, fd, 1);
04792    ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04793    return RESULT_SUCCESS;
04794 }
04795 
04796 static int iax2_do_debug(int fd, int argc, char *argv[])
04797 {
04798    if (argc < 2 || argc > 3)
04799       return RESULT_SHOWUSAGE;
04800    iaxdebug = 1;
04801    ast_cli(fd, "IAX2 Debugging Enabled\n");
04802    return RESULT_SUCCESS;
04803 }
04804 
04805 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04806 {
04807    if (argc < 3 || argc > 4)
04808       return RESULT_SHOWUSAGE;
04809    iaxtrunkdebug = 1;
04810    ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04811    return RESULT_SUCCESS;
04812 }
04813 
04814 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04815 {
04816    if (argc < 3 || argc > 4)
04817       return RESULT_SHOWUSAGE;
04818    jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04819    ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04820    return RESULT_SUCCESS;
04821 }
04822 
04823 static int iax2_no_debug(int fd, int argc, char *argv[])
04824 {
04825    if (argc < 3 || argc > 4)
04826       return RESULT_SHOWUSAGE;
04827    iaxdebug = 0;
04828    ast_cli(fd, "IAX2 Debugging Disabled\n");
04829    return RESULT_SUCCESS;
04830 }
04831 
04832 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04833 {
04834    if (argc < 4 || argc > 5)
04835       return RESULT_SHOWUSAGE;
04836    iaxtrunkdebug = 0;
04837    ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04838    return RESULT_SUCCESS;
04839 }
04840 
04841 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04842 {
04843    if (argc < 4 || argc > 5)
04844       return RESULT_SHOWUSAGE;
04845    jb_setoutput(jb_error_output, jb_warning_output, NULL);
04846    jb_debug_output("\n");
04847    ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04848    return RESULT_SUCCESS;
04849 }
04850 
04851 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04852 {
04853    unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04854    int res = -1;
04855    ast_mutex_lock(&iaxsl[callno]);
04856    if (iaxs[callno]) {
04857    /* If there's an outstanding error, return failure now */
04858       if (!iaxs[callno]->error) {
04859          if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04860             res = 0;
04861             /* Don't waste bandwidth sending null frames */
04862          else if (f->frametype == AST_FRAME_NULL)
04863             res = 0;
04864          else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04865             res = 0;
04866          else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04867             res = 0;
04868          else
04869          /* Simple, just queue for transmission */
04870             res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04871       } else {
04872          if (option_debug)
04873             ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04874       }
04875    }
04876    /* If it's already gone, just return */
04877    ast_mutex_unlock(&iaxsl[callno]);
04878    return res;
04879 }
04880 
04881 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, 
04882       int now, int transfer, int final)
04883 {
04884    struct ast_frame f = { 0, };
04885 
04886    f.frametype = type;
04887    f.subclass = command;
04888    f.datalen = datalen;
04889    f.src = __FUNCTION__;
04890    f.data = (void *) data;
04891 
04892    return iax2_send(i, &f, ts, seqno, now, transfer, final);
04893 }
04894 
04895 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04896 {
04897    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04898 }
04899 
04900 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04901 {
04902    int res;
04903    ast_mutex_lock(&iaxsl[callno]);
04904    res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04905    ast_mutex_unlock(&iaxsl[callno]);
04906    return res;
04907 }
04908 
04909 /*!
04910  * \note Since this function calls iax2_predestroy() -> iax2_queue_hangup(),
04911  *       the pvt struct for the given call number may disappear during its 
04912  *       execution.
04913  */
04914 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)
04915 {
04916    int call_num = i->callno;
04917    /* It is assumed that the callno has already been locked */
04918    iax2_predestroy(i->callno);
04919    if (!iaxs[call_num])
04920       return -1;
04921    return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04922 }
04923 
04924 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)
04925 {
04926    return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04927 }
04928 
04929 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04930 {
04931    return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04932 }
04933 
04934 static int apply_context(struct iax2_context *con, const char *context)
04935 {
04936    while(con) {
04937       if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04938          return -1;
04939       con = con->next;
04940    }
04941    return 0;
04942 }
04943 
04944 
04945 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04946 {
04947    /* Start pessimistic */
04948    int res = -1;
04949    int version = 2;
04950    struct iax2_user *user = NULL, *best = NULL;
04951    int bestscore = 0;
04952    int gotcapability = 0;
04953    struct ast_variable *v = NULL, *tmpvar = NULL;
04954    struct ao2_iterator i;
04955 
04956    if (!iaxs[callno])
04957       return res;
04958    if (ies->called_number)
04959       ast_string_field_set(iaxs[callno], exten, ies->called_number);
04960    if (ies->calling_number) {
04961       ast_shrink_phone_number(ies->calling_number);
04962       ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
04963    }
04964    if (ies->calling_name)
04965       ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
04966    if (ies->calling_ani)
04967       ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
04968    if (ies->dnid)
04969       ast_string_field_set(iaxs[callno], dnid, ies->dnid);
04970    if (ies->rdnis)
04971       ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
04972    if (ies->called_context)
04973       ast_string_field_set(iaxs[callno], context, ies->called_context);
04974    if (ies->language)
04975       ast_string_field_set(iaxs[callno], language, ies->language);
04976    if (ies->username)
04977       ast_string_field_set(iaxs[callno], username, ies->username);
04978    if (ies->calling_ton > -1)
04979       iaxs[callno]->calling_ton = ies->calling_ton;
04980    if (ies->calling_tns > -1)
04981       iaxs[callno]->calling_tns = ies->calling_tns;
04982    if (ies->calling_pres > -1)
04983       iaxs[callno]->calling_pres = ies->calling_pres;
04984    if (ies->format)
04985       iaxs[callno]->peerformat = ies->format;
04986    if (ies->adsicpe)
04987       iaxs[callno]->peeradsicpe = ies->adsicpe;
04988    if (ies->capability) {
04989       gotcapability = 1;
04990       iaxs[callno]->peercapability = ies->capability;
04991    } 
04992    if (ies->version)
04993       version = ies->version;
04994 
04995    /* Use provided preferences until told otherwise for actual preferences */
04996    if(ies->codec_prefs) {
04997       ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04998       ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04999    }
05000 
05001    if (!gotcapability) 
05002       iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05003    if (version > IAX_PROTO_VERSION) {
05004       ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 
05005          ast_inet_ntoa(sin->sin_addr), version);
05006       return res;
05007    }
05008    /* Search the userlist for a compatible entry, and fill in the rest */
05009    i = ao2_iterator_init(users, 0);
05010    while ((user = ao2_iterator_next(&i))) {
05011       if ((ast_strlen_zero(iaxs[callno]->username) ||          /* No username specified */
05012          !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */
05013          && ast_apply_ha(user->ha, sin)   /* Access is permitted from this IP */
05014          && (ast_strlen_zero(iaxs[callno]->context) ||         /* No context specified */
05015               apply_context(user->contexts, iaxs[callno]->context))) {        /* Context is permitted */
05016          if (!ast_strlen_zero(iaxs[callno]->username)) {
05017             /* Exact match, stop right now. */
05018             if (best)
05019                user_unref(best);
05020             best = user;
05021             break;
05022          } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05023             /* No required authentication */
05024             if (user->ha) {
05025                /* There was host authentication and we passed, bonus! */
05026                if (bestscore < 4) {
05027                   bestscore = 4;
05028                   if (best)
05029                      user_unref(best);
05030                   best = user;
05031                   continue;
05032                }
05033             } else {
05034                /* No host access, but no secret, either, not bad */
05035                if (bestscore < 3) {
05036                   bestscore = 3;
05037                   if (best)
05038                      user_unref(best);
05039                   best = user;
05040                   continue;
05041                }
05042             }
05043          } else {
05044             if (user->ha) {
05045                /* Authentication, but host access too, eh, it's something.. */
05046                if (bestscore < 2) {
05047                   bestscore = 2;
05048                   if (best)
05049                      user_unref(best);
05050                   best = user;
05051                   continue;
05052                }
05053             } else {
05054                /* Authentication and no host access...  This is our baseline */
05055                if (bestscore < 1) {
05056                   bestscore = 1;
05057                   if (best)
05058                      user_unref(best);
05059                   best = user;
05060                   continue;
05061                }
05062             }
05063          }
05064       }
05065       user_unref(user);
05066    }
05067    user = best;
05068    if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05069       user = realtime_user(iaxs[callno]->username, sin);
05070       if (user && !ast_strlen_zero(iaxs[callno]->context) &&         /* No context specified */
05071           !apply_context(user->contexts, iaxs[callno]->context)) {      /* Context is permitted */
05072          user = user_unref(user);
05073       }
05074    }
05075    if (user) {
05076       /* We found our match (use the first) */
05077       /* copy vars */
05078       for (v = user->vars ; v ; v = v->next) {
05079          if((tmpvar = ast_variable_new(v->name, v->value))) {
05080             tmpvar->next = iaxs[callno]->vars; 
05081             iaxs[callno]->vars = tmpvar;
05082          }
05083       }
05084       /* If a max AUTHREQ restriction is in place, activate it */
05085       if (user->maxauthreq > 0)
05086          ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05087       iaxs[callno]->prefs = user->prefs;
05088       ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05089       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05090       ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05091       iaxs[callno]->encmethods = user->encmethods;
05092       /* Store the requested username if not specified */
05093       if (ast_strlen_zero(iaxs[callno]->username))
05094          ast_string_field_set(iaxs[callno], username, user->name);
05095       /* Store whether this is a trunked call, too, of course, and move if appropriate */
05096       ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05097       iaxs[callno]->capability = user->capability;
05098       /* And use the default context */
05099       if (ast_strlen_zero(iaxs[callno]->context)) {
05100          if (user->contexts)
05101             ast_string_field_set(iaxs[callno], context, user->contexts->context);
05102          else
05103             ast_string_field_set(iaxs[callno], context, context);
05104       }
05105       /* And any input keys */
05106       ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05107       /* And the permitted authentication methods */
05108       iaxs[callno]->authmethods = user->authmethods;
05109       iaxs[callno]->adsi = user->adsi;
05110       /* If they have callerid, override the given caller id.  Always store the ANI */
05111       if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05112          if (ast_test_flag(user, IAX_HASCALLERID)) {
05113             iaxs[callno]->calling_tns = 0;
05114             iaxs[callno]->calling_ton = 0;
05115             ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05116             ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05117             iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05118          }
05119          if (ast_strlen_zero(iaxs[callno]->ani))
05120             ast_string_field_set(iaxs[callno], ani, user->cid_num);
05121       } else {
05122          iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05123       }
05124       if (!ast_strlen_zero(user->accountcode))
05125          ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05126       if (!ast_strlen_zero(user->mohinterpret))
05127          ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05128       if (!ast_strlen_zero(user->mohsuggest))
05129          ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05130       if (user->amaflags)
05131          iaxs[callno]->amaflags = user->amaflags;
05132       if (!ast_strlen_zero(user->language))
05133          ast_string_field_set(iaxs[callno], language, user->language);
05134       ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);   
05135       /* Keep this check last */
05136       if (!ast_strlen_zero(user->dbsecret)) {
05137          char *family, *key=NULL;
05138          char buf[80];
05139          family = ast_strdupa(user->dbsecret);
05140          key = strchr(family, '/');
05141          if (key) {
05142             *key = '\0';
05143             key++;
05144          }
05145          if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05146             ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05147          else
05148             ast_string_field_set(iaxs[callno], secret, buf);
05149       } else
05150          ast_string_field_set(iaxs[callno], secret, user->secret);
05151       res = 0;
05152       user = user_unref(user);
05153    }
05154    ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);  
05155    return res;
05156 }
05157 
05158 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05159 {
05160    struct ast_iax2_full_hdr fh;
05161    fh.scallno = htons(src | IAX_FLAG_FULL);
05162    fh.dcallno = htons(dst);
05163    fh.ts = 0;
05164    fh.oseqno = 0;
05165    fh.iseqno = 0;
05166    fh.type = AST_FRAME_IAX;
05167    fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05168    if (iaxdebug)
05169        iax_showframe(NULL, &fh, 0, sin, 0);
05170    if (option_debug)
05171       ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05172          ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05173    return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05174 }
05175 
05176 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05177 {
05178    /* Select exactly one common encryption if there are any */
05179    p->encmethods &= enc;
05180    if (p->encmethods) {
05181       if (p->encmethods & IAX_ENCRYPT_AES128)
05182          p->encmethods = IAX_ENCRYPT_AES128;
05183       else
05184          p->encmethods = 0;
05185    }
05186 }
05187 
05188 /*!
05189  * \pre iaxsl[call_num] is locked
05190  *
05191  * \note Since this function calls send_command_final(), the pvt struct for the given
05192  *       call number may disappear while executing this function.
05193  */
05194 static int authenticate_request(int call_num)
05195 {
05196    struct iax_ie_data ied;
05197    int res = -1, authreq_restrict = 0;
05198    char challenge[10];
05199    struct chan_iax2_pvt *p = iaxs[call_num];
05200 
05201    memset(&ied, 0, sizeof(ied));
05202 
05203    /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */
05204    if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05205       struct iax2_user *user, tmp_user = {
05206          .name = p->username, 
05207       };
05208 
05209       user = ao2_find(users, &tmp_user, OBJ_POINTER);
05210       if (user) {
05211          if (user->curauthreq == user->maxauthreq)
05212             authreq_restrict = 1;
05213          else
05214             user->curauthreq++;
05215          user = user_unref(user);
05216       }
05217    }
05218 
05219    /* If the AUTHREQ limit test failed, send back an error */
05220    if (authreq_restrict) {
05221       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05222       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05223       send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05224       return 0;
05225    }
05226 
05227    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05228    if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05229       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05230       ast_string_field_set(p, challenge, challenge);
05231       /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */
05232       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05233    }
05234    if (p->encmethods)
05235       iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05236 
05237    iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05238 
05239    res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05240 
05241    if (p->encmethods)
05242       ast_set_flag(p, IAX_ENCRYPTED);
05243 
05244    return res;
05245 }
05246 
05247 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05248 {
05249    char requeststr[256];
05250    char md5secret[256] = "";
05251    char secret[256] = "";
05252    char rsasecret[256] = "";
05253    int res = -1; 
05254    int x;
05255    struct iax2_user *user, tmp_user = {
05256       .name = p->username, 
05257    };
05258 
05259    user = ao2_find(users, &tmp_user, OBJ_POINTER);
05260    if (user) {
05261       if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05262          ast_atomic_fetchadd_int(&user->curauthreq, -1);
05263          ast_clear_flag(p, IAX_MAXAUTHREQ);
05264       }
05265       ast_string_field_set(p, host, user->name);
05266       user = user_unref(user);
05267    }
05268 
05269    if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05270       return res;
05271    if (ies->password)
05272       ast_copy_string(secret, ies->password, sizeof(secret));
05273    if (ies->md5_result)
05274       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05275    if (ies->rsa_result)
05276       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05277    if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05278       struct ast_key *key;
05279       char *keyn;
05280       char tmpkey[256];
05281       char *stringp=NULL;
05282       ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05283       stringp=tmpkey;
05284       keyn = strsep(&stringp, ":");
05285       while(keyn) {
05286          key = ast_key_get(keyn, AST_KEY_PUBLIC);
05287          if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05288             res = 0;
05289             break;
05290          } else if (!key)
05291             ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05292          keyn = strsep(&stringp, ":");
05293       }
05294    } else if (p->authmethods & IAX_AUTH_MD5) {
05295       struct MD5Context md5;
05296       unsigned char digest[16];
05297       char *tmppw, *stringp;
05298       
05299       tmppw = ast_strdupa(p->secret);
05300       stringp = tmppw;
05301       while((tmppw = strsep(&stringp, ";"))) {
05302          MD5Init(&md5);
05303          MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05304          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05305          MD5Final(digest, &md5);
05306          /* If they support md5, authenticate with it.  */
05307          for (x=0;x<16;x++)
05308             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05309          if (!strcasecmp(requeststr, md5secret)) {
05310             res = 0;
05311             break;
05312          }
05313       }
05314    } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05315       if (!strcmp(secret, p->secret))
05316          res = 0;
05317    }
05318    return res;
05319 }
05320 
05321 /*! \brief Verify inbound registration */
05322 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05323 {
05324    char requeststr[256] = "";
05325    char peer[256] = "";
05326    char md5secret[256] = "";
05327    char rsasecret[256] = "";
05328    char secret[256] = "";
05329    struct iax2_peer *p = NULL;
05330    struct ast_key *key;
05331    char *keyn;
05332    int x;
05333    int expire = 0;
05334    int res = -1;
05335 
05336    ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05337    /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */
05338    if (ies->username)
05339       ast_copy_string(peer, ies->username, sizeof(peer));
05340    if (ies->password)
05341       ast_copy_string(secret, ies->password, sizeof(secret));
05342    if (ies->md5_result)
05343       ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05344    if (ies->rsa_result)
05345       ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05346    if (ies->refresh)
05347       expire = ies->refresh;
05348 
05349    if (ast_strlen_zero(peer)) {
05350       ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05351       return -1;
05352    }
05353 
05354    /* SLD: first call to lookup peer during registration */
05355    ast_mutex_unlock(&iaxsl[callno]);
05356    p = find_peer(peer, 1);
05357    ast_mutex_lock(&iaxsl[callno]);
05358    if (!p || !iaxs[callno]) {
05359       if (authdebug && !p)
05360          ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05361       goto return_unref;
05362    }
05363 
05364    if (!ast_test_flag(p, IAX_DYNAMIC)) {
05365       if (authdebug)
05366          ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05367       goto return_unref;
05368    }
05369 
05370    if (!ast_apply_ha(p->ha, sin)) {
05371       if (authdebug)
05372          ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05373       goto return_unref;
05374    }
05375    if (!inaddrcmp(&p->addr, sin))
05376       ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05377    ast_string_field_set(iaxs[callno], secret, p->secret);
05378    ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05379    /* Check secret against what we have on file */
05380    if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05381       if (!ast_strlen_zero(p->inkeys)) {
05382          char tmpkeys[256];
05383          char *stringp=NULL;
05384          ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05385          stringp=tmpkeys;
05386          keyn = strsep(&stringp, ":");
05387          while(keyn) {
05388             key = ast_key_get(keyn, AST_KEY_PUBLIC);
05389             if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05390                ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05391                break;
05392             } else if (!key) 
05393                ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05394             keyn = strsep(&stringp, ":");
05395          }
05396          if (!keyn) {
05397             if (authdebug)
05398                ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05399             goto return_unref;
05400          }
05401       } else {
05402          if (authdebug)
05403             ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05404          goto return_unref;
05405       }
05406    } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05407       struct MD5Context md5;
05408       unsigned char digest[16];
05409       char *tmppw, *stringp;
05410       
05411       tmppw = ast_strdupa(p->secret);
05412       stringp = tmppw;
05413       while((tmppw = strsep(&stringp, ";"))) {
05414          MD5Init(&md5);
05415          MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05416          MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05417          MD5Final(digest, &md5);
05418          for (x=0;x<16;x++)
05419             sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */
05420          if (!strcasecmp(requeststr, md5secret)) 
05421             break;
05422       }
05423       if (tmppw) {
05424          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05425       } else {
05426          if (authdebug)
05427             ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05428          goto return_unref;
05429       }
05430    } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05431       /* They've provided a plain text password and we support that */
05432       if (strcmp(secret, p->secret)) {
05433          if (authdebug)
05434             ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05435          goto return_unref;
05436       } else
05437          ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05438    } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05439       if (authdebug)
05440          ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05441       goto return_unref;
05442    }
05443    ast_string_field_set(iaxs[callno], peer, peer);
05444    /* Choose lowest expiry number */
05445    if (expire && (expire < iaxs[callno]->expiry)) 
05446       iaxs[callno]->expiry = expire;
05447 
05448    ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05449 
05450    res = 0;
05451 
05452 return_unref:
05453    if (p)
05454       peer_unref(p);
05455 
05456    return res;
05457 }
05458 
05459 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05460 {
05461    int res = -1;
05462    int x;
05463    if (!ast_strlen_zero(keyn)) {
05464       if (!(authmethods & IAX_AUTH_RSA)) {
05465          if (ast_strlen_zero(secret)) 
05466             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));
05467       } else if (ast_strlen_zero(challenge)) {
05468          ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05469       } else {
05470          char sig[256];
05471          struct ast_key *key;
05472          key = ast_key_get(keyn, AST_KEY_PRIVATE);
05473          if (!key) {
05474             ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05475          } else {
05476             if (ast_sign(key, (char*)challenge, sig)) {
05477                ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05478                res = -1;
05479             } else {
05480                iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05481                res = 0;
05482             }
05483          }
05484       }
05485    } 
05486    /* Fall back */
05487    if (res && !ast_strlen_zero(secret)) {
05488       if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05489          struct MD5Context md5;
05490          unsigned char digest[16];
05491          char digres[128];
05492          MD5Init(&md5);
05493          MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05494          MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05495          MD5Final(digest, &md5);
05496          /* If they support md5, authenticate with it.  */
05497          for (x=0;x<16;x++)
05498             sprintf(digres + (x << 1),  "%2.2x", digest[x]); /* safe */
05499          if (ecx && dcx)
05500             build_enc_keys(digest, ecx, dcx);
05501          iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05502          res = 0;
05503       } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05504          iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05505          res = 0;
05506       } else
05507          ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05508    }
05509    return res;
05510 }
05511 
05512 /*!
05513  * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
05514  *       so do not call this function with a pvt lock held.
05515  */
05516 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05517 {
05518    struct iax2_peer *peer = NULL;
05519    /* Start pessimistic */
05520    int res = -1;
05521    int authmethods = 0;
05522    struct iax_ie_data ied;
05523    uint16_t callno = p->callno;
05524 
05525    memset(&ied, 0, sizeof(ied));
05526    
05527    if (ies->username)
05528       ast_string_field_set(p, username, ies->username);
05529    if (ies->challenge)
05530       ast_string_field_set(p, challenge, ies->challenge);
05531    if (ies->authmethods)
05532       authmethods = ies->authmethods;
05533    if (authmethods & IAX_AUTH_MD5)
05534       merge_encryption(p, ies->encmethods);
05535    else
05536       p->encmethods = 0;
05537 
05538    /* Check for override RSA authentication first */
05539    if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05540       /* Normal password authentication */
05541       res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05542    } else {
05543       struct ao2_iterator i = ao2_iterator_init(peers, 0);
05544       while ((peer = ao2_iterator_next(&i))) {
05545          if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 
05546              /* No peer specified at our end, or this is the peer */
05547              && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05548              /* No username specified in peer rule, or this is the right username */
05549              && (!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)))
05550              /* No specified host, or this is our host */
05551             ) {
05552             res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05553             if (!res) {
05554                peer_unref(peer);
05555                break;
05556             }
05557          }
05558          peer_unref(peer);
05559       }
05560       if (!peer) {
05561          /* We checked our list and didn't find one.  It's unlikely, but possible, 
05562             that we're trying to authenticate *to* a realtime peer */
05563          const char *peer_name = ast_strdupa(p->peer);
05564          ast_mutex_unlock(&iaxsl[callno]);
05565          if ((peer = realtime_peer(peer_name, NULL))) {
05566             ast_mutex_lock(&iaxsl[callno]);
05567             if (!(p = iaxs[callno])) {
05568                peer_unref(peer);
05569                return -1;
05570             }
05571             res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05572             peer_unref(peer);
05573          }
05574          if (!peer) {
05575             ast_mutex_lock(&iaxsl[callno]);
05576             if (!(p = iaxs[callno]))
05577                return -1;
05578          }
05579       }
05580    }
05581    if (ies->encmethods)
05582       ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05583    if (!res)
05584       res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05585    return res;
05586 }
05587 
05588 static int iax2_do_register(struct iax2_registry *reg);
05589 
05590 static void __iax2_do_register_s(const void *data)
05591 {
05592    struct iax2_registry *reg = (struct iax2_registry *)data;
05593    reg->expire = -1;
05594    iax2_do_register(reg);
05595 }
05596 
05597 static int iax2_do_register_s(const void *data)
05598 {
05599 #ifdef SCHED_MULTITHREADED
05600    if (schedule_action(__iax2_do_register_s, data))
05601 #endif      
05602       __iax2_do_register_s(data);
05603    return 0;
05604 }
05605 
05606 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05607 {
05608    int newcall = 0;
05609    char newip[256];
05610    struct iax_ie_data ied;
05611    struct sockaddr_in new;
05612    
05613    
05614    memset(&ied, 0, sizeof(ied));
05615    if (ies->apparent_addr)
05616       bcopy(ies->apparent_addr, &new, sizeof(new));
05617    if (ies->callno)
05618       newcall = ies->callno;
05619    if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05620       ast_log(LOG_WARNING, "Invalid transfer request\n");
05621       return -1;
05622    }
05623    pvt->transfercallno = newcall;
05624    memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05625    inet_aton(newip, &pvt->transfer.sin_addr);
05626    pvt->transfer.sin_family = AF_INET;
05627    pvt->transferring = TRANSFER_BEGIN;
05628    pvt->transferid = ies->transferid;
05629    if (ies->transferid)
05630       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05631    send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05632    return 0; 
05633 }
05634 
05635 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05636 {
05637    char exten[256] = "";
05638    int status = CACHE_FLAG_UNKNOWN;
05639    int expiry = iaxdefaultdpcache;
05640    int x;
05641    int matchmore = 0;
05642    struct iax2_dpcache *dp, *prev;
05643    
05644    if (ies->called_number)
05645       ast_copy_string(exten, ies->called_number, sizeof(exten));
05646 
05647    if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05648       status = CACHE_FLAG_EXISTS;
05649    else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05650       status = CACHE_FLAG_CANEXIST;
05651    else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05652       status = CACHE_FLAG_NONEXISTENT;
05653 
05654    if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05655       /* Don't really do anything with this */
05656    }
05657    if (ies->refresh)
05658       expiry = ies->refresh;
05659    if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05660       matchmore = CACHE_FLAG_MATCHMORE;
05661    ast_mutex_lock(&dpcache_lock);
05662    prev = NULL;
05663    dp = pvt->dpentries;
05664    while(dp) {
05665       if (!strcmp(dp->exten, exten)) {
05666          /* Let them go */
05667          if (prev)
05668             prev->peer = dp->peer;
05669          else
05670             pvt->dpentries = dp->peer;
05671          dp->peer = NULL;
05672          dp->callno = 0;
05673          dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05674          if (dp->flags & CACHE_FLAG_PENDING) {
05675             dp->flags &= ~CACHE_FLAG_PENDING;
05676             dp->flags |= status;
05677             dp->flags |= matchmore;
05678          }
05679          /* Wake up waiters */
05680          for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05681             if (dp->waiters[x] > -1)
05682                write(dp->waiters[x], "asdf", 4);
05683       }
05684       prev = dp;
05685       dp = dp->peer;
05686    }
05687    ast_mutex_unlock(&dpcache_lock);
05688    return 0;
05689 }
05690 
05691 static int complete_transfer(int callno, struct iax_ies *ies)
05692 {
05693    int peercallno = 0;
05694    struct chan_iax2_pvt *pvt = iaxs[callno];
05695    struct iax_frame *cur;
05696    jb_frame frame;
05697 
05698    if (ies->callno)
05699       peercallno = ies->callno;
05700 
05701    if (peercallno < 1) {
05702       ast_log(LOG_WARNING, "Invalid transfer request\n");
05703       return -1;
05704    }
05705    memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05706    memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05707    /* Reset sequence numbers */
05708    pvt->oseqno = 0;
05709    pvt->rseqno = 0;
05710    pvt->iseqno = 0;
05711    pvt->aseqno = 0;
05712    pvt->peercallno = peercallno;
05713    pvt->transferring = TRANSFER_NONE;
05714    pvt->svoiceformat = -1;
05715    pvt->voiceformat = 0;
05716    pvt->svideoformat = -1;
05717    pvt->videoformat = 0;
05718    pvt->transfercallno = -1;
05719    memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05720    memset(&pvt->offset, 0, sizeof(pvt->offset));
05721    /* reset jitterbuffer */
05722    while(jb_getall(pvt->jb,&frame) == JB_OK)
05723       iax2_frame_free(frame.data);
05724    jb_reset(pvt->jb);
05725    pvt->lag = 0;
05726    pvt->last = 0;
05727    pvt->lastsent = 0;
05728    pvt->nextpred = 0;
05729    pvt->pingtime = DEFAULT_RETRY_TIME;
05730    AST_LIST_LOCK(&iaxq.queue);
05731    AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05732       /* We must cancel any packets that would have been transmitted
05733          because now we're talking to someone new.  It's okay, they
05734          were transmitted to someone that didn't care anyway. */
05735       if (callno == cur->callno) 
05736          cur->retries = -1;
05737    }
05738    AST_LIST_UNLOCK(&iaxq.queue);
05739    return 0; 
05740 }
05741 
05742 /*! \brief Acknowledgment received for OUR registration */
05743 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05744 {
05745    struct iax2_registry *reg;
05746    /* Start pessimistic */
05747    char peer[256] = "";
05748    char msgstatus[60];
05749    int refresh = 60;
05750    char ourip[256] = "<Unspecified>";
05751    struct sockaddr_in oldus;
05752    struct sockaddr_in us;
05753    int oldmsgs;
05754 
05755    memset(&us, 0, sizeof(us));
05756    if (ies->apparent_addr)
05757       bcopy(ies->apparent_addr, &us, sizeof(us));
05758    if (ies->username)
05759       ast_copy_string(peer, ies->username, sizeof(peer));
05760    if (ies->refresh)
05761       refresh = ies->refresh;
05762    if (ies->calling_number) {
05763       /* We don't do anything with it really, but maybe we should */
05764    }
05765    reg = iaxs[callno]->reg;
05766    if (!reg) {
05767       ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05768       return -1;
05769    }
05770    memcpy(&oldus, &reg->us, sizeof(oldus));
05771    oldmsgs = reg->messages;
05772    if (inaddrcmp(&reg->addr, sin)) {
05773       ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05774       return -1;
05775    }
05776    memcpy(&reg->us, &us, sizeof(reg->us));
05777    if (ies->msgcount >= 0)
05778       reg->messages = ies->msgcount & 0xffff;      /* only low 16 bits are used in the transmission of the IE */
05779    /* always refresh the registration at the interval requested by the server
05780       we are registering to
05781    */
05782    reg->refresh = refresh;
05783    AST_SCHED_DEL(sched, reg->expire);
05784    reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05785    if (inaddrcmp(&oldus, &reg->us) || (reg->messages != oldmsgs)) {
05786       if (option_verbose > 2) {
05787          if (reg->messages > 255)
05788             snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05789          else if (reg->messages > 1)
05790             snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05791          else if (reg->messages > 0)
05792             snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05793          else
05794             snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05795          snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05796          ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05797       }
05798       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05799    }
05800    reg->regstate = REG_STATE_REGISTERED;
05801    return 0;
05802 }
05803 
05804 static int iax2_register(char *value, int lineno)
05805 {
05806    struct iax2_registry *reg;
05807    char copy[256];
05808    char *username, *hostname, *secret;
05809    char *porta;
05810    char *stringp=NULL;
05811    
05812    if (!value)
05813       return -1;
05814    ast_copy_string(copy, value, sizeof(copy));
05815    stringp=copy;
05816    username = strsep(&stringp, "@");
05817    hostname = strsep(&stringp, "@");
05818    if (!hostname) {
05819       ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05820       return -1;
05821    }
05822    stringp=username;
05823    username = strsep(&stringp, ":");
05824    secret = strsep(&stringp, ":");
05825    stringp=hostname;
05826    hostname = strsep(&stringp, ":");
05827    porta = strsep(&stringp, ":");
05828    
05829    if (porta && !atoi(porta)) {
05830       ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05831       return -1;
05832    }
05833    if (!(reg = ast_calloc(1, sizeof(*reg))))
05834       return -1;
05835    if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
05836       free(reg);
05837       return -1;
05838    }
05839    ast_copy_string(reg->username, username, sizeof(reg->username));
05840    if (secret)
05841       ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05842    reg->expire = -1;
05843    reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05844    reg->addr.sin_family = AF_INET;
05845    reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05846    AST_LIST_LOCK(&registrations);
05847    AST_LIST_INSERT_HEAD(&registrations, reg, entry);
05848    AST_LIST_UNLOCK(&registrations);
05849    
05850    return 0;
05851 }
05852 
05853 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05854 {
05855    char multi[256];
05856    char *stringp, *ext;
05857    if (!ast_strlen_zero(regcontext)) {
05858       ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
05859       stringp = multi;
05860       while((ext = strsep(&stringp, "&"))) {
05861          if (onoff) {
05862             if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05863                ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
05864                        "Noop", ast_strdup(peer->name), ast_free, "IAX2");
05865          } else
05866             ast_context_remove_extension(regcontext, ext, 1, NULL);
05867       }
05868    }
05869 }
05870 static void prune_peers(void);
05871 
05872 static void unlink_peer(struct iax2_peer *peer)
05873 {
05874    if (peer->expire > -1) {
05875       if (!ast_sched_del(sched, peer->expire)) {
05876          peer->expire = -1;
05877          peer_unref(peer);
05878       }
05879    }
05880 
05881    if (peer->pokeexpire > -1) {
05882       if (!ast_sched_del(sched, peer->pokeexpire)) {
05883          peer->pokeexpire = -1;
05884          peer_unref(peer);
05885       }
05886    }
05887 
05888    ao2_unlink(peers, peer);
05889 }
05890 
05891 static void __expire_registry(const void *data)
05892 {
05893    struct iax2_peer *peer = (struct iax2_peer *) data;
05894 
05895    if (!peer)
05896       return;
05897 
05898    peer->expire = -1;
05899 
05900    if (option_debug)
05901       ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
05902    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05903       realtime_update_peer(peer->name, &peer->addr, 0);
05904    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
05905    /* Reset the address */
05906    memset(&peer->addr, 0, sizeof(peer->addr));
05907    /* Reset expiry value */
05908    peer->expiry = min_reg_expire;
05909    if (!ast_test_flag(peer, IAX_TEMPONLY))
05910       ast_db_del("IAX/Registry", peer->name);
05911    register_peer_exten(peer, 0);
05912    ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
05913    if (iax2_regfunk)
05914       iax2_regfunk(peer->name, 0);
05915 
05916    if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
05917       unlink_peer(peer);
05918 
05919    peer_unref(peer);
05920 }
05921 
05922 static int expire_registry(const void *data)
05923 {
05924 #ifdef SCHED_MULTITHREADED
05925    if (schedule_action(__expire_registry, data))
05926 #endif      
05927       __expire_registry(data);
05928    return 0;
05929 }
05930 
05931 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05932 
05933 static void reg_source_db(struct iax2_peer *p)
05934 {
05935    char data[80];
05936    struct in_addr in;
05937    char *c, *d;
05938    if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05939       c = strchr(data, ':');
05940       if (c) {
05941          *c = '\0';
05942          c++;
05943          if (inet_aton(data, &in)) {
05944             d = strchr(c, ':');
05945             if (d) {
05946                *d = '\0';
05947                d++;
05948                if (option_verbose > 2)
05949                   ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name, 
05950                   ast_inet_ntoa(in), atoi(c), atoi(d));
05951                iax2_poke_peer(p, 0);
05952                p->expiry = atoi(d);
05953                memset(&p->addr, 0, sizeof(p->addr));
05954                p->addr.sin_family = AF_INET;
05955                p->addr.sin_addr = in;
05956                p->addr.sin_port = htons(atoi(c));
05957                if (p->expire > -1) {
05958                   if (!ast_sched_del(sched, p->expire)) {
05959                      p->expire = -1;
05960                      peer_unref(p);
05961                   }
05962                }
05963                ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
05964                p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
05965                if (p->expire == -1)
05966                   peer_unref(p);
05967                if (iax2_regfunk)
05968                   iax2_regfunk(p->name, 1);
05969                register_peer_exten(p, 1);
05970             }              
05971                
05972          }
05973       }
05974    }
05975 }
05976 
05977 /*!
05978  * \pre iaxsl[callno] is locked
05979  *
05980  * \note Since this function calls send_command_final(), the pvt struct for
05981  *       the given call number may disappear while executing this function.
05982  */
05983 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05984 {
05985    /* Called from IAX thread only, with proper iaxsl lock */
05986    struct iax_ie_data ied;
05987    struct iax2_peer *p;
05988    int msgcount;
05989    char data[80];
05990    int version;
05991    const char *peer_name;
05992    int res = -1;
05993 
05994    memset(&ied, 0, sizeof(ied));
05995 
05996    peer_name = ast_strdupa(iaxs[callno]->peer);
05997 
05998    /* SLD: Another find_peer call during registration - this time when we are really updating our registration */
05999    ast_mutex_unlock(&iaxsl[callno]);
06000    if (!(p = find_peer(peer_name, 1))) {
06001       ast_mutex_lock(&iaxsl[callno]);
06002       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06003       return -1;
06004    }
06005    ast_mutex_lock(&iaxsl[callno]);
06006    if (!iaxs[callno])
06007       goto return_unref;
06008 
06009    if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06010       if (sin->sin_addr.s_addr) {
06011          time_t nowtime;
06012          time(&nowtime);
06013          realtime_update_peer(peer_name, sin, nowtime);
06014       } else {
06015          realtime_update_peer(peer_name, sin, 0);
06016       }
06017    }
06018    if (inaddrcmp(&p->addr, sin)) {
06019       if (iax2_regfunk)
06020          iax2_regfunk(p->name, 1);
06021       /* Stash the IP address from which they registered */
06022       memcpy(&p->addr, sin, sizeof(p->addr));
06023       snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06024       if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06025          ast_db_put("IAX/Registry", p->name, data);
06026          if  (option_verbose > 2)
06027             ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 
06028                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06029          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06030          register_peer_exten(p, 1);
06031          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06032       } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06033          if  (option_verbose > 2)
06034             ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name, 
06035                    ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06036          manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06037          register_peer_exten(p, 0);
06038          ast_db_del("IAX/Registry", p->name);
06039          ast_device_state_changed("IAX2/%s", p->name); /* Activate notification */
06040       }
06041       /* Update the host */
06042       /* Verify that the host is really there */
06043       iax2_poke_peer(p, callno);
06044    }     
06045 
06046    /* Make sure our call still exists, an INVAL at the right point may make it go away */
06047    if (!iaxs[callno]) {
06048       res = 0;
06049       goto return_unref;
06050    }
06051 
06052    /* Store socket fd */
06053    p->sockfd = fd;
06054    /* Setup the expiry */
06055    if (p->expire > -1) {
06056       if (!ast_sched_del(sched, p->expire)) {
06057          p->expire = -1;
06058          peer_unref(p);
06059       }
06060    }
06061    /* treat an unspecified refresh interval as the minimum */
06062    if (!refresh)
06063       refresh = min_reg_expire;
06064    if (refresh > max_reg_expire) {
06065       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06066          p->name, max_reg_expire, refresh);
06067       p->expiry = max_reg_expire;
06068    } else if (refresh < min_reg_expire) {
06069       ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06070          p->name, min_reg_expire, refresh);
06071       p->expiry = min_reg_expire;
06072    } else {
06073       p->expiry = refresh;
06074    }
06075    if (p->expiry && sin->sin_addr.s_addr) {
06076       p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06077       if (p->expire == -1)
06078          peer_unref(p);
06079    }
06080    iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06081    iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06082    if (sin->sin_addr.s_addr) {
06083       iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06084       iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06085       if (!ast_strlen_zero(p->mailbox)) {
06086          int new, old;
06087          ast_app_inboxcount(p->mailbox, &new, &old);
06088          if (new > 255)
06089             new = 255;
06090          if (old > 255)
06091             old = 255;
06092          msgcount = (old << 8) | new;
06093          iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06094       }
06095       if (ast_test_flag(p, IAX_HASCALLERID)) {
06096          iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06097          iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06098       }
06099    }
06100    version = iax_check_version(devtype);
06101    if (version) 
06102       iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06103 
06104    res = 0;
06105 
06106 return_unref:
06107    peer_unref(p);
06108 
06109    return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06110 }
06111 
06112 static int registry_authrequest(int callno)
06113 {
06114    struct iax_ie_data ied;
06115    struct iax2_peer *p;
06116    char challenge[10];
06117    const char *peer_name;
06118    int res = -1;
06119 
06120    peer_name = ast_strdupa(iaxs[callno]->peer);
06121 
06122    /* SLD: third call to find_peer in registration */
06123    ast_mutex_unlock(&iaxsl[callno]);
06124    p = find_peer(peer_name, 1);
06125    ast_mutex_lock(&iaxsl[callno]);
06126    if (!iaxs[callno])
06127       goto return_unref;
06128    if (!p) {
06129       ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06130       goto return_unref;
06131    }
06132    
06133    memset(&ied, 0, sizeof(ied));
06134    iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06135    if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06136       /* Build the challenge */
06137       snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06138       ast_string_field_set(iaxs[callno], challenge, challenge);
06139       iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06140    }
06141    iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06142 
06143    res = 0;
06144 
06145 return_unref:
06146    peer_unref(p);
06147 
06148    return res ? res : send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
06149 }
06150 
06151 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06152 {
06153    struct iax2_registry *reg;
06154    /* Start pessimistic */
06155    struct iax_ie_data ied;
06156    char peer[256] = "";
06157    char challenge[256] = "";
06158    int res;
06159    int authmethods = 0;
06160    if (ies->authmethods)
06161       authmethods = ies->authmethods;
06162    if (ies->username)
06163       ast_copy_string(peer, ies->username, sizeof(peer));
06164    if (ies->challenge)
06165       ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06166    memset(&ied, 0, sizeof(ied));
06167    reg = iaxs[callno]->reg;
06168    if (reg) {
06169          if (inaddrcmp(&reg->addr, sin)) {
06170             ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06171             return -1;
06172          }
06173          if (ast_strlen_zero(reg->secret)) {
06174             ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06175             reg->regstate = REG_STATE_NOAUTH;
06176             return -1;
06177          }
06178          iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06179          iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06180          if (reg->secret[0] == '[') {
06181             char tmpkey[256];
06182             ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06183             tmpkey[strlen(tmpkey) - 1] = '\0';
06184             res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06185          } else
06186             res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06187          if (!res) {
06188             reg->regstate = REG_STATE_AUTHSENT;
06189             return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06190          } else
06191             return -1;
06192          ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06193    } else   
06194       ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06195    return -1;
06196 }
06197 
06198 static void stop_stuff(int callno)
06199 {
06200    iax2_destroy_helper(iaxs[callno]);
06201 }
06202 
06203 static void __auth_reject(const void *nothing)
06204 {
06205    /* Called from IAX thread only, without iaxs lock */
06206    int callno = (int)(long)(nothing);
06207    struct iax_ie_data ied;
06208    ast_mutex_lock(&iaxsl[callno]);
06209    if (iaxs[callno]) {
06210       memset(&ied, 0, sizeof(ied));
06211       if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06212          iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06213          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06214       } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06215          iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06216          iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06217       }
06218       send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06219    }
06220    ast_mutex_unlock(&iaxsl[callno]);
06221 }
06222 
06223 static int auth_reject(const void *data)
06224 {
06225    int callno = (int)(long)(data);
06226    ast_mutex_lock(&iaxsl[callno]);
06227    if (iaxs[callno])
06228       iaxs[callno]->authid = -1;
06229    ast_mutex_unlock(&iaxsl[callno]);
06230 #ifdef SCHED_MULTITHREADED
06231    if (schedule_action(__auth_reject, data))
06232 #endif      
06233       __auth_reject(data);
06234    return 0;
06235 }
06236 
06237 static int auth_fail(int callno, int failcode)
06238 {
06239    /* Schedule sending the authentication failure in one second, to prevent
06240       guessing */
06241    if (iaxs[callno]) {
06242       iaxs[callno]->authfail = failcode;
06243       if (delayreject) {
06244          AST_SCHED_DEL(sched, iaxs[callno]->authid);
06245          iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06246       } else
06247          auth_reject((void *)(long)callno);
06248    }
06249    return 0;
06250 }
06251 
06252 static void __auto_hangup(const void *nothing)
06253 {
06254    /* Called from IAX thread only, without iaxs lock */
06255    int callno = (int)(long)(nothing);
06256    struct iax_ie_data ied;
06257    ast_mutex_lock(&iaxsl[callno]);
06258    if (iaxs[callno]) {
06259       memset(&ied, 0, sizeof(ied));
06260       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06261       iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06262       send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06263    }
06264    ast_mutex_unlock(&iaxsl[callno]);
06265 }
06266 
06267 static int auto_hangup(const void *data)
06268 {
06269    int callno = (int)(long)(data);
06270    ast_mutex_lock(&iaxsl[callno]);
06271    if (iaxs[callno]) {
06272       iaxs[callno]->autoid = -1;
06273    }
06274    ast_mutex_unlock(&iaxsl[callno]);
06275 #ifdef SCHED_MULTITHREADED
06276    if (schedule_action(__auto_hangup, data))
06277 #endif      
06278       __auto_hangup(data);
06279    return 0;
06280 }
06281 
06282 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06283 {
06284    struct iax_ie_data ied;
06285    /* Auto-hangup with 30 seconds of inactivity */
06286    AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06287    iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06288    memset(&ied, 0, sizeof(ied));
06289    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06290    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06291    dp->flags |= CACHE_FLAG_TRANSMITTED;
06292 }
06293 
06294 static int iax2_vnak(int callno)
06295 {
06296    return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06297 }
06298 
06299 static void vnak_retransmit(int callno, int last)
06300 {
06301    struct iax_frame *f;
06302 
06303    AST_LIST_LOCK(&iaxq.queue);
06304    AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06305       /* Send a copy immediately */
06306       if ((f->callno == callno) && iaxs[f->callno] &&
06307          ((unsigned char ) (f->oseqno - last) < 128) &&
06308          (f->retries >= 0)) {
06309          send_packet(f);
06310       }
06311    }
06312    AST_LIST_UNLOCK(&iaxq.queue);
06313 }
06314 
06315 static void __iax2_poke_peer_s(const void *data)
06316 {
06317    struct iax2_peer *peer = (struct iax2_peer *)data;
06318    iax2_poke_peer(peer, 0);
06319    peer_unref(peer);
06320 }
06321 
06322 static int iax2_poke_peer_s(const void *data)
06323 {
06324    struct iax2_peer *peer = (struct iax2_peer *)data;
06325    peer->pokeexpire = -1;
06326 #ifdef SCHED_MULTITHREADED
06327    if (schedule_action(__iax2_poke_peer_s, data))
06328 #endif      
06329       __iax2_poke_peer_s(data);
06330    return 0;
06331 }
06332 
06333 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06334 {
06335    int res = 0;
06336    struct iax_frame *fr;
06337    struct ast_iax2_meta_hdr *meta;
06338    struct ast_iax2_meta_trunk_hdr *mth;
06339    int calls = 0;
06340    
06341    /* Point to frame */
06342    fr = (struct iax_frame *)tpeer->trunkdata;
06343    /* Point to meta data */
06344    meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06345    mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06346    if (tpeer->trunkdatalen) {
06347       /* We're actually sending a frame, so fill the meta trunk header and meta header */
06348       meta->zeros = 0;
06349       meta->metacmd = IAX_META_TRUNK;
06350       if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06351          meta->cmddata = IAX_META_TRUNK_MINI;
06352       else
06353          meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06354       mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06355       /* And the rest of the ast_iax2 header */
06356       fr->direction = DIRECTION_OUTGRESS;
06357       fr->retrans = -1;
06358       fr->transfer = 0;
06359       /* Any appropriate call will do */
06360       fr->data = fr->afdata;
06361       fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06362       res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06363       calls = tpeer->calls;
06364 #if 0
06365       if (option_debug)
06366          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));
06367 #endif      
06368       /* Reset transmit trunk side data */
06369       tpeer->trunkdatalen = 0;
06370       tpeer->calls = 0;
06371    }
06372    if (res < 0)
06373       return res;
06374    return calls;
06375 }
06376 
06377 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06378 {
06379    /* Drop when trunk is about 5 seconds idle */
06380    if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 
06381       return 1;
06382    return 0;
06383 }
06384 
06385 static int timing_read(int *id, int fd, short events, void *cbdata)
06386 {
06387    char buf[1024];
06388    int res;
06389    struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06390    int processed = 0;
06391    int totalcalls = 0;
06392 #ifdef ZT_TIMERACK
06393    int x = 1;
06394 #endif
06395    struct timeval now;
06396    if (iaxtrunkdebug)
06397       ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06398    gettimeofday(&now, NULL);
06399    if (events & AST_IO_PRI) {
06400 #ifdef ZT_TIMERACK
06401       /* Great, this is a timing interface, just call the ioctl */
06402       if (ioctl(fd, ZT_TIMERACK, &x)) {
06403          ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06404          usleep(1);
06405          return -1;
06406       }
06407 #endif      
06408    } else {
06409       /* Read and ignore from the pseudo channel for timing */
06410       res = read(fd, buf, sizeof(buf));
06411       if (res < 1) {
06412          ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06413          return 1;
06414       }
06415    }
06416    /* For each peer that supports trunking... */
06417    ast_mutex_lock(&tpeerlock);
06418    tpeer = tpeers;
06419    while(tpeer) {
06420       processed++;
06421       res = 0;
06422       ast_mutex_lock(&tpeer->lock);
06423       /* We can drop a single tpeer per pass.  That makes all this logic
06424          substantially easier */
06425       if (!drop && iax2_trunk_expired(tpeer, &now)) {
06426          /* Take it out of the list, but don't free it yet, because it
06427             could be in use */
06428          if (prev)
06429             prev->next = tpeer->next;
06430          else
06431             tpeers = tpeer->next;
06432          drop = tpeer;
06433       } else {
06434          res = send_trunk(tpeer, &now);
06435          if (iaxtrunkdebug)
06436             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);
06437       }     
06438       totalcalls += res;   
06439       res = 0;
06440       ast_mutex_unlock(&tpeer->lock);
06441       prev = tpeer;
06442       tpeer = tpeer->next;
06443    }
06444    ast_mutex_unlock(&tpeerlock);
06445    if (drop) {
06446       ast_mutex_lock(&drop->lock);
06447       /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 
06448          because by the time they could get tpeerlock, we've already grabbed it */
06449       if (option_debug)
06450          ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06451       if (drop->trunkdata) {
06452          free(drop->trunkdata);
06453          drop->trunkdata = NULL;
06454       }
06455       ast_mutex_unlock(&drop->lock);
06456       ast_mutex_destroy(&drop->lock);
06457       free(drop);
06458       
06459    }
06460    if (iaxtrunkdebug)
06461       ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06462    iaxtrunkdebug =0;
06463    return 1;
06464 }
06465 
06466 struct dpreq_data {
06467    int callno;
06468    char context[AST_MAX_EXTENSION];
06469    char callednum[AST_MAX_EXTENSION];
06470    char *callerid;
06471 };
06472 
06473 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06474 {
06475    unsigned short dpstatus = 0;
06476    struct iax_ie_data ied1;
06477    int mm;
06478 
06479    memset(&ied1, 0, sizeof(ied1));
06480    mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06481    /* Must be started */
06482    if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06483       dpstatus = IAX_DPSTATUS_EXISTS;
06484    } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06485       dpstatus = IAX_DPSTATUS_CANEXIST;
06486    } else {
06487       dpstatus = IAX_DPSTATUS_NONEXISTENT;
06488    }
06489    if (ast_ignore_pattern(context, callednum))
06490       dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06491    if (mm)
06492       dpstatus |= IAX_DPSTATUS_MATCHMORE;
06493    if (!skiplock)
06494       ast_mutex_lock(&iaxsl[callno]);
06495    if (iaxs[callno]) {
06496       iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06497       iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06498       iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06499       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06500    }
06501    if (!skiplock)
06502       ast_mutex_unlock(&iaxsl[callno]);
06503 }
06504 
06505 static void *dp_lookup_thread(void *data)
06506 {
06507    /* Look up for dpreq */
06508    struct dpreq_data *dpr = data;
06509    dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06510    if (dpr->callerid)
06511       free(dpr->callerid);
06512    free(dpr);
06513    return NULL;
06514 }
06515 
06516 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06517 {
06518    pthread_t newthread;
06519    struct dpreq_data *dpr;
06520    pthread_attr_t attr;
06521    
06522    if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06523       return;
06524 
06525    pthread_attr_init(&attr);
06526    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
06527 
06528    dpr->callno = callno;
06529    ast_copy_string(dpr->context, context, sizeof(dpr->context));
06530    ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06531    if (callerid)
06532       dpr->callerid = ast_strdup(callerid);
06533    if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06534       ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06535    }
06536 
06537    pthread_attr_destroy(&attr);
06538 }
06539 
06540 struct iax_dual {
06541    struct ast_channel *chan1;
06542    struct ast_channel *chan2;
06543 };
06544 
06545 static void *iax_park_thread(void *stuff)
06546 {
06547    struct ast_channel *chan1, *chan2;
06548    struct iax_dual *d;
06549    struct ast_frame *f;
06550    int ext;
06551    int res;
06552    d = stuff;
06553    chan1 = d->chan1;
06554    chan2 = d->chan2;
06555    free(d);
06556    f = ast_read(chan1);
06557    if (f)
06558       ast_frfree(f);
06559    res = ast_park_call(chan1, chan2, 0, &ext);
06560    ast_hangup(chan2);
06561    ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06562    return NULL;
06563 }
06564 
06565 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06566 {
06567    struct iax_dual *d;
06568    struct ast_channel *chan1m, *chan2m;
06569    pthread_t th;
06570    chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06571    chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06572    if (chan2m && chan1m) {
06573       /* Make formats okay */
06574       chan1m->readformat = chan1->readformat;
06575       chan1m->writeformat = chan1->writeformat;
06576       ast_channel_masquerade(chan1m, chan1);
06577       /* Setup the extensions and such */
06578       ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06579       ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06580       chan1m->priority = chan1->priority;
06581       
06582       /* We make a clone of the peer channel too, so we can play
06583          back the announcement */
06584       /* Make formats okay */
06585       chan2m->readformat = chan2->readformat;
06586       chan2m->writeformat = chan2->writeformat;
06587       ast_channel_masquerade(chan2m, chan2);
06588       /* Setup the extensions and such */
06589       ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06590       ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06591       chan2m->priority = chan2->priority;
06592       if (ast_do_masquerade(chan2m)) {
06593          ast_log(LOG_WARNING, "Masquerade failed :(\n");
06594          ast_hangup(chan2m);
06595          return -1;
06596       }
06597    } else {
06598       if (chan1m)
06599          ast_hangup(chan1m);
06600       if (chan2m)
06601          ast_hangup(chan2m);
06602       return -1;
06603    }
06604    if ((d = ast_calloc(1, sizeof(*d)))) {
06605       pthread_attr_t attr;
06606 
06607       pthread_attr_init(&attr);
06608       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06609 
06610       d->chan1 = chan1m;
06611       d->chan2 = chan2m;
06612       if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06613          pthread_attr_destroy(&attr);
06614          return 0;
06615       }
06616       pthread_attr_destroy(&attr);
06617       free(d);
06618    }
06619    return -1;
06620 }
06621 
06622 
06623 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06624 
06625 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06626 {
06627    unsigned int ourver;
06628    char rsi[80];
06629    snprintf(rsi, sizeof(rsi), "si-%s", si);
06630    if (iax_provision_version(&ourver, rsi, 1))
06631       return 0;
06632    if (option_debug)
06633       ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06634    if (ourver != ver) 
06635       iax2_provision(sin, sockfd, NULL, rsi, 1);
06636    return 0;
06637 }
06638 
06639 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) 
06640 {
06641    jb_info stats;
06642    jb_getinfo(pvt->jb, &stats);
06643    
06644    memset(iep, 0, sizeof(*iep));
06645 
06646    iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06647    if(stats.frames_in == 0) stats.frames_in = 1;
06648    iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06649    iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06650    iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06651    iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06652    iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06653 }
06654 
06655 static void save_rr(struct iax_frame *fr, struct iax_ies *ies) 
06656 {
06657    iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06658    iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06659    iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06660    iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06661    iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06662    iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06663    iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06664 }
06665 
06666 static int socket_process(struct iax2_thread *thread);
06667 
06668 /*!
06669  * \brief Handle any deferred full frames for this thread
06670  */
06671 static void handle_deferred_full_frames(struct iax2_thread *thread)
06672 {
06673    struct iax2_pkt_buf *pkt_buf;
06674 
06675    ast_mutex_lock(&thread->lock);
06676 
06677    while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06678       ast_mutex_unlock(&thread->lock);
06679 
06680       thread->buf = pkt_buf->buf;
06681       thread->buf_len = pkt_buf->len;
06682       thread->buf_size = pkt_buf->len + 1;
06683       
06684       socket_process(thread);
06685 
06686       thread->buf = NULL;
06687       ast_free(pkt_buf);
06688 
06689       ast_mutex_lock(&thread->lock);
06690    }
06691 
06692    ast_mutex_unlock(&thread->lock);
06693 }
06694 
06695 /*!
06696  * \brief Queue the last read full frame for processing by a certain thread
06697  *
06698  * If there are already any full frames queued, they are sorted
06699  * by sequence number.
06700  */
06701 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06702 {
06703    struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06704    struct ast_iax2_full_hdr *fh, *cur_fh;
06705 
06706    if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06707       return;
06708 
06709    pkt_buf->len = from_here->buf_len;
06710    memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06711 
06712    fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06713    ast_mutex_lock(&to_here->lock);
06714    AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06715       cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06716       if (fh->oseqno < cur_fh->oseqno) {
06717          AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06718          break;
06719       }
06720    }
06721    AST_LIST_TRAVERSE_SAFE_END
06722 
06723    if (!cur_pkt_buf)
06724       AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06725    
06726    ast_mutex_unlock(&to_here->lock);
06727 }
06728 
06729 static int socket_read(int *id, int fd, short events, void *cbdata)
06730 {
06731    struct iax2_thread *thread;
06732    socklen_t len;
06733    time_t t;
06734    static time_t last_errtime = 0;
06735    struct ast_iax2_full_hdr *fh;
06736 
06737    if (!(thread = find_idle_thread())) {
06738       time(&t);
06739       if (t != last_errtime && option_debug)
06740          ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06741       last_errtime = t;
06742       usleep(1);
06743       return 1;
06744    }
06745 
06746    len = sizeof(thread->iosin);
06747    thread->iofd = fd;
06748    thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06749    thread->buf_size = sizeof(thread->readbuf);
06750    thread->buf = thread->readbuf;
06751    if (thread->buf_len < 0) {
06752       if (errno != ECONNREFUSED && errno != EAGAIN)
06753          ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06754       handle_error();
06755       thread->iostate = IAX_IOSTATE_IDLE;
06756       signal_condition(&thread->lock, &thread->cond);
06757       return 1;
06758    }
06759    if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
06760       thread->iostate = IAX_IOSTATE_IDLE;
06761       signal_condition(&thread->lock, &thread->cond);
06762       return 1;
06763    }
06764    
06765    /* Determine if this frame is a full frame; if so, and any thread is currently
06766       processing a full frame for the same callno from this peer, then drop this
06767       frame (and the peer will retransmit it) */
06768    fh = (struct ast_iax2_full_hdr *) thread->buf;
06769    if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06770       struct iax2_thread *cur = NULL;
06771       uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06772       
06773       AST_LIST_LOCK(&active_list);
06774       AST_LIST_TRAVERSE(&active_list, cur, list) {
06775          if ((cur->ffinfo.callno == callno) &&
06776              !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06777             break;
06778       }
06779       if (cur) {
06780          /* we found another thread processing a full frame for this call,
06781             so queue it up for processing later. */
06782          defer_full_frame(thread, cur);
06783          AST_LIST_UNLOCK(&active_list);
06784          thread->iostate = IAX_IOSTATE_IDLE;
06785          signal_condition(&thread->lock, &thread->cond);
06786          return 1;
06787       } else {
06788          /* this thread is going to process this frame, so mark it */
06789          thread->ffinfo.callno = callno;
06790          memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06791          thread->ffinfo.type = fh->type;
06792          thread->ffinfo.csub = fh->csub;
06793       }
06794       AST_LIST_UNLOCK(&active_list);
06795    }
06796    
06797    /* Mark as ready and send on its way */
06798    thread->iostate = IAX_IOSTATE_READY;
06799 #ifdef DEBUG_SCHED_MULTITHREAD
06800    ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06801 #endif
06802    signal_condition(&thread->lock, &thread->cond);
06803 
06804    return 1;
06805 }
06806 
06807 static int socket_process(struct iax2_thread *thread)
06808 {
06809    struct sockaddr_in sin;
06810    int res;
06811    int updatehistory=1;
06812    int new = NEW_PREVENT;
06813    void *ptr;
06814    int dcallno = 0;
06815    struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06816    struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06817    struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06818    struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06819    struct ast_iax2_meta_trunk_hdr *mth;
06820    struct ast_iax2_meta_trunk_entry *mte;
06821    struct ast_iax2_meta_trunk_mini *mtm;
06822    struct iax_frame *fr;
06823    struct iax_frame *cur;
06824    struct ast_frame f = { 0, };
06825    struct ast_channel *c;
06826    struct iax2_dpcache *dp;
06827    struct iax2_peer *peer;
06828    struct iax2_trunk_peer *tpeer;
06829    struct timeval rxtrunktime;
06830    struct iax_ies ies;
06831    struct iax_ie_data ied0, ied1;
06832    int format;
06833    int fd;
06834    int exists;
06835    int minivid = 0;
06836    unsigned int ts;
06837    char empty[32]="";      /* Safety measure */
06838    struct iax_frame *duped_fr;
06839    char host_pref_buf[128];
06840    char caller_pref_buf[128];
06841    struct ast_codec_pref pref;
06842    char *using_prefs = "mine";
06843 
06844    /* allocate an iax_frame with 4096 bytes of data buffer */
06845    fr = alloca(sizeof(*fr) + 4096);
06846    fr->callno = 0;
06847    fr->afdatalen = 4096; /* From alloca() above */
06848 
06849    /* Copy frequently used parameters to the stack */
06850    res = thread->buf_len;
06851    fd = thread->iofd;
06852    memcpy(&sin, &thread->iosin, sizeof(sin));
06853 
06854    if (res < sizeof(*mh)) {
06855       ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06856       return 1;
06857    }
06858    if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06859       if (res < sizeof(*vh)) {
06860          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));
06861          return 1;
06862       }
06863 
06864       /* This is a video frame, get call number */
06865       fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd);
06866       minivid = 1;
06867    } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06868       unsigned char metatype;
06869 
06870       if (res < sizeof(*meta)) {
06871          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));
06872          return 1;
06873       }
06874 
06875       /* This is a meta header */
06876       switch(meta->metacmd) {
06877       case IAX_META_TRUNK:
06878          if (res < (sizeof(*meta) + sizeof(*mth))) {
06879             ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06880                sizeof(*meta) + sizeof(*mth));
06881             return 1;
06882          }
06883          mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06884          ts = ntohl(mth->ts);
06885          metatype = meta->cmddata;
06886          res -= (sizeof(*meta) + sizeof(*mth));
06887          ptr = mth->data;
06888          tpeer = find_tpeer(&sin, fd);
06889          if (!tpeer) {
06890             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));
06891             return 1;
06892          }
06893          tpeer->trunkact = ast_tvnow();
06894          if (!ts || ast_tvzero(tpeer->rxtrunktime))
06895             tpeer->rxtrunktime = tpeer->trunkact;
06896          rxtrunktime = tpeer->rxtrunktime;
06897          ast_mutex_unlock(&tpeer->lock);
06898          while(res >= sizeof(*mte)) {
06899             /* Process channels */
06900             unsigned short callno, trunked_ts, len;
06901 
06902             if (metatype == IAX_META_TRUNK_MINI) {
06903                mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06904                ptr += sizeof(*mtm);
06905                res -= sizeof(*mtm);
06906                len = ntohs(mtm->len);
06907                callno = ntohs(mtm->mini.callno);
06908                trunked_ts = ntohs(mtm->mini.ts);
06909             } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06910                mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06911                ptr += sizeof(*mte);
06912                res -= sizeof(*mte);
06913                len = ntohs(mte->len);
06914                callno = ntohs(mte->callno);
06915                trunked_ts = 0;
06916             } else {
06917                ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06918                break;
06919             }
06920             /* Stop if we don't have enough data */
06921             if (len > res)
06922                break;
06923             fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd);
06924             if (fr->callno) {
06925                ast_mutex_lock(&iaxsl[fr->callno]);
06926                /* If it's a valid call, deliver the contents.  If not, we
06927                   drop it, since we don't have a scallno to use for an INVAL */
06928                /* Process as a mini frame */
06929                memset(&f, 0, sizeof(f));
06930                f.frametype = AST_FRAME_VOICE;
06931                if (iaxs[fr->callno]) {
06932                   if (iaxs[fr->callno]->voiceformat > 0) {
06933                      f.subclass = iaxs[fr->callno]->voiceformat;
06934                      f.datalen = len;
06935                      if (f.datalen >= 0) {
06936                         if (f.datalen)
06937                            f.data = ptr;
06938                         if(trunked_ts) {
06939                            fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06940                         } else
06941                            fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06942                         /* Don't pass any packets until we're started */
06943                         if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06944                            /* Common things */
06945                            f.src = "IAX2";
06946                            if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 
06947                               f.samples = ast_codec_get_samples(&f);
06948                            iax_frame_wrap(fr, &f);
06949                            duped_fr = iaxfrdup2(fr);
06950                            if (duped_fr) {
06951                               schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06952                            }
06953                            /* It is possible for the pvt structure to go away after we call schedule_delivery */
06954                            if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
06955                               iaxs[fr->callno]->last = fr->ts;
06956 #if 1
06957                               if (option_debug && iaxdebug)
06958                                  ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06959 #endif
06960                            }
06961                         }
06962                      } else {
06963                         ast_log(LOG_WARNING, "Datalen < 0?\n");
06964                      }
06965                   } else {
06966                      ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06967                      iax2_vnak(fr->callno);
06968                   }
06969                }
06970                ast_mutex_unlock(&iaxsl[fr->callno]);
06971             }
06972             ptr += len;
06973             res -= len;
06974          }
06975          
06976       }
06977       return 1;
06978    }
06979 
06980 #ifdef DEBUG_SUPPORT
06981    if (iaxdebug && (res >= sizeof(*fh)))
06982       iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06983 #endif
06984    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06985       if (res < sizeof(*fh)) {
06986          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));
06987          return 1;
06988       }
06989 
06990       /* Get the destination call number */
06991       dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06992       /* Retrieve the type and subclass */
06993       f.frametype = fh->type;
06994       if (f.frametype == AST_FRAME_VIDEO) {
06995          f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06996       } else {
06997          f.subclass = uncompress_subclass(fh->csub);
06998       }
06999       if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07000                          (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07001                          (f.subclass == IAX_COMMAND_REGREL)))
07002          new = NEW_ALLOW;
07003    } else {
07004       /* Don't know anything about it yet */
07005       f.frametype = AST_FRAME_NULL;
07006       f.subclass = 0;
07007    }
07008 
07009    if (!fr->callno)
07010       fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd);
07011 
07012    if (fr->callno > 0)
07013       ast_mutex_lock(&iaxsl[fr->callno]);
07014 
07015    if (!fr->callno || !iaxs[fr->callno]) {
07016       /* A call arrived for a nonexistent destination.  Unless it's an "inval"
07017          frame, reply with an inval */
07018       if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07019          /* We can only raw hangup control frames */
07020          if (((f.subclass != IAX_COMMAND_INVAL) &&
07021              (f.subclass != IAX_COMMAND_TXCNT) &&
07022              (f.subclass != IAX_COMMAND_TXACC) &&
07023              (f.subclass != IAX_COMMAND_FWDOWNL))||
07024              (f.frametype != AST_FRAME_IAX))
07025             raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07026             fd);
07027       }
07028       if (fr->callno > 0) 
07029          ast_mutex_unlock(&iaxsl[fr->callno]);
07030       return 1;
07031    }
07032    if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07033       if (decrypt_frame(fr->callno, fh, &f, &res)) {
07034          ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07035          ast_mutex_unlock(&iaxsl[fr->callno]);
07036          return 1;
07037       }
07038 #ifdef DEBUG_SUPPORT
07039       else if (iaxdebug)
07040          iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07041 #endif
07042    }
07043 
07044    /* count this frame */
07045    iaxs[fr->callno]->frames_received++;
07046 
07047    if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07048       f.subclass != IAX_COMMAND_TXCNT &&     /* for attended transfer */
07049       f.subclass != IAX_COMMAND_TXACC)    /* for attended transfer */
07050       iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
07051    if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07052       if (option_debug  && iaxdebug)
07053          ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07054       /* Check if it's out of order (and not an ACK or INVAL) */
07055       fr->oseqno = fh->oseqno;
07056       fr->iseqno = fh->iseqno;
07057       fr->ts = ntohl(fh->ts);
07058 #ifdef IAXTESTS
07059       if (test_resync) {
07060          if (option_debug)
07061             ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07062          fr->ts += test_resync;
07063       }
07064 #endif /* IAXTESTS */
07065 #if 0
07066       if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07067            ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07068                         (f.subclass == IAX_COMMAND_NEW ||
07069                          f.subclass == IAX_COMMAND_AUTHREQ ||
07070                          f.subclass == IAX_COMMAND_ACCEPT ||
07071                          f.subclass == IAX_COMMAND_REJECT))      ) )
07072 #endif
07073       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07074          updatehistory = 0;
07075       if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07076          (iaxs[fr->callno]->iseqno ||
07077             ((f.subclass != IAX_COMMAND_TXCNT) &&
07078             (f.subclass != IAX_COMMAND_TXREADY) &&    /* for attended transfer */
07079             (f.subclass != IAX_COMMAND_TXREL) &&      /* for attended transfer */
07080             (f.subclass != IAX_COMMAND_UNQUELCH ) &&  /* for attended transfer */
07081             (f.subclass != IAX_COMMAND_TXACC)) ||
07082             (f.frametype != AST_FRAME_IAX))) {
07083          if (
07084           ((f.subclass != IAX_COMMAND_ACK) &&
07085            (f.subclass != IAX_COMMAND_INVAL) &&
07086            (f.subclass != IAX_COMMAND_TXCNT) &&
07087            (f.subclass != IAX_COMMAND_TXREADY) &&     /* for attended transfer */
07088            (f.subclass != IAX_COMMAND_TXREL) &&    /* for attended transfer */
07089            (f.subclass != IAX_COMMAND_UNQUELCH ) &&   /* for attended transfer */
07090            (f.subclass != IAX_COMMAND_TXACC) &&
07091            (f.subclass != IAX_COMMAND_VNAK)) ||
07092            (f.frametype != AST_FRAME_IAX)) {
07093             /* If it's not an ACK packet, it's out of order. */
07094             if (option_debug)
07095                ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 
07096                   iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07097             /* Check to see if we need to request retransmission,
07098              * and take sequence number wraparound into account */
07099             if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07100                /* If we've already seen it, ack it XXX There's a border condition here XXX */
07101                if ((f.frametype != AST_FRAME_IAX) || 
07102                      ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07103                   if (option_debug)
07104                      ast_log(LOG_DEBUG, "Acking anyway\n");
07105                   /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
07106                      we have anything to send, we'll retransmit and get an ACK back anyway XXX */
07107                   send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07108                }
07109             } else {
07110                /* Send a VNAK requesting retransmission */
07111                iax2_vnak(fr->callno);
07112             }
07113             ast_mutex_unlock(&iaxsl[fr->callno]);
07114             return 1;
07115          }
07116       } else {
07117          /* Increment unless it's an ACK or VNAK */
07118          if (((f.subclass != IAX_COMMAND_ACK) &&
07119              (f.subclass != IAX_COMMAND_INVAL) &&
07120              (f.subclass != IAX_COMMAND_TXCNT) &&
07121              (f.subclass != IAX_COMMAND_TXACC) &&
07122             (f.subclass != IAX_COMMAND_VNAK)) ||
07123              (f.frametype != AST_FRAME_IAX))
07124             iaxs[fr->callno]->iseqno++;
07125       }
07126       /* A full frame */
07127       if (res < sizeof(*fh)) {
07128          ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07129          ast_mutex_unlock(&iaxsl[fr->callno]);
07130          return 1;
07131       }
07132       /* Ensure text frames are NULL-terminated */
07133       if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07134          if (res < thread->buf_size)
07135             thread->buf[res++] = '\0';
07136          else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */
07137             thread->buf[res - 1] = '\0';
07138       }
07139       f.datalen = res - sizeof(*fh);
07140 
07141       /* Handle implicit ACKing unless this is an INVAL, and only if this is 
07142          from the real peer, not the transfer peer */
07143       if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07144           ((f.subclass != IAX_COMMAND_INVAL) ||
07145            (f.frametype != AST_FRAME_IAX))) {
07146          unsigned char x;
07147          int call_to_destroy;
07148          /* XXX This code is not very efficient.  Surely there is a better way which still
07149                 properly handles boundary conditions? XXX */
07150          /* First we have to qualify that the ACKed value is within our window */
07151          for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07152             if (fr->iseqno == x)
07153                break;
07154          if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07155             /* The acknowledgement is within our window.  Time to acknowledge everything
07156                that it says to */
07157             for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07158                /* Ack the packet with the given timestamp */
07159                if (option_debug && iaxdebug)
07160                   ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07161                call_to_destroy = 0;
07162                AST_LIST_LOCK(&iaxq.queue);
07163                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07164                   /* If it's our call, and our timestamp, mark -1 retries */
07165                   if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07166                      cur->retries = -1;
07167                      /* Destroy call if this is the end */
07168                      if (cur->final)
07169                         call_to_destroy = fr->callno;
07170                   }
07171                }
07172                AST_LIST_UNLOCK(&iaxq.queue);
07173                if (call_to_destroy) {
07174                   if (iaxdebug && option_debug)
07175                      ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07176                   iax2_destroy(call_to_destroy);
07177                }
07178             }
07179             /* Note how much we've received acknowledgement for */
07180             if (iaxs[fr->callno])
07181                iaxs[fr->callno]->rseqno = fr->iseqno;
07182             else {
07183                /* Stop processing now */
07184                ast_mutex_unlock(&iaxsl[fr->callno]);
07185                return 1;
07186             }
07187          } else if (option_debug)
07188             ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07189       }
07190       if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 
07191          ((f.frametype != AST_FRAME_IAX) || 
07192           ((f.subclass != IAX_COMMAND_TXACC) &&
07193            (f.subclass != IAX_COMMAND_TXCNT)))) {
07194          /* Only messages we accept from a transfer host are TXACC and TXCNT */
07195          ast_mutex_unlock(&iaxsl[fr->callno]);
07196          return 1;
07197       }
07198 
07199       if (f.datalen) {
07200          if (f.frametype == AST_FRAME_IAX) {
07201             if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07202                ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07203                ast_mutex_unlock(&iaxsl[fr->callno]);
07204                return 1;
07205             }
07206             f.data = NULL;
07207             f.datalen = 0;
07208          } else
07209             f.data = thread->buf + sizeof(*fh);
07210       } else {
07211          if (f.frametype == AST_FRAME_IAX)
07212             f.data = NULL;
07213          else
07214             f.data = empty;
07215          memset(&ies, 0, sizeof(ies));
07216       }
07217 
07218       /* when we receive the first full frame for a new incoming channel,
07219          it is safe to start the PBX on the channel because we have now
07220          completed a 3-way handshake with the peer */
07221       if ((f.frametype == AST_FRAME_VOICE) ||
07222           (f.frametype == AST_FRAME_VIDEO) ||
07223           (f.frametype == AST_FRAME_IAX)) {
07224          if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07225             ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07226             if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07227                ast_mutex_unlock(&iaxsl[fr->callno]);
07228                return 1;
07229             }
07230          }
07231       }
07232 
07233       if (f.frametype == AST_FRAME_VOICE) {
07234          if (f.subclass != iaxs[fr->callno]->voiceformat) {
07235                iaxs[fr->callno]->voiceformat = f.subclass;
07236                if (option_debug)
07237                   ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07238                if (iaxs[fr->callno]->owner) {
07239                   int orignative;
07240 retryowner:
07241                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07242                      ast_mutex_unlock(&iaxsl[fr->callno]);
07243                      usleep(1);
07244                      ast_mutex_lock(&iaxsl[fr->callno]);
07245                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07246                   }
07247                   if (iaxs[fr->callno]) {
07248                      if (iaxs[fr->callno]->owner) {
07249                         orignative = iaxs[fr->callno]->owner->nativeformats;
07250                         iaxs[fr->callno]->owner->nativeformats = f.subclass;
07251                         if (iaxs[fr->callno]->owner->readformat)
07252                            ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07253                         iaxs[fr->callno]->owner->nativeformats = orignative;
07254                         ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07255                      }
07256                   } else {
07257                      if (option_debug)
07258                         ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07259                      ast_mutex_unlock(&iaxsl[fr->callno]);
07260                      return 1;
07261                   }
07262                }
07263          }
07264       }
07265       if (f.frametype == AST_FRAME_VIDEO) {
07266          if (f.subclass != iaxs[fr->callno]->videoformat) {
07267             if (option_debug)
07268                ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07269             iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07270          }
07271       }
07272       if (f.frametype == AST_FRAME_IAX) {
07273          AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07274          /* Handle the IAX pseudo frame itself */
07275          if (option_debug && iaxdebug)
07276             ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07277 
07278                         /* Update last ts unless the frame's timestamp originated with us. */
07279          if (iaxs[fr->callno]->last < fr->ts &&
07280                             f.subclass != IAX_COMMAND_ACK &&
07281                             f.subclass != IAX_COMMAND_PONG &&
07282                             f.subclass != IAX_COMMAND_LAGRP) {
07283             iaxs[fr->callno]->last = fr->ts;
07284             if (option_debug && iaxdebug)
07285                ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07286          }
07287 
07288          switch(f.subclass) {
07289          case IAX_COMMAND_ACK:
07290             /* Do nothing */
07291             break;
07292          case IAX_COMMAND_QUELCH:
07293             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07294                     /* Generate Manager Hold event, if necessary*/
07295                if (iaxs[fr->callno]->owner) {
07296                   manager_event(EVENT_FLAG_CALL, "Hold",
07297                      "Channel: %s\r\n"
07298                      "Uniqueid: %s\r\n",
07299                      iaxs[fr->callno]->owner->name, 
07300                      iaxs[fr->callno]->owner->uniqueid);
07301                }
07302 
07303                ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07304                if (ies.musiconhold) {
07305                   if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07306                      const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07307                      iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 
07308                         S_OR(mohsuggest, NULL),
07309                         !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07310                      if (!iaxs[fr->callno]) {
07311                         ast_mutex_unlock(&iaxsl[fr->callno]);
07312                         return 1;
07313                      }
07314                   }
07315                }
07316             }
07317             break;
07318          case IAX_COMMAND_UNQUELCH:
07319             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07320                     /* Generate Manager Unhold event, if necessary*/
07321                if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07322                   manager_event(EVENT_FLAG_CALL, "Unhold",
07323                      "Channel: %s\r\n"
07324                      "Uniqueid: %s\r\n",
07325                      iaxs[fr->callno]->owner->name, 
07326                      iaxs[fr->callno]->owner->uniqueid);
07327                }
07328 
07329                ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07330                if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07331                   iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07332                   if (!iaxs[fr->callno]) {
07333                      ast_mutex_unlock(&iaxsl[fr->callno]);
07334                      return 1;
07335                   }
07336                }
07337             }
07338             break;
07339          case IAX_COMMAND_TXACC:
07340             if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07341                /* Ack the packet with the given timestamp */
07342                AST_LIST_LOCK(&iaxq.queue);
07343                AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07344                   /* Cancel any outstanding txcnt's */
07345                   if ((fr->callno == cur->callno) && (cur->transfer))
07346                      cur->retries = -1;
07347                }
07348                AST_LIST_UNLOCK(&iaxq.queue);
07349                memset(&ied1, 0, sizeof(ied1));
07350                iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07351                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07352                iaxs[fr->callno]->transferring = TRANSFER_READY;
07353             }
07354             break;
07355          case IAX_COMMAND_NEW:
07356             /* Ignore if it's already up */
07357             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07358                break;
07359             if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07360                ast_mutex_unlock(&iaxsl[fr->callno]);
07361                check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07362                ast_mutex_lock(&iaxsl[fr->callno]);
07363                if (!iaxs[fr->callno]) {
07364                   ast_mutex_unlock(&iaxsl[fr->callno]);
07365                   return 1;
07366                }
07367             }
07368             /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
07369             if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07370                int new_callno;
07371                if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07372                   fr->callno = new_callno;
07373             }
07374             /* For security, always ack immediately */
07375             if (delayreject)
07376                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07377             if (check_access(fr->callno, &sin, &ies)) {
07378                /* They're not allowed on */
07379                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07380                if (authdebug)
07381                   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);
07382                break;
07383             }
07384             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07385                const char *context, *exten, *cid_num;
07386 
07387                context = ast_strdupa(iaxs[fr->callno]->context);
07388                exten = ast_strdupa(iaxs[fr->callno]->exten);
07389                cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07390 
07391                /* This might re-enter the IAX code and need the lock */
07392                ast_mutex_unlock(&iaxsl[fr->callno]);
07393                exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07394                ast_mutex_lock(&iaxsl[fr->callno]);
07395 
07396                if (!iaxs[fr->callno]) {
07397                   ast_mutex_unlock(&iaxsl[fr->callno]);
07398                   return 1;
07399                }
07400             } else
07401                exists = 0;
07402             if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07403                if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07404                   memset(&ied0, 0, sizeof(ied0));
07405                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07406                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07407                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07408                   if (!iaxs[fr->callno]) {
07409                      ast_mutex_unlock(&iaxsl[fr->callno]);
07410                      return 1;
07411                   }
07412                   if (authdebug)
07413                      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);
07414                } else {
07415                   /* Select an appropriate format */
07416 
07417                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07418                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07419                         using_prefs = "reqonly";
07420                      } else {
07421                         using_prefs = "disabled";
07422                      }
07423                      format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07424                      memset(&pref, 0, sizeof(pref));
07425                      strcpy(caller_pref_buf, "disabled");
07426                      strcpy(host_pref_buf, "disabled");
07427                   } else {
07428                      using_prefs = "mine";
07429                      /* If the information elements are in here... use them */
07430                      if (ies.codec_prefs)
07431                         ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07432                      if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07433                         /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
07434                         if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07435                            pref = iaxs[fr->callno]->rprefs;
07436                            using_prefs = "caller";
07437                         } else {
07438                            pref = iaxs[fr->callno]->prefs;
07439                         }
07440                      } else
07441                         pref = iaxs[fr->callno]->prefs;
07442                      
07443                      format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07444                      ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07445                      ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07446                   }
07447                   if (!format) {
07448                      if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07449                         format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07450                      if (!format) {
07451                         memset(&ied0, 0, sizeof(ied0));
07452                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07453                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07454                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07455                         if (!iaxs[fr->callno]) {
07456                            ast_mutex_unlock(&iaxsl[fr->callno]);
07457                            return 1;
07458                         }
07459                         if (authdebug) {
07460                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07461                               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);
07462                            else 
07463                               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);
07464                         }
07465                      } else {
07466                         /* Pick one... */
07467                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07468                            if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07469                               format = 0;
07470                         } else {
07471                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07472                               using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07473                               memset(&pref, 0, sizeof(pref));
07474                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07475                               strcpy(caller_pref_buf,"disabled");
07476                               strcpy(host_pref_buf,"disabled");
07477                            } else {
07478                               using_prefs = "mine";
07479                               if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07480                                  /* Do the opposite of what we tried above. */
07481                                  if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07482                                     pref = iaxs[fr->callno]->prefs;                       
07483                                  } else {
07484                                     pref = iaxs[fr->callno]->rprefs;
07485                                     using_prefs = "caller";
07486                                  }
07487                                  format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07488                            
07489                               } else /* if no codec_prefs IE do it the old way */
07490                                  format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07491                            }
07492                         }
07493 
07494                         if (!format) {
07495                            memset(&ied0, 0, sizeof(ied0));
07496                            iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07497                            iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07498                            ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07499                            send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07500                            if (!iaxs[fr->callno]) {
07501                               ast_mutex_unlock(&iaxsl[fr->callno]);
07502                               return 1;
07503                            }
07504                            if (authdebug)
07505                               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);
07506                            ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);   
07507                            break;
07508                         }
07509                      }
07510                   }
07511                   if (format) {
07512                      /* No authentication required, let them in */
07513                      memset(&ied1, 0, sizeof(ied1));
07514                      iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07515                      send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07516                      if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07517                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07518                         if (option_verbose > 2) 
07519                            ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07520                                     "%srequested format = %s,\n"
07521                                     "%srequested prefs = %s,\n"
07522                                     "%sactual format = %s,\n"
07523                                     "%shost prefs = %s,\n"
07524                                     "%spriority = %s\n",
07525                                     ast_inet_ntoa(sin.sin_addr), 
07526                                     VERBOSE_PREFIX_4,
07527                                     ast_getformatname(iaxs[fr->callno]->peerformat), 
07528                                     VERBOSE_PREFIX_4,
07529                                     caller_pref_buf,
07530                                     VERBOSE_PREFIX_4,
07531                                     ast_getformatname(format), 
07532                                     VERBOSE_PREFIX_4,
07533                                     host_pref_buf, 
07534                                     VERBOSE_PREFIX_4,
07535                                     using_prefs);
07536                         
07537                         iaxs[fr->callno]->chosenformat = format;
07538                         ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07539                      } else {
07540                         ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07541                         /* If this is a TBD call, we're ready but now what...  */
07542                         if (option_verbose > 2)
07543                            ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07544                      }
07545                   }
07546                }
07547                break;
07548             }
07549             if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07550                merge_encryption(iaxs[fr->callno],ies.encmethods);
07551             else
07552                iaxs[fr->callno]->encmethods = 0;
07553             if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07554                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07555             if (!iaxs[fr->callno]) {
07556                ast_mutex_unlock(&iaxsl[fr->callno]);
07557                return 1;
07558             }
07559             break;
07560          case IAX_COMMAND_DPREQ:
07561             /* Request status in the dialplan */
07562             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07563                !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07564                if (iaxcompat) {
07565                   /* Spawn a thread for the lookup */
07566                   spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07567                } else {
07568                   /* Just look it up */
07569                   dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07570                }
07571             }
07572             break;
07573          case IAX_COMMAND_HANGUP:
07574             ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07575             if (option_debug)
07576                ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07577             /* Set hangup cause according to remote */
07578             if (ies.causecode && iaxs[fr->callno]->owner)
07579                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07580             /* Send ack immediately, before we destroy */
07581             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07582             iax2_destroy(fr->callno);
07583             break;
07584          case IAX_COMMAND_REJECT:
07585             /* Set hangup cause according to remote */
07586             if (ies.causecode && iaxs[fr->callno]->owner)
07587                iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07588 
07589             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07590                if (iaxs[fr->callno]->owner && authdebug)
07591                   ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07592                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07593                      ies.cause ? ies.cause : "<Unknown>");
07594                if (option_debug)
07595                   ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07596                      fr->callno);
07597             }
07598             /* Send ack immediately, before we destroy */
07599             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07600                          fr->ts, NULL, 0, fr->iseqno);
07601             if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07602                iaxs[fr->callno]->error = EPERM;
07603             iax2_destroy(fr->callno);
07604             break;
07605          case IAX_COMMAND_TRANSFER:
07606          {
07607             struct ast_channel *bridged_chan;
07608 
07609             if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07610                /* Set BLINDTRANSFER channel variables */
07611 
07612                ast_mutex_unlock(&iaxsl[fr->callno]);
07613                pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07614                ast_mutex_lock(&iaxsl[fr->callno]);
07615                if (!iaxs[fr->callno]) {
07616                   ast_mutex_unlock(&iaxsl[fr->callno]);
07617                   return 1;
07618                }
07619 
07620                pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07621                if (!strcmp(ies.called_number, ast_parking_ext())) {
07622                   if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07623                      ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07624                   } else {
07625                      ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07626                   }
07627                } else {
07628                   if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07629                      ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 
07630                         ies.called_number, iaxs[fr->callno]->context);
07631                   else
07632                      ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 
07633                         ies.called_number, iaxs[fr->callno]->context);
07634                }
07635             } else
07636                   ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07637 
07638             break;
07639          }
07640          case IAX_COMMAND_ACCEPT:
07641             /* Ignore if call is already up or needs authentication or is a TBD */
07642             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07643                break;
07644             if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07645                /* Send ack immediately, before we destroy */
07646                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07647                iax2_destroy(fr->callno);
07648                break;
07649             }
07650             if (ies.format) {
07651                iaxs[fr->callno]->peerformat = ies.format;
07652             } else {
07653                if (iaxs[fr->callno]->owner)
07654                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07655                else
07656                   iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07657             }
07658             if (option_verbose > 2)
07659                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));
07660             if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07661                memset(&ied0, 0, sizeof(ied0));
07662                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07663                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07664                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07665                if (!iaxs[fr->callno]) {
07666                   ast_mutex_unlock(&iaxsl[fr->callno]);
07667                   return 1;
07668                }
07669                if (authdebug)
07670                   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);
07671             } else {
07672                ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07673                if (iaxs[fr->callno]->owner) {
07674                   /* Switch us to use a compatible format */
07675                   iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07676                   if (option_verbose > 2)
07677                      ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07678 retryowner2:
07679                   if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07680                      ast_mutex_unlock(&iaxsl[fr->callno]);
07681                      usleep(1);
07682                      ast_mutex_lock(&iaxsl[fr->callno]);
07683                      if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07684                   }
07685                   
07686                   if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07687                      /* Setup read/write formats properly. */
07688                      if (iaxs[fr->callno]->owner->writeformat)
07689                         ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);   
07690                      if (iaxs[fr->callno]->owner->readformat)
07691                         ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);  
07692                      ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07693                   }
07694                }
07695             }
07696             if (iaxs[fr->callno]) {
07697                ast_mutex_lock(&dpcache_lock);
07698                dp = iaxs[fr->callno]->dpentries;
07699                while(dp) {
07700                   if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07701                      iax2_dprequest(dp, fr->callno);
07702                   }
07703                   dp = dp->peer;
07704                }
07705                ast_mutex_unlock(&dpcache_lock);
07706             }
07707             break;
07708          case IAX_COMMAND_POKE:
07709             /* Send back a pong packet with the original timestamp */
07710             send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07711             if (!iaxs[fr->callno]) {
07712                ast_mutex_unlock(&iaxsl[fr->callno]);
07713                return 1;
07714             }
07715             break;
07716          case IAX_COMMAND_PING:
07717          {
07718             struct iax_ie_data pingied;
07719             construct_rr(iaxs[fr->callno], &pingied);
07720             /* Send back a pong packet with the original timestamp */
07721             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07722          }
07723             break;
07724          case IAX_COMMAND_PONG:
07725             /* Calculate ping time */
07726             iaxs[fr->callno]->pingtime =  calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07727             /* save RR info */
07728             save_rr(fr, &ies);
07729 
07730             if (iaxs[fr->callno]->peerpoke) {
07731                peer = iaxs[fr->callno]->peerpoke;
07732                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) {
07733                   if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07734                      ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07735                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07736                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07737                   }
07738                } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07739                   if (iaxs[fr->callno]->pingtime > peer->maxms) {
07740                      ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07741                      manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 
07742                      ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
07743                   }
07744                }
07745                peer->lastms = iaxs[fr->callno]->pingtime;
07746                if (peer->smoothing && (peer->lastms > -1))
07747                   peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07748                else if (peer->smoothing && peer->lastms < 0)
07749                   peer->historicms = (0 + peer->historicms) / 2;
07750                else              
07751                   peer->historicms = iaxs[fr->callno]->pingtime;
07752 
07753                /* Remove scheduled iax2_poke_noanswer */
07754                if (peer->pokeexpire > -1) {
07755                   if (!ast_sched_del(sched, peer->pokeexpire)) {
07756                      peer_unref(peer);
07757                      peer->pokeexpire = -1;
07758                   }
07759                }
07760                /* Schedule the next cycle */
07761                if ((peer->lastms < 0)  || (peer->historicms > peer->maxms)) 
07762                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
07763                else
07764                   peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
07765                if (peer->pokeexpire == -1)
07766                   peer_unref(peer);
07767                /* and finally send the ack */
07768                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07769                /* And wrap up the qualify call */
07770                iax2_destroy(fr->callno);
07771                peer->callno = 0;
07772                if (option_debug)
07773                   ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07774             }
07775             break;
07776          case IAX_COMMAND_LAGRQ:
07777          case IAX_COMMAND_LAGRP:
07778             f.src = "LAGRQ";
07779             f.mallocd = 0;
07780             f.offset = 0;
07781             f.samples = 0;
07782             iax_frame_wrap(fr, &f);
07783             if(f.subclass == IAX_COMMAND_LAGRQ) {
07784                /* Received a LAGRQ - echo back a LAGRP */
07785                fr->af.subclass = IAX_COMMAND_LAGRP;
07786                iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07787             } else {
07788                /* Received LAGRP in response to our LAGRQ */
07789                unsigned int ts;
07790                /* This is a reply we've been given, actually measure the difference */
07791                ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07792                iaxs[fr->callno]->lag = ts - fr->ts;
07793                if (option_debug && iaxdebug)
07794                   ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07795                      ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07796             }
07797             break;
07798          case IAX_COMMAND_AUTHREQ:
07799             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07800                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>");
07801                break;
07802             }
07803             if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07804                ast_log(LOG_WARNING, 
07805                   "I don't know how to authenticate %s to %s\n", 
07806                   ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07807             }
07808             if (!iaxs[fr->callno]) {
07809                ast_mutex_unlock(&iaxsl[fr->callno]);
07810                return 1;
07811             }
07812             break;
07813          case IAX_COMMAND_AUTHREP:
07814             /* For security, always ack immediately */
07815             if (delayreject)
07816                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07817             /* Ignore once we've started */
07818             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07819                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>");
07820                break;
07821             }
07822             if (authenticate_verify(iaxs[fr->callno], &ies)) {
07823                if (authdebug)
07824                   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);
07825                memset(&ied0, 0, sizeof(ied0));
07826                auth_fail(fr->callno, IAX_COMMAND_REJECT);
07827                break;
07828             }
07829             if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07830                /* This might re-enter the IAX code and need the lock */
07831                exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07832             } else
07833                exists = 0;
07834             if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07835                if (authdebug)
07836                   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);
07837                memset(&ied0, 0, sizeof(ied0));
07838                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07839                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07840                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07841                if (!iaxs[fr->callno]) {
07842                   ast_mutex_unlock(&iaxsl[fr->callno]);
07843                   return 1;
07844                }
07845             } else {
07846                /* Select an appropriate format */
07847                if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07848                   if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07849                      using_prefs = "reqonly";
07850                   } else {
07851                      using_prefs = "disabled";
07852                   }
07853                   format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07854                   memset(&pref, 0, sizeof(pref));
07855                   strcpy(caller_pref_buf, "disabled");
07856                   strcpy(host_pref_buf, "disabled");
07857                } else {
07858                   using_prefs = "mine";
07859                   if (ies.codec_prefs)
07860                      ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07861                   if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07862                      if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07863                         pref = iaxs[fr->callno]->rprefs;
07864                         using_prefs = "caller";
07865                      } else {
07866                         pref = iaxs[fr->callno]->prefs;
07867                      }
07868                   } else /* if no codec_prefs IE do it the old way */
07869                      pref = iaxs[fr->callno]->prefs;
07870                
07871                   format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07872                   ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07873                   ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07874                }
07875                if (!format) {
07876                   if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07877                      if (option_debug)
07878                         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);
07879                      format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07880                   }
07881                   if (!format) {
07882                      if (authdebug) {
07883                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 
07884                            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);
07885                         else
07886                            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);
07887                      }
07888                      memset(&ied0, 0, sizeof(ied0));
07889                      iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07890                      iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07891                      send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07892                      if (!iaxs[fr->callno]) {
07893                         ast_mutex_unlock(&iaxsl[fr->callno]);
07894                         return 1;
07895                      }
07896                   } else {
07897                      /* Pick one... */
07898                      if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07899                         if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07900                            format = 0;
07901                      } else {
07902                         if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07903                            using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07904                            memset(&pref, 0, sizeof(pref));
07905                            format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07906                               iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07907                            strcpy(caller_pref_buf,"disabled");
07908                            strcpy(host_pref_buf,"disabled");
07909                         } else {
07910                            using_prefs = "mine";
07911                            if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07912                               /* Do the opposite of what we tried above. */
07913                               if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07914                                  pref = iaxs[fr->callno]->prefs;                 
07915                               } else {
07916                                  pref = iaxs[fr->callno]->rprefs;
07917                                  using_prefs = "caller";
07918                               }
07919                               format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07920                            } else /* if no codec_prefs IE do it the old way */
07921                               format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 
07922                         }
07923                      }
07924                      if (!format) {
07925                         ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07926                         if (authdebug) {
07927                            if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07928                               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);
07929                            else
07930                               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);
07931                         }
07932                         memset(&ied0, 0, sizeof(ied0));
07933                         iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07934                         iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07935                         send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07936                         if (!iaxs[fr->callno]) {
07937                            ast_mutex_unlock(&iaxsl[fr->callno]);
07938                            return 1;
07939                         }
07940                      }
07941                   }
07942                }
07943                if (format) {
07944                   /* Authentication received */
07945                   memset(&ied1, 0, sizeof(ied1));
07946                   iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07947                   send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07948                   if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07949                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07950                      if (option_verbose > 2) 
07951                         ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07952                                  "%srequested format = %s,\n"
07953                                  "%srequested prefs = %s,\n"
07954                                  "%sactual format = %s,\n"
07955                                  "%shost prefs = %s,\n"
07956                                  "%spriority = %s\n", 
07957                                  ast_inet_ntoa(sin.sin_addr), 
07958                                  VERBOSE_PREFIX_4,
07959                                  ast_getformatname(iaxs[fr->callno]->peerformat),
07960                                  VERBOSE_PREFIX_4,
07961                                  caller_pref_buf,
07962                                  VERBOSE_PREFIX_4,
07963                                  ast_getformatname(format),
07964                                  VERBOSE_PREFIX_4,
07965                                  host_pref_buf,
07966                                  VERBOSE_PREFIX_4,
07967                                  using_prefs);
07968 
07969                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07970                      if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07971                         iax2_destroy(fr->callno);
07972                   } else {
07973                      ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07974                      /* If this is a TBD call, we're ready but now what...  */
07975                      if (option_verbose > 2)
07976                         ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07977                   }
07978                }
07979             }
07980             break;
07981          case IAX_COMMAND_DIAL:
07982             if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07983                ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07984                ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
07985                if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07986                   if (authdebug)
07987                      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);
07988                   memset(&ied0, 0, sizeof(ied0));
07989                   iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07990                   iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07991                   send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07992                   if (!iaxs[fr->callno]) {
07993                      ast_mutex_unlock(&iaxsl[fr->callno]);
07994                      return 1;
07995                   }
07996                } else {
07997                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07998                   if (option_verbose > 2) 
07999                      ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08000                   ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08001                   send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08002                   if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08003                      iax2_destroy(fr->callno);
08004                }
08005             }
08006             break;
08007          case IAX_COMMAND_INVAL:
08008             iaxs[fr->callno]->error = ENOTCONN;
08009             if (option_debug)
08010                ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08011             iax2_destroy(fr->callno);
08012             if (option_debug)
08013                ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08014             break;
08015          case IAX_COMMAND_VNAK:
08016             if (option_debug)
08017                ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08018             /* Force retransmission */
08019             vnak_retransmit(fr->callno, fr->iseqno);
08020             break;
08021          case IAX_COMMAND_REGREQ:
08022          case IAX_COMMAND_REGREL:
08023             /* For security, always ack immediately */
08024             if (delayreject)
08025                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08026             if (register_verify(fr->callno, &sin, &ies)) {
08027                if (!iaxs[fr->callno]) {
08028                   ast_mutex_unlock(&iaxsl[fr->callno]);
08029                   return 1;
08030                }
08031                /* Send delayed failure */
08032                auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08033                break;
08034             }
08035             if (!iaxs[fr->callno]) {
08036                ast_mutex_unlock(&iaxsl[fr->callno]);
08037                return 1;
08038             }
08039             if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 
08040                   ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08041                if (f.subclass == IAX_COMMAND_REGREL)
08042                   memset(&sin, 0, sizeof(sin));
08043                if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08044                   ast_log(LOG_WARNING, "Registry error\n");
08045                if (!iaxs[fr->callno]) {
08046                   ast_mutex_unlock(&iaxsl[fr->callno]);
08047                   return 1;
08048                }
08049                if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08050                   ast_mutex_unlock(&iaxsl[fr->callno]);
08051                   check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08052                   ast_mutex_lock(&iaxsl[fr->callno]);
08053                   if (!iaxs[fr->callno]) {
08054                      ast_mutex_unlock(&iaxsl[fr->callno]);
08055                      return 1;
08056                   }
08057                }
08058                break;
08059             }
08060             registry_authrequest(fr->callno);
08061             if (!iaxs[fr->callno]) {
08062                ast_mutex_unlock(&iaxsl[fr->callno]);
08063                return 1;
08064             }
08065             break;
08066          case IAX_COMMAND_REGACK:
08067             if (iax2_ack_registry(&ies, &sin, fr->callno)) 
08068                ast_log(LOG_WARNING, "Registration failure\n");
08069             /* Send ack immediately, before we destroy */
08070             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08071             iax2_destroy(fr->callno);
08072             break;
08073          case IAX_COMMAND_REGREJ:
08074             if (iaxs[fr->callno]->reg) {
08075                if (authdebug) {
08076                   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));
08077                   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>");
08078                }
08079                iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08080             }
08081             /* Send ack immediately, before we destroy */
08082             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08083             iax2_destroy(fr->callno);
08084             break;
08085          case IAX_COMMAND_REGAUTH:
08086             /* Authentication request */
08087             if (registry_rerequest(&ies, fr->callno, &sin)) {
08088                memset(&ied0, 0, sizeof(ied0));
08089                iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08090                iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08091                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08092                if (!iaxs[fr->callno]) {
08093                   ast_mutex_unlock(&iaxsl[fr->callno]);
08094                   return 1;
08095                }
08096             }
08097             break;
08098          case IAX_COMMAND_TXREJ:
08099             iaxs[fr->callno]->transferring = 0;
08100             if (option_verbose > 2) 
08101                ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08102             memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08103             if (iaxs[fr->callno]->bridgecallno) {
08104                if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08105                   iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08106                   send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08107                }
08108             }
08109             break;
08110          case IAX_COMMAND_TXREADY:
08111             if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08112                 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08113                if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08114                   iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08115                else
08116                   iaxs[fr->callno]->transferring = TRANSFER_READY;
08117                if (option_verbose > 2) 
08118                   ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08119                if (iaxs[fr->callno]->bridgecallno) {
08120                   if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08121                       (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08122                      /* They're both ready, now release them. */
08123                      if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08124                         if (option_verbose > 2) 
08125                            ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08126                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08127 
08128                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08129                         iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08130 
08131                         memset(&ied0, 0, sizeof(ied0));
08132                         memset(&ied1, 0, sizeof(ied1));
08133                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08134                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08135                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08136                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08137                      } else {
08138                         if (option_verbose > 2) 
08139                            ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08140                               iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08141 
08142                         iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08143                         iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08144                         ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08145                         ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08146 
08147                         /* Stop doing lag & ping requests */
08148                         stop_stuff(fr->callno);
08149                         stop_stuff(iaxs[fr->callno]->bridgecallno);
08150 
08151                         memset(&ied0, 0, sizeof(ied0));
08152                         memset(&ied1, 0, sizeof(ied1));
08153                         iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08154                         iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08155                         send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08156                         send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08157                      }
08158 
08159                   }
08160                }
08161             }
08162             break;
08163          case IAX_COMMAND_TXREQ:
08164             try_transfer(iaxs[fr->callno], &ies);
08165             break;
08166          case IAX_COMMAND_TXCNT:
08167             if (iaxs[fr->callno]->transferring)
08168                send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08169             break;
08170          case IAX_COMMAND_TXREL:
08171             /* Send ack immediately, rather than waiting until we've changed addresses */
08172             send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08173             complete_transfer(fr->callno, &ies);
08174             stop_stuff(fr->callno); /* for attended transfer to work with libiax */
08175             break;   
08176          case IAX_COMMAND_TXMEDIA:
08177             if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08178                                         AST_LIST_LOCK(&iaxq.queue);
08179                                         AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08180                                                 /* Cancel any outstanding frames and start anew */
08181                                                 if ((fr->callno == cur->callno) && (cur->transfer)) {
08182                                                         cur->retries = -1;
08183                                                 }
08184                                         }
08185                                         AST_LIST_UNLOCK(&iaxq.queue);
08186                /* Start sending our media to the transfer address, but otherwise leave the call as-is */
08187                iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08188             }
08189             break;   
08190          case IAX_COMMAND_DPREP:
08191             complete_dpreply(iaxs[fr->callno], &ies);
08192             break;
08193          case IAX_COMMAND_UNSUPPORT:
08194             ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08195             break;
08196          case IAX_COMMAND_FWDOWNL:
08197             /* Firmware download */
08198             memset(&ied0, 0, sizeof(ied0));
08199             res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08200             if (res < 0)
08201                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08202             else if (res > 0)
08203                send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08204             else
08205                send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08206             if (!iaxs[fr->callno]) {
08207                ast_mutex_unlock(&iaxsl[fr->callno]);
08208                return 1;
08209             }
08210             break;
08211          default:
08212             if (option_debug)
08213                ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08214             memset(&ied0, 0, sizeof(ied0));
08215             iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08216             send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08217          }
08218          /* Don't actually pass these frames along */
08219          if ((f.subclass != IAX_COMMAND_ACK) && 
08220            (f.subclass != IAX_COMMAND_TXCNT) && 
08221            (f.subclass != IAX_COMMAND_TXACC) && 
08222            (f.subclass != IAX_COMMAND_INVAL) &&
08223            (f.subclass != IAX_COMMAND_VNAK)) { 
08224             if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08225                send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08226          }
08227          ast_mutex_unlock(&iaxsl[fr->callno]);
08228          return 1;
08229       }
08230       /* Unless this is an ACK or INVAL frame, ack it */
08231       if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08232          send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08233    } else if (minivid) {
08234       f.frametype = AST_FRAME_VIDEO;
08235       if (iaxs[fr->callno]->videoformat > 0) 
08236          f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08237       else {
08238          ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08239          iax2_vnak(fr->callno);
08240          ast_mutex_unlock(&iaxsl[fr->callno]);
08241          return 1;
08242       }
08243       f.datalen = res - sizeof(*vh);
08244       if (f.datalen)
08245          f.data = thread->buf + sizeof(*vh);
08246       else
08247          f.data = NULL;
08248 #ifdef IAXTESTS
08249       if (test_resync) {
08250          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08251       } else
08252 #endif /* IAXTESTS */
08253          fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08254    } else {
08255       /* A mini frame */
08256       f.frametype = AST_FRAME_VOICE;
08257       if (iaxs[fr->callno]->voiceformat > 0)
08258          f.subclass = iaxs[fr->callno]->voiceformat;
08259       else {
08260          if (option_debug)
08261             ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08262          iax2_vnak(fr->callno);
08263          ast_mutex_unlock(&iaxsl[fr->callno]);
08264          return 1;
08265       }
08266       f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08267       if (f.datalen < 0) {
08268          ast_log(LOG_WARNING, "Datalen < 0?\n");
08269          ast_mutex_unlock(&iaxsl[fr->callno]);
08270          return 1;
08271       }
08272       if (f.datalen)
08273          f.data = thread->buf + sizeof(*mh);
08274       else
08275          f.data = NULL;
08276 #ifdef IAXTESTS
08277       if (test_resync) {
08278          fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08279       } else
08280 #endif /* IAXTESTS */
08281       fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08282       /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */
08283    }
08284    /* Don't pass any packets until we're started */
08285    if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08286       ast_mutex_unlock(&iaxsl[fr->callno]);
08287       return 1;
08288    }
08289    /* Common things */
08290    f.src = "IAX2";
08291    f.mallocd = 0;
08292    f.offset = 0;
08293    f.len = 0;
08294    if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08295       f.samples = ast_codec_get_samples(&f);
08296       /* We need to byteswap incoming slinear samples from network byte order */
08297       if (f.subclass == AST_FORMAT_SLINEAR)
08298          ast_frame_byteswap_be(&f);
08299    } else
08300       f.samples = 0;
08301    iax_frame_wrap(fr, &f);
08302 
08303    /* If this is our most recent packet, use it as our basis for timestamping */
08304    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08305       /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/
08306       fr->outoforder = 0;
08307    } else {
08308       if (option_debug && iaxdebug && iaxs[fr->callno])
08309          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);
08310       fr->outoforder = -1;
08311    }
08312    duped_fr = iaxfrdup2(fr);
08313    if (duped_fr) {
08314       schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08315    }
08316    if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08317       iaxs[fr->callno]->last = fr->ts;
08318 #if 1
08319       if (option_debug && iaxdebug)
08320          ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08321 #endif
08322    }
08323 
08324    /* Always run again */
08325    ast_mutex_unlock(&iaxsl[fr->callno]);
08326    return 1;
08327 }
08328 
08329 /* Function to clean up process thread if it is cancelled */
08330 static void iax2_process_thread_cleanup(void *data)
08331 {
08332    struct iax2_thread *thread = data;
08333    ast_mutex_destroy(&thread->lock);
08334    ast_cond_destroy(&thread->cond);
08335    free(thread);
08336    ast_atomic_dec_and_test(&iaxactivethreadcount);
08337 }
08338 
08339 static void *iax2_process_thread(void *data)
08340 {
08341    struct iax2_thread *thread = data;
08342    struct timeval tv;
08343    struct timespec ts;
08344    int put_into_idle = 0;
08345 
08346    ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08347    pthread_cleanup_push(iax2_process_thread_cleanup, data);
08348    for(;;) {
08349       /* Wait for something to signal us to be awake */
08350       ast_mutex_lock(&thread->lock);
08351 
08352       /* Flag that we're ready to accept signals */
08353       thread->ready_for_signal = 1;
08354       
08355       /* Put into idle list if applicable */
08356       if (put_into_idle)
08357          insert_idle_thread(thread);
08358 
08359       if (thread->type == IAX_TYPE_DYNAMIC) {
08360          struct iax2_thread *t = NULL;
08361          /* Wait to be signalled or time out */
08362          tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08363          ts.tv_sec = tv.tv_sec;
08364          ts.tv_nsec = tv.tv_usec * 1000;
08365          if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08366             /* This thread was never put back into the available dynamic
08367              * thread list, so just go away. */
08368             if (!put_into_idle) {
08369                ast_mutex_unlock(&thread->lock);
08370                break;
08371             }
08372             AST_LIST_LOCK(&dynamic_list);
08373             /* Account for the case where this thread is acquired *right* after a timeout */
08374             if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08375                iaxdynamicthreadcount--;
08376             AST_LIST_UNLOCK(&dynamic_list);
08377             if (t) {
08378                /* This dynamic thread timed out waiting for a task and was
08379                 * not acquired immediately after the timeout, 
08380                 * so it's time to go away. */
08381                ast_mutex_unlock(&thread->lock);
08382                break;
08383             }
08384             /* Someone grabbed our thread *right* after we timed out.
08385              * Wait for them to set us up with something to do and signal
08386              * us to continue. */
08387             tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08388             ts.tv_sec = tv.tv_sec;
08389             ts.tv_nsec = tv.tv_usec * 1000;
08390             if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08391             {
08392                ast_mutex_unlock(&thread->lock);
08393                break;
08394             }
08395          }
08396       } else {
08397          ast_cond_wait(&thread->cond, &thread->lock);
08398       }
08399 
08400       /* Go back into our respective list */
08401       put_into_idle = 1;
08402 
08403       ast_mutex_unlock(&thread->lock);
08404 
08405       if (thread->iostate == IAX_IOSTATE_IDLE)
08406          continue;
08407 
08408       /* Add ourselves to the active list now */
08409       AST_LIST_LOCK(&active_list);
08410       AST_LIST_INSERT_HEAD(&active_list, thread, list);
08411       AST_LIST_UNLOCK(&active_list);
08412 
08413       /* See what we need to do */
08414       switch(thread->iostate) {
08415       case IAX_IOSTATE_READY:
08416          thread->actions++;
08417          thread->iostate = IAX_IOSTATE_PROCESSING;
08418          socket_process(thread);
08419          handle_deferred_full_frames(thread);
08420          break;
08421       case IAX_IOSTATE_SCHEDREADY:
08422          thread->actions++;
08423          thread->iostate = IAX_IOSTATE_PROCESSING;
08424 #ifdef SCHED_MULTITHREADED
08425          thread->schedfunc(thread->scheddata);
08426 #endif      
08427          break;
08428       }
08429       time(&thread->checktime);
08430       thread->iostate = IAX_IOSTATE_IDLE;
08431 #ifdef DEBUG_SCHED_MULTITHREAD
08432       thread->curfunc[0]='\0';
08433 #endif      
08434 
08435       /* Now... remove ourselves from the active list, and return to the idle list */
08436       AST_LIST_LOCK(&active_list);
08437       AST_LIST_REMOVE(&active_list, thread, list);
08438       AST_LIST_UNLOCK(&active_list);
08439 
08440       /* Make sure another frame didn't sneak in there after we thought we were done. */
08441       handle_deferred_full_frames(thread);
08442    }
08443 
08444    /*!\note For some reason, idle threads are exiting without being removed
08445     * from an idle list, which is causing memory corruption.  Forcibly remove
08446     * it from the list, if it's there.
08447     */
08448    AST_LIST_LOCK(&idle_list);
08449    AST_LIST_REMOVE(&idle_list, thread, list);
08450    AST_LIST_UNLOCK(&idle_list);
08451 
08452    AST_LIST_LOCK(&dynamic_list);
08453    AST_LIST_REMOVE(&dynamic_list, thread, list);
08454    AST_LIST_UNLOCK(&dynamic_list);
08455 
08456    /* I am exiting here on my own volition, I need to clean up my own data structures
08457    * Assume that I am no longer in any of the lists (idle, active, or dynamic)
08458    */
08459    pthread_cleanup_pop(1);
08460 
08461    return NULL;
08462 }
08463 
08464 static int iax2_do_register(struct iax2_registry *reg)
08465 {
08466    struct iax_ie_data ied;
08467    if (option_debug && iaxdebug)
08468       ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08469 
08470    if (reg->dnsmgr && 
08471        ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08472       /* Maybe the IP has changed, force DNS refresh */
08473       ast_dnsmgr_refresh(reg->dnsmgr);
08474    }
08475    
08476    /*
08477     * if IP has Changed, free allocated call to create a new one with new IP
08478     * call has the pointer to IP and must be updated to the new one
08479     */
08480    if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08481       ast_mutex_lock(&iaxsl[reg->callno]);
08482       iax2_destroy(reg->callno);
08483       ast_mutex_unlock(&iaxsl[reg->callno]);
08484       reg->callno = 0;
08485    }
08486    if (!reg->addr.sin_addr.s_addr) {
08487       if (option_debug && iaxdebug)
08488          ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08489       /* Setup the next registration attempt */
08490       AST_SCHED_DEL(sched, reg->expire);
08491       reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08492       return -1;
08493    }
08494 
08495    if (!reg->callno) {
08496       if (option_debug)
08497          ast_log(LOG_DEBUG, "Allocate call number\n");
08498       reg->callno = find_callno(0, 0, &reg->addr, NEW_FORCE, defaultsockfd);
08499       if (reg->callno < 1) {
08500          ast_log(LOG_WARNING, "Unable to create call for registration\n");
08501          return -1;
08502       } else if (option_debug)
08503          ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08504       iaxs[reg->callno]->reg = reg;
08505    }
08506    /* Schedule the next registration attempt */
08507    AST_SCHED_DEL(sched, reg->expire);
08508    /* Setup the next registration a little early */
08509    reg->expire  = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08510    /* Send the request */
08511    memset(&ied, 0, sizeof(ied));
08512    iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08513    iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08514    send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08515    reg->regstate = REG_STATE_REGSENT;
08516    return 0;
08517 }
08518 
08519 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08520 {
08521    if (pos != 3)
08522       return NULL;
08523    return iax_prov_complete_template(line, word, pos, state);
08524 }
08525 
08526 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08527 {
08528    /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning
08529       is found for template */
08530    struct iax_ie_data provdata;
08531    struct iax_ie_data ied;
08532    unsigned int sig;
08533    struct sockaddr_in sin;
08534    int callno;
08535    struct create_addr_info cai;
08536 
08537    memset(&cai, 0, sizeof(cai));
08538 
08539    if (option_debug)
08540       ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08541 
08542    if (iax_provision_build(&provdata, &sig, template, force)) {
08543       if (option_debug)
08544          ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08545       return 0;
08546    }
08547 
08548    if (end) {
08549       memcpy(&sin, end, sizeof(sin));
08550       cai.sockfd = sockfd;
08551    } else if (create_addr(dest, NULL, &sin, &cai))
08552       return -1;
08553 
08554    /* Build the rest of the message */
08555    memset(&ied, 0, sizeof(ied));
08556    iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08557 
08558    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
08559    if (!callno)
08560       return -1;
08561 
08562    ast_mutex_lock(&iaxsl[callno]);
08563    if (iaxs[callno]) {
08564       /* Schedule autodestruct in case they don't ever give us anything back */
08565       AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08566       iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08567       ast_set_flag(iaxs[callno], IAX_PROVISION);
08568       /* Got a call number now, so go ahead and send the provisioning information */
08569       send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08570    }
08571    ast_mutex_unlock(&iaxsl[callno]);
08572 
08573    return 1;
08574 }
08575 
08576 static char *papp = "IAX2Provision";
08577 static char *psyn = "Provision a calling IAXy with a given template";
08578 static char *pdescrip = 
08579 "  IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08580 "the calling entity is in fact an IAXy) with the given template or\n"
08581 "default if one is not specified.  Returns -1 on error or 0 on success.\n";
08582 
08583 /*! iax2provision
08584 \ingroup applications
08585 */
08586 static int iax2_prov_app(struct ast_channel *chan, void *data)
08587 {
08588    int res;
08589    char *sdata;
08590    char *opts;
08591    int force =0;
08592    unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08593    if (ast_strlen_zero(data))
08594       data = "default";
08595    sdata = ast_strdupa(data);
08596    opts = strchr(sdata, '|');
08597    if (opts)
08598       *opts='\0';
08599 
08600    if (chan->tech != &iax2_tech) {
08601       ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08602       return -1;
08603    } 
08604    if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08605       ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08606       return -1;
08607    }
08608    res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08609    if (option_verbose > 2)
08610       ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n", 
08611       ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08612       sdata, res);
08613    return res;
08614 }
08615 
08616 
08617 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08618 {
08619    int force = 0;
08620    int res;
08621    if (argc < 4)
08622       return RESULT_SHOWUSAGE;
08623    if ((argc > 4)) {
08624       if (!strcasecmp(argv[4], "forced"))
08625          force = 1;
08626       else
08627          return RESULT_SHOWUSAGE;
08628    }
08629    res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08630    if (res < 0)
08631       ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08632    else if (res < 1)
08633       ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08634    else
08635       ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08636    return RESULT_SUCCESS;
08637 }
08638 
08639 static void __iax2_poke_noanswer(const void *data)
08640 {
08641    struct iax2_peer *peer = (struct iax2_peer *)data;
08642    if (peer->lastms > -1) {
08643       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08644       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08645       ast_device_state_changed("IAX2/%s", peer->name); /* Activate notification */
08646    }
08647    if (peer->callno > 0) {
08648       ast_mutex_lock(&iaxsl[peer->callno]);
08649       iax2_destroy(peer->callno);
08650       ast_mutex_unlock(&iaxsl[peer->callno]);
08651    }
08652    peer->callno = 0;
08653    peer->lastms = -1;
08654    /* Try again quickly */
08655    peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08656    if (peer->pokeexpire == -1)
08657       peer_unref(peer);
08658 }
08659 
08660 static int iax2_poke_noanswer(const void *data)
08661 {
08662    struct iax2_peer *peer = (struct iax2_peer *)data;
08663    peer->pokeexpire = -1;
08664 #ifdef SCHED_MULTITHREADED
08665    if (schedule_action(__iax2_poke_noanswer, data))
08666 #endif      
08667       __iax2_poke_noanswer(data);
08668    peer_unref(peer);
08669    return 0;
08670 }
08671 
08672 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08673 {
08674    struct iax2_peer *peer = obj;
08675 
08676    iax2_poke_peer(peer, 0);
08677 
08678    return 0;
08679 }
08680 
08681 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08682 {
08683    if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08684       /* IF we have no IP without dnsmgr, or this isn't to be monitored, return
08685         immediately after clearing things out */
08686       peer->lastms = 0;
08687       peer->historicms = 0;
08688       peer->pokeexpire = -1;
08689       peer->callno = 0;
08690       return 0;
08691    }
08692    if (peer->callno > 0) {
08693       ast_log(LOG_NOTICE, "Still have a callno...\n");
08694       ast_mutex_lock(&iaxsl[peer->callno]);
08695       iax2_destroy(peer->callno);
08696       ast_mutex_unlock(&iaxsl[peer->callno]);
08697    }
08698    if (heldcall)
08699       ast_mutex_unlock(&iaxsl[heldcall]);
08700    peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd);
08701    if (heldcall)
08702       ast_mutex_lock(&iaxsl[heldcall]);
08703    if (peer->callno < 1) {
08704       ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08705       return -1;
08706    }
08707 
08708    /* Speed up retransmission times for this qualify call */
08709    iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08710    iaxs[peer->callno]->peerpoke = peer;
08711    
08712    /* Remove any pending pokeexpire task */
08713    if (peer->pokeexpire > -1) {
08714       if (!ast_sched_del(sched, peer->pokeexpire)) {
08715          peer->pokeexpire = -1;
08716          peer_unref(peer);
08717       }
08718    }
08719 
08720    /* Queue up a new task to handle no reply */
08721    /* If the host is already unreachable then use the unreachable interval instead */
08722    if (peer->lastms < 0) {
08723       peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08724    } else
08725       peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08726 
08727    if (peer->pokeexpire == -1)
08728       peer_unref(peer);
08729 
08730    /* And send the poke */
08731    send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08732 
08733    return 0;
08734 }
08735 
08736 static void free_context(struct iax2_context *con)
08737 {
08738    struct iax2_context *conl;
08739    while(con) {
08740       conl = con;
08741       con = con->next;
08742       free(conl);
08743    }
08744 }
08745 
08746 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08747 {
08748    int callno;
08749    int res;
08750    int fmt, native;
08751    struct sockaddr_in sin;
08752    struct ast_channel *c;
08753    struct parsed_dial_string pds;
08754    struct create_addr_info cai;
08755    char *tmpstr;
08756 
08757    memset(&pds, 0, sizeof(pds));
08758    tmpstr = ast_strdupa(data);
08759    parse_dial_string(tmpstr, &pds);
08760 
08761    if (ast_strlen_zero(pds.peer)) {
08762       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
08763       return NULL;
08764    }
08765           
08766    memset(&cai, 0, sizeof(cai));
08767    cai.capability = iax2_capability;
08768 
08769    ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08770    
08771    /* Populate our address from the given */
08772    if (create_addr(pds.peer, NULL, &sin, &cai)) {
08773       *cause = AST_CAUSE_UNREGISTERED;
08774       return NULL;
08775    }
08776 
08777    if (pds.port)
08778       sin.sin_port = htons(atoi(pds.port));
08779 
08780    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
08781    if (callno < 1) {
08782       ast_log(LOG_WARNING, "Unable to create call\n");
08783       *cause = AST_CAUSE_CONGESTION;
08784       return NULL;
08785    }
08786 
08787    ast_mutex_lock(&iaxsl[callno]);
08788 
08789    /* If this is a trunk, update it now */
08790    ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 
08791    if (ast_test_flag(&cai, IAX_TRUNK)) {
08792       int new_callno;
08793       if ((new_callno = make_trunk(callno, 1)) != -1)
08794          callno = new_callno;
08795    }
08796    iaxs[callno]->maxtime = cai.maxtime;
08797    if (cai.found)
08798       ast_string_field_set(iaxs[callno], host, pds.peer);
08799 
08800    c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08801 
08802    ast_mutex_unlock(&iaxsl[callno]);
08803 
08804    if (c) {
08805       /* Choose a format we can live with */
08806       if (c->nativeformats & format) 
08807          c->nativeformats &= format;
08808       else {
08809          native = c->nativeformats;
08810          fmt = format;
08811          res = ast_translator_best_choice(&fmt, &native);
08812          if (res < 0) {
08813             ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08814                ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08815             ast_hangup(c);
08816             return NULL;
08817          }
08818          c->nativeformats = native;
08819       }
08820       c->readformat = ast_best_codec(c->nativeformats);
08821       c->writeformat = c->readformat;
08822    }
08823 
08824    return c;
08825 }
08826 
08827 static void *sched_thread(void *ignore)
08828 {
08829    int count;
08830    int res;
08831    struct timeval tv;
08832    struct timespec ts;
08833 
08834    for (;;) {
08835       res = ast_sched_wait(sched);
08836       if ((res > 1000) || (res < 0))
08837          res = 1000;
08838       tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
08839       ts.tv_sec = tv.tv_sec;
08840       ts.tv_nsec = tv.tv_usec * 1000;
08841 
08842       pthread_testcancel();
08843       ast_mutex_lock(&sched_lock);
08844       ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
08845       ast_mutex_unlock(&sched_lock);
08846       pthread_testcancel();
08847 
08848       count = ast_sched_runq(sched);
08849       if (option_debug && count >= 20)
08850          ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08851    }
08852    return NULL;
08853 }
08854 
08855 static void *network_thread(void *ignore)
08856 {
08857    /* Our job is simple: Send queued messages, retrying if necessary.  Read frames 
08858       from the network, and queue them for delivery to the channels */
08859    int res, count, wakeup;
08860    struct iax_frame *f;
08861 
08862    if (timingfd > -1)
08863       ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08864    
08865    for(;;) {
08866       pthread_testcancel();
08867 
08868       /* Go through the queue, sending messages which have not yet been
08869          sent, and scheduling retransmissions if appropriate */
08870       AST_LIST_LOCK(&iaxq.queue);
08871       count = 0;
08872       wakeup = -1;
08873       AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
08874          if (f->sentyet)
08875             continue;
08876          
08877          /* Try to lock the pvt, if we can't... don't fret - defer it till later */
08878          if (ast_mutex_trylock(&iaxsl[f->callno])) {
08879             wakeup = 1;
08880             continue;
08881          }
08882 
08883          f->sentyet++;
08884 
08885          if (iaxs[f->callno]) {
08886             send_packet(f);
08887             count++;
08888          } 
08889 
08890          ast_mutex_unlock(&iaxsl[f->callno]);
08891 
08892          if (f->retries < 0) {
08893             /* This is not supposed to be retransmitted */
08894             AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
08895             iaxq.count--;
08896             /* Free the iax frame */
08897             iax_frame_free(f);
08898          } else {
08899             /* We need reliable delivery.  Schedule a retransmission */
08900             f->retries++;
08901             f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
08902          }
08903       }
08904       AST_LIST_TRAVERSE_SAFE_END
08905       AST_LIST_UNLOCK(&iaxq.queue);
08906 
08907       pthread_testcancel();
08908 
08909       if (option_debug && count >= 20)
08910          ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08911 
08912       /* Now do the IO, and run scheduled tasks */
08913       res = ast_io_wait(io, wakeup);
08914       if (res >= 0) {
08915          if (option_debug && res >= 20)
08916             ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08917       }
08918    }
08919    return NULL;
08920 }
08921 
08922 static int start_network_thread(void)
08923 {
08924    pthread_attr_t attr;
08925    int threadcount = 0;
08926    int x;
08927    for (x = 0; x < iaxthreadcount; x++) {
08928       struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
08929       if (thread) {
08930          thread->type = IAX_TYPE_POOL;
08931          thread->threadnum = ++threadcount;
08932          ast_mutex_init(&thread->lock);
08933          ast_cond_init(&thread->cond, NULL);
08934          pthread_attr_init(&attr);
08935          pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);   
08936          if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
08937             ast_log(LOG_WARNING, "Failed to create new thread!\n");
08938             free(thread);
08939             thread = NULL;
08940          }
08941          AST_LIST_LOCK(&idle_list);
08942          AST_LIST_INSERT_TAIL(&idle_list, thread, list);
08943          AST_LIST_UNLOCK(&idle_list);
08944       }
08945    }
08946    ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
08947    ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
08948    if (option_verbose > 1)
08949       ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
08950    return 0;
08951 }
08952 
08953 static struct iax2_context *build_context(char *context)
08954 {
08955    struct iax2_context *con;
08956 
08957    if ((con = ast_calloc(1, sizeof(*con))))
08958       ast_copy_string(con->context, context, sizeof(con->context));
08959    
08960    return con;
08961 }
08962 
08963 static int get_auth_methods(char *value)
08964 {
08965    int methods = 0;
08966    if (strstr(value, "rsa"))
08967       methods |= IAX_AUTH_RSA;
08968    if (strstr(value, "md5"))
08969       methods |= IAX_AUTH_MD5;
08970    if (strstr(value, "plaintext"))
08971       methods |= IAX_AUTH_PLAINTEXT;
08972    return methods;
08973 }
08974 
08975 
08976 /*! \brief Check if address can be used as packet source.
08977  \return 0  address available, 1  address unavailable, -1  error
08978 */
08979 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08980 {
08981    int sd;
08982    int res;
08983    
08984    sd = socket(AF_INET, SOCK_DGRAM, 0);
08985    if (sd < 0) {
08986       ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08987       return -1;
08988    }
08989 
08990    res = bind(sd, sa, salen);
08991    if (res < 0) {
08992       if (option_debug)
08993          ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08994       close(sd);
08995       return 1;
08996    }
08997 
08998    close(sd);
08999    return 0;
09000 }
09001 
09002 /*! \brief Parse the "sourceaddress" value,
09003   lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if
09004   not found. */
09005 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09006 {
09007    struct sockaddr_in sin;
09008    int nonlocal = 1;
09009    int port = IAX_DEFAULT_PORTNO;
09010    int sockfd = defaultsockfd;
09011    char *tmp;
09012    char *addr;
09013    char *portstr;
09014 
09015    if (!(tmp = ast_strdupa(srcaddr)))
09016       return -1;
09017 
09018    addr = strsep(&tmp, ":");
09019    portstr = tmp;
09020 
09021    if (portstr) {
09022       port = atoi(portstr);
09023       if (port < 1)
09024          port = IAX_DEFAULT_PORTNO;
09025    }
09026    
09027    if (!ast_get_ip(&sin, addr)) {
09028       struct ast_netsock *sock;
09029       int res;
09030 
09031       sin.sin_port = 0;
09032       sin.sin_family = AF_INET;
09033       res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09034       if (res == 0) {
09035          /* ip address valid. */
09036          sin.sin_port = htons(port);
09037          if (!(sock = ast_netsock_find(netsock, &sin)))
09038             sock = ast_netsock_find(outsock, &sin);
09039          if (sock) {
09040             sockfd = ast_netsock_sockfd(sock);
09041             nonlocal = 0;
09042          } else {
09043             unsigned int orig_saddr = sin.sin_addr.s_addr;
09044             /* INADDR_ANY matches anyway! */
09045             sin.sin_addr.s_addr = INADDR_ANY;
09046             if (ast_netsock_find(netsock, &sin)) {
09047                sin.sin_addr.s_addr = orig_saddr;
09048                sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09049                if (sock) {
09050                   sockfd = ast_netsock_sockfd(sock);
09051                   ast_netsock_unref(sock);
09052                   nonlocal = 0;
09053                } else {
09054                   nonlocal = 2;
09055                }
09056             }
09057          }
09058       }
09059    }
09060       
09061    peer->sockfd = sockfd;
09062 
09063    if (nonlocal == 1) {
09064       ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09065          srcaddr, peer->name);
09066       return -1;
09067         } else if (nonlocal == 2) {
09068       ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09069          srcaddr, peer->name);
09070          return -1;
09071    } else {
09072       if (option_debug)
09073          ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09074       return 0;
09075    }
09076 }
09077 
09078 static void peer_destructor(void *obj)
09079 {
09080    struct iax2_peer *peer = obj;
09081 
09082    ast_free_ha(peer->ha);
09083 
09084    if (peer->callno > 0) {
09085       ast_mutex_lock(&iaxsl[peer->callno]);
09086       iax2_destroy(peer->callno);
09087       ast_mutex_unlock(&iaxsl[peer->callno]);
09088    }
09089 
09090    register_peer_exten(peer, 0);
09091 
09092    if (peer->dnsmgr)
09093       ast_dnsmgr_release(peer->dnsmgr);
09094 
09095    ast_string_field_free_memory(peer);
09096 }
09097 
09098 /*! \brief Create peer structure based on configuration */
09099 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09100 {
09101    struct iax2_peer *peer = NULL;
09102    struct ast_ha *oldha = NULL;
09103    int maskfound=0;
09104    int found=0;
09105    int firstpass=1;
09106    struct iax2_peer tmp_peer = {
09107       .name = name,
09108    };
09109 
09110    if (!temponly) {
09111       peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09112       if (peer && !ast_test_flag(peer, IAX_DELME))
09113          firstpass = 0;
09114    }
09115 
09116    if (peer) {
09117       found++;
09118       if (firstpass) {
09119          oldha = peer->ha;
09120          peer->ha = NULL;
09121       }
09122       unlink_peer(peer);
09123    } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09124       peer->expire = -1;
09125       peer->pokeexpire = -1;
09126       peer->sockfd = defaultsockfd;
09127       if (ast_string_field_init(peer, 32))
09128          peer = peer_unref(peer);
09129    }
09130 
09131    if (peer) {
09132       if (firstpass) {
09133          ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09134          peer->encmethods = iax2_encryption;
09135          peer->adsi = adsi;
09136          ast_string_field_set(peer,secret,"");
09137          if (!found) {
09138             ast_string_field_set(peer, name, name);
09139             peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09140             peer->expiry = min_reg_expire;
09141          }
09142          peer->prefs = prefs;
09143          peer->capability = iax2_capability;
09144          peer->smoothing = 0;
09145          peer->pokefreqok = DEFAULT_FREQ_OK;
09146          peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09147          ast_string_field_set(peer,context,"");
09148          ast_string_field_set(peer,peercontext,"");
09149          ast_clear_flag(peer, IAX_HASCALLERID);
09150          ast_string_field_set(peer, cid_name, "");
09151          ast_string_field_set(peer, cid_num, "");
09152       }
09153 
09154       if (!v) {
09155          v = alt;
09156          alt = NULL;
09157       }
09158       while(v) {
09159          if (!strcasecmp(v->name, "secret")) {
09160             ast_string_field_set(peer, secret, v->value);
09161          } else if (!strcasecmp(v->name, "mailbox")) {
09162             ast_string_field_set(peer, mailbox, v->value);
09163          } else if (!strcasecmp(v->name, "mohinterpret")) {
09164             ast_string_field_set(peer, mohinterpret, v->value);
09165          } else if (!strcasecmp(v->name, "mohsuggest")) {
09166             ast_string_field_set(peer, mohsuggest, v->value);
09167          } else if (!strcasecmp(v->name, "dbsecret")) {
09168             ast_string_field_set(peer, dbsecret, v->value);
09169          } else if (!strcasecmp(v->name, "trunk")) {
09170             ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);   
09171             if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09172                ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09173                ast_clear_flag(peer, IAX_TRUNK);
09174             }
09175          } else if (!strcasecmp(v->name, "auth")) {
09176             peer->authmethods = get_auth_methods(v->value);
09177          } else if (!strcasecmp(v->name, "encryption")) {
09178             peer->encmethods = get_encrypt_methods(v->value);
09179          } else if (!strcasecmp(v->name, "notransfer")) {
09180             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09181             ast_clear_flag(peer, IAX_TRANSFERMEDIA);  
09182             ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER); 
09183          } else if (!strcasecmp(v->name, "transfer")) {
09184             if (!strcasecmp(v->value, "mediaonly")) {
09185                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09186             } else if (ast_true(v->value)) {
09187                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09188             } else 
09189                ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09190          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09191             ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);  
09192          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09193             ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);   
09194          } else if (!strcasecmp(v->name, "host")) {
09195             if (!strcasecmp(v->value, "dynamic")) {
09196                /* They'll register with us */
09197                ast_set_flag(peer, IAX_DYNAMIC); 
09198                if (!found) {
09199                   /* Initialize stuff iff we're not found, otherwise
09200                      we keep going with what we had */
09201                   memset(&peer->addr.sin_addr, 0, 4);
09202                   if (peer->addr.sin_port) {
09203                      /* If we've already got a port, make it the default rather than absolute */
09204                      peer->defaddr.sin_port = peer->addr.sin_port;
09205                      peer->addr.sin_port = 0;
09206                   }
09207                }
09208             } else {
09209                /* Non-dynamic.  Make sure we become that way if we're not */
09210                AST_SCHED_DEL(sched, peer->expire);
09211                ast_clear_flag(peer, IAX_DYNAMIC);
09212                if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09213                   return peer_unref(peer);
09214                if (!peer->addr.sin_port)
09215                   peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09216             }
09217             if (!maskfound)
09218                inet_aton("255.255.255.255", &peer->mask);
09219          } else if (!strcasecmp(v->name, "defaultip")) {
09220             if (ast_get_ip(&peer->defaddr, v->value))
09221                return peer_unref(peer);
09222          } else if (!strcasecmp(v->name, "sourceaddress")) {
09223             peer_set_srcaddr(peer, v->value);
09224          } else if (!strcasecmp(v->name, "permit") ||
09225                   !strcasecmp(v->name, "deny")) {
09226             peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09227          } else if (!strcasecmp(v->name, "mask")) {
09228             maskfound++;
09229             inet_aton(v->value, &peer->mask);
09230          } else if (!strcasecmp(v->name, "context")) {
09231             ast_string_field_set(peer, context, v->value);
09232          } else if (!strcasecmp(v->name, "regexten")) {
09233             ast_string_field_set(peer, regexten, v->value);
09234          } else if (!strcasecmp(v->name, "peercontext")) {
09235             ast_string_field_set(peer, peercontext, v->value);
09236          } else if (!strcasecmp(v->name, "port")) {
09237             if (ast_test_flag(peer, IAX_DYNAMIC))
09238                peer->defaddr.sin_port = htons(atoi(v->value));
09239             else
09240                peer->addr.sin_port = htons(atoi(v->value));
09241          } else if (!strcasecmp(v->name, "username")) {
09242             ast_string_field_set(peer, username, v->value);
09243          } else if (!strcasecmp(v->name, "allow")) {
09244             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09245          } else if (!strcasecmp(v->name, "disallow")) {
09246             ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09247          } else if (!strcasecmp(v->name, "callerid")) {
09248             if (!ast_strlen_zero(v->value)) {
09249                char name2[80];
09250                char num2[80];
09251                ast_callerid_split(v->value, name2, 80, num2, 80);
09252                ast_string_field_set(peer, cid_name, name2);
09253                ast_string_field_set(peer, cid_num, num2);
09254                ast_set_flag(peer, IAX_HASCALLERID);
09255             } else {
09256                ast_clear_flag(peer, IAX_HASCALLERID);
09257                ast_string_field_set(peer, cid_name, "");
09258                ast_string_field_set(peer, cid_num, "");
09259             }
09260          } else if (!strcasecmp(v->name, "fullname")) {
09261             if (!ast_strlen_zero(v->value)) {
09262                ast_string_field_set(peer, cid_name, v->value);
09263                ast_set_flag(peer, IAX_HASCALLERID);
09264             } else {
09265                ast_string_field_set(peer, cid_name, "");
09266                if (ast_strlen_zero(peer->cid_num))
09267                   ast_clear_flag(peer, IAX_HASCALLERID);
09268             }
09269          } else if (!strcasecmp(v->name, "cid_number")) {
09270             if (!ast_strlen_zero(v->value)) {
09271                ast_string_field_set(peer, cid_num, v->value);
09272                ast_set_flag(peer, IAX_HASCALLERID);
09273             } else {
09274                ast_string_field_set(peer, cid_num, "");
09275                if (ast_strlen_zero(peer->cid_name))
09276                   ast_clear_flag(peer, IAX_HASCALLERID);
09277             }
09278          } else if (!strcasecmp(v->name, "sendani")) {
09279             ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 
09280          } else if (!strcasecmp(v->name, "inkeys")) {
09281             ast_string_field_set(peer, inkeys, v->value);
09282          } else if (!strcasecmp(v->name, "outkey")) {
09283             ast_string_field_set(peer, outkey, v->value);
09284          } else if (!strcasecmp(v->name, "qualify")) {
09285             if (!strcasecmp(v->value, "no")) {
09286                peer->maxms = 0;
09287             } else if (!strcasecmp(v->value, "yes")) {
09288                peer->maxms = DEFAULT_MAXMS;
09289             } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09290                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);
09291                peer->maxms = 0;
09292             }
09293          } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09294             peer->smoothing = ast_true(v->value);
09295          } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09296             if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09297                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);
09298             }
09299          } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09300             if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09301                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);
09302             } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09303          } else if (!strcasecmp(v->name, "timezone")) {
09304             ast_string_field_set(peer, zonetag, v->value);
09305          } else if (!strcasecmp(v->name, "adsi")) {
09306             peer->adsi = ast_true(v->value);
09307          }/* else if (strcasecmp(v->name,"type")) */
09308          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09309          v = v->next;
09310          if (!v) {
09311             v = alt;
09312             alt = NULL;
09313          }
09314       }
09315       if (!peer->authmethods)
09316          peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09317       ast_clear_flag(peer, IAX_DELME); 
09318       /* Make sure these are IPv4 addresses */
09319       peer->addr.sin_family = AF_INET;
09320    }
09321    if (oldha)
09322       ast_free_ha(oldha);
09323    return peer;
09324 }
09325 
09326 static void user_destructor(void *obj)
09327 {
09328    struct iax2_user *user = obj;
09329 
09330    ast_free_ha(user->ha);
09331    free_context(user->contexts);
09332    if(user->vars) {
09333       ast_variables_destroy(user->vars);
09334       user->vars = NULL;
09335    }
09336    ast_string_field_free_memory(user);
09337 }
09338 
09339 /*! \brief Create in-memory user structure from configuration */
09340 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09341 {
09342    struct iax2_user *user = NULL;
09343    struct iax2_context *con, *conl = NULL;
09344    struct ast_ha *oldha = NULL;
09345    struct iax2_context *oldcon = NULL;
09346    int format;
09347    int firstpass=1;
09348    int oldcurauthreq = 0;
09349    char *varname = NULL, *varval = NULL;
09350    struct ast_variable *tmpvar = NULL;
09351    struct iax2_user tmp_user = {
09352       .name = name,
09353    };
09354 
09355    if (!temponly) {
09356       user = ao2_find(users, &tmp_user, OBJ_POINTER);
09357       if (user && !ast_test_flag(user, IAX_DELME))
09358          firstpass = 0;
09359    }
09360 
09361    if (user) {
09362       if (firstpass) {
09363          oldcurauthreq = user->curauthreq;
09364          oldha = user->ha;
09365          oldcon = user->contexts;
09366          user->ha = NULL;
09367          user->contexts = NULL;
09368       }
09369       /* Already in the list, remove it and it will be added back (or FREE'd) */
09370       ao2_unlink(users, user);
09371    } else {
09372       user = ao2_alloc(sizeof(*user), user_destructor);
09373    }
09374    
09375    if (user) {
09376       if (firstpass) {
09377          ast_string_field_free_memory(user);
09378          memset(user, 0, sizeof(struct iax2_user));
09379          if (ast_string_field_init(user, 32)) {
09380             user = user_unref(user);
09381             goto cleanup;
09382          }
09383          user->maxauthreq = maxauthreq;
09384          user->curauthreq = oldcurauthreq;
09385          user->prefs = prefs;
09386          user->capability = iax2_capability;
09387          user->encmethods = iax2_encryption;
09388          user->adsi = adsi;
09389          ast_string_field_set(user, name, name);
09390          ast_string_field_set(user, language, language);
09391          ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);   
09392          ast_clear_flag(user, IAX_HASCALLERID);
09393          ast_string_field_set(user, cid_name, "");
09394          ast_string_field_set(user, cid_num, "");
09395       }
09396       if (!v) {
09397          v = alt;
09398          alt = NULL;
09399       }
09400       while(v) {
09401          if (!strcasecmp(v->name, "context")) {
09402             con = build_context(v->value);
09403             if (con) {
09404                if (conl)
09405                   conl->next = con;
09406                else
09407                   user->contexts = con;
09408                conl = con;
09409             }
09410          } else if (!strcasecmp(v->name, "permit") ||
09411                   !strcasecmp(v->name, "deny")) {
09412             user->ha = ast_append_ha(v->name, v->value, user->ha);
09413          } else if (!strcasecmp(v->name, "setvar")) {
09414             varname = ast_strdupa(v->value);
09415             if (varname && (varval = strchr(varname,'='))) {
09416                *varval = '\0';
09417                varval++;
09418                if((tmpvar = ast_variable_new(varname, varval))) {
09419                   tmpvar->next = user->vars; 
09420                   user->vars = tmpvar;
09421                }
09422             }
09423          } else if (!strcasecmp(v->name, "allow")) {
09424             ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09425          } else if (!strcasecmp(v->name, "disallow")) {
09426             ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09427          } else if (!strcasecmp(v->name, "trunk")) {
09428             ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);   
09429             if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09430                ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09431                ast_clear_flag(user, IAX_TRUNK);
09432             }
09433          } else if (!strcasecmp(v->name, "auth")) {
09434             user->authmethods = get_auth_methods(v->value);
09435          } else if (!strcasecmp(v->name, "encryption")) {
09436             user->encmethods = get_encrypt_methods(v->value);
09437          } else if (!strcasecmp(v->name, "notransfer")) {
09438             ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09439             ast_clear_flag(user, IAX_TRANSFERMEDIA);  
09440             ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER); 
09441          } else if (!strcasecmp(v->name, "transfer")) {
09442             if (!strcasecmp(v->value, "mediaonly")) {
09443                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);  
09444             } else if (ast_true(v->value)) {
09445                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09446             } else 
09447                ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09448          } else if (!strcasecmp(v->name, "codecpriority")) {
09449             if(!strcasecmp(v->value, "caller"))
09450                ast_set_flag(user, IAX_CODEC_USER_FIRST);
09451             else if(!strcasecmp(v->value, "disabled"))
09452                ast_set_flag(user, IAX_CODEC_NOPREFS);
09453             else if(!strcasecmp(v->value, "reqonly")) {
09454                ast_set_flag(user, IAX_CODEC_NOCAP);
09455                ast_set_flag(user, IAX_CODEC_NOPREFS);
09456             }
09457          } else if (!strcasecmp(v->name, "jitterbuffer")) {
09458             ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09459          } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09460             ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09461          } else if (!strcasecmp(v->name, "dbsecret")) {
09462             ast_string_field_set(user, dbsecret, v->value);
09463          } else if (!strcasecmp(v->name, "secret")) {
09464             if (!ast_strlen_zero(user->secret)) {
09465                char *old = ast_strdupa(user->secret);
09466 
09467                ast_string_field_build(user, secret, "%s;%s", old, v->value);
09468             } else
09469                ast_string_field_set(user, secret, v->value);
09470          } else if (!strcasecmp(v->name, "callerid")) {
09471             if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09472                char name2[80];
09473                char num2[80];
09474                ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09475                ast_string_field_set(user, cid_name, name2);
09476                ast_string_field_set(user, cid_num, num2);
09477                ast_set_flag(user, IAX_HASCALLERID);
09478             } else {
09479                ast_clear_flag(user, IAX_HASCALLERID);
09480                ast_string_field_set(user, cid_name, "");
09481                ast_string_field_set(user, cid_num, "");
09482             }
09483          } else if (!strcasecmp(v->name, "fullname")) {
09484             if (!ast_strlen_zero(v->value)) {
09485                ast_string_field_set(user, cid_name, v->value);
09486                ast_set_flag(user, IAX_HASCALLERID);
09487             } else {
09488                ast_string_field_set(user, cid_name, "");
09489                if (ast_strlen_zero(user->cid_num))
09490                   ast_clear_flag(user, IAX_HASCALLERID);
09491             }
09492          } else if (!strcasecmp(v->name, "cid_number")) {
09493             if (!ast_strlen_zero(v->value)) {
09494                ast_string_field_set(user, cid_num, v->value);
09495                ast_set_flag(user, IAX_HASCALLERID);
09496             } else {
09497                ast_string_field_set(user, cid_num, "");
09498                if (ast_strlen_zero(user->cid_name))
09499                   ast_clear_flag(user, IAX_HASCALLERID);
09500             }
09501          } else if (!strcasecmp(v->name, "accountcode")) {
09502             ast_string_field_set(user, accountcode, v->value);
09503          } else if (!strcasecmp(v->name, "mohinterpret")) {
09504             ast_string_field_set(user, mohinterpret, v->value);
09505          } else if (!strcasecmp(v->name, "mohsuggest")) {
09506             ast_string_field_set(user, mohsuggest, v->value);
09507          } else if (!strcasecmp(v->name, "language")) {
09508             ast_string_field_set(user, language, v->value);
09509          } else if (!strcasecmp(v->name, "amaflags")) {
09510             format = ast_cdr_amaflags2int(v->value);
09511             if (format < 0) {
09512                ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09513             } else {
09514                user->amaflags = format;
09515             }
09516          } else if (!strcasecmp(v->name, "inkeys")) {
09517             ast_string_field_set(user, inkeys, v->value);
09518          } else if (!strcasecmp(v->name, "maxauthreq")) {
09519             user->maxauthreq = atoi(v->value);
09520             if (user->maxauthreq < 0)
09521                user->maxauthreq = 0;
09522          } else if (!strcasecmp(v->name, "adsi")) {
09523             user->adsi = ast_true(v->value);
09524          }/* else if (strcasecmp(v->name,"type")) */
09525          /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09526          v = v->next;
09527          if (!v) {
09528             v = alt;
09529             alt = NULL;
09530          }
09531       }
09532       if (!user->authmethods) {
09533          if (!ast_strlen_zero(user->secret)) {
09534             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09535             if (!ast_strlen_zero(user->inkeys))
09536                user->authmethods |= IAX_AUTH_RSA;
09537          } else if (!ast_strlen_zero(user->inkeys)) {
09538             user->authmethods = IAX_AUTH_RSA;
09539          } else {
09540             user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09541          }
09542       }
09543       ast_clear_flag(user, IAX_DELME);
09544    }
09545 cleanup:
09546    if (oldha)
09547       ast_free_ha(oldha);
09548    if (oldcon)
09549       free_context(oldcon);
09550    return user;
09551 }
09552 
09553 static int peer_delme_cb(void *obj, void *arg, int flags)
09554 {
09555    struct iax2_peer *peer = obj;
09556 
09557    ast_set_flag(peer, IAX_DELME);
09558 
09559    return 0;
09560 }
09561 
09562 static int user_delme_cb(void *obj, void *arg, int flags)
09563 {
09564    struct iax2_user *user = obj;
09565 
09566    ast_set_flag(user, IAX_DELME);
09567 
09568    return 0;
09569 }
09570 
09571 static void delete_users(void)
09572 {
09573    struct iax2_registry *reg;
09574 
09575    ao2_callback(users, 0, user_delme_cb, NULL);
09576 
09577    AST_LIST_LOCK(&registrations);
09578    while ((reg = AST_LIST_REMOVE_HEAD(&registrations, entry))) {
09579       ast_sched_del(sched, reg->expire);
09580       if (reg->callno) {
09581          ast_mutex_lock(&iaxsl[reg->callno]);
09582          if (iaxs[reg->callno]) {
09583             iaxs[reg->callno]->reg = NULL;
09584             iax2_destroy(reg->callno);
09585          }
09586          ast_mutex_unlock(&iaxsl[reg->callno]);
09587       }
09588       if (reg->dnsmgr)
09589          ast_dnsmgr_release(reg->dnsmgr);
09590       free(reg);
09591    }
09592    AST_LIST_UNLOCK(&registrations);
09593 
09594    ao2_callback(peers, 0, peer_delme_cb, NULL);
09595 }
09596 
09597 static void prune_users(void)
09598 {
09599    struct iax2_user *user;
09600    struct ao2_iterator i;
09601 
09602    i = ao2_iterator_init(users, 0);
09603    while ((user = ao2_iterator_next(&i))) {
09604       if (ast_test_flag(user, IAX_DELME))
09605          ao2_unlink(users, user);
09606       user_unref(user);
09607    }
09608 }
09609 
09610 /* Prune peers who still are supposed to be deleted */
09611 static void prune_peers(void)
09612 {
09613    struct iax2_peer *peer;
09614    struct ao2_iterator i;
09615 
09616    i = ao2_iterator_init(peers, 0);
09617    while ((peer = ao2_iterator_next(&i))) {
09618       if (ast_test_flag(peer, IAX_DELME))
09619          unlink_peer(peer);
09620       peer_unref(peer);
09621    }
09622 }
09623 
09624 static void set_timing(void)
09625 {
09626 #ifdef HAVE_ZAPTEL
09627    int bs = trunkfreq * 8;
09628    if (timingfd > -1) {
09629       if (
09630 #ifdef ZT_TIMERACK
09631          ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09632 #endif         
09633          ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09634          ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09635    }
09636 #endif
09637 }
09638 
09639 static void set_config_destroy(void)
09640 {
09641    strcpy(accountcode, "");
09642    strcpy(language, "");
09643    strcpy(mohinterpret, "default");
09644    strcpy(mohsuggest, "");
09645    amaflags = 0;
09646    delayreject = 0;
09647    ast_clear_flag((&globalflags), IAX_NOTRANSFER); 
09648    ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09649    ast_clear_flag((&globalflags), IAX_USEJITTERBUF);  
09650    ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);   
09651    delete_users();
09652 }
09653 
09654 /*! \brief Load configuration */
09655 static int set_config(char *config_file, int reload)
09656 {
09657    struct ast_config *cfg, *ucfg;
09658    int capability=iax2_capability;
09659    struct ast_variable *v;
09660    char *cat;
09661    const char *utype;
09662    const char *tosval;
09663    int format;
09664    int portno = IAX_DEFAULT_PORTNO;
09665    int  x;
09666    struct iax2_user *user;
09667    struct iax2_peer *peer;
09668    struct ast_netsock *ns;
09669 #if 0
09670    static unsigned short int last_port=0;
09671 #endif
09672 
09673    cfg = ast_config_load(config_file);
09674    
09675    if (!cfg) {
09676       ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09677       return -1;
09678    }
09679 
09680    if (reload) {
09681       set_config_destroy();
09682    }
09683 
09684    /* Reset global codec prefs */   
09685    memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09686    
09687    /* Reset Global Flags */
09688    memset(&globalflags, 0, sizeof(globalflags));
09689    ast_set_flag(&globalflags, IAX_RTUPDATE);
09690 
09691 #ifdef SO_NO_CHECK
09692    nochecksums = 0;
09693 #endif
09694 
09695    min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09696    max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09697 
09698    maxauthreq = 3;
09699 
09700    v = ast_variable_browse(cfg, "general");
09701 
09702    /* Seed initial tos value */
09703    tosval = ast_variable_retrieve(cfg, "general", "tos");
09704    if (tosval) {
09705       if (ast_str2tos(tosval, &tos))
09706          ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09707    }
09708    while(v) {
09709       if (!strcasecmp(v->name, "bindport")){ 
09710          if (reload)
09711             ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09712          else
09713             portno = atoi(v->value);
09714       } else if (!strcasecmp(v->name, "pingtime")) 
09715          ping_time = atoi(v->value);
09716       else if (!strcasecmp(v->name, "iaxthreadcount")) {
09717          if (reload) {
09718             if (atoi(v->value) != iaxthreadcount)
09719                ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09720          } else {
09721             iaxthreadcount = atoi(v->value);
09722             if (iaxthreadcount < 1) {
09723                ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09724                iaxthreadcount = 1;
09725             } else if (iaxthreadcount > 256) {
09726                ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09727                iaxthreadcount = 256;
09728             }
09729          }
09730       } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09731          if (reload) {
09732             AST_LIST_LOCK(&dynamic_list);
09733             iaxmaxthreadcount = atoi(v->value);
09734             AST_LIST_UNLOCK(&dynamic_list);
09735          } else {
09736             iaxmaxthreadcount = atoi(v->value);
09737             if (iaxmaxthreadcount < 0) {
09738                ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09739                iaxmaxthreadcount = 0;
09740             } else if (iaxmaxthreadcount > 256) {
09741                ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09742                iaxmaxthreadcount = 256;
09743             }
09744          }
09745       } else if (!strcasecmp(v->name, "nochecksums")) {
09746 #ifdef SO_NO_CHECK
09747          if (ast_true(v->value))
09748             nochecksums = 1;
09749          else
09750             nochecksums = 0;
09751 #else
09752          if (ast_true(v->value))
09753             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09754 #endif
09755       }
09756       else if (!strcasecmp(v->name, "maxjitterbuffer")) 
09757          maxjitterbuffer = atoi(v->value);
09758       else if (!strcasecmp(v->name, "resyncthreshold")) 
09759          resyncthreshold = atoi(v->value);
09760       else if (!strcasecmp(v->name, "maxjitterinterps")) 
09761          maxjitterinterps = atoi(v->value);
09762       else if (!strcasecmp(v->name, "lagrqtime")) 
09763          lagrq_time = atoi(v->value);
09764       else if (!strcasecmp(v->name, "maxregexpire")) 
09765          max_reg_expire = atoi(v->value);
09766       else if (!strcasecmp(v->name, "minregexpire")) 
09767          min_reg_expire = atoi(v->value);
09768       else if (!strcasecmp(v->name, "bindaddr")) {
09769          if (reload) {
09770             ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09771          } else {
09772             if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09773                ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09774             } else {
09775                if (option_verbose > 1) {
09776                   if (strchr(v->value, ':'))
09777                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09778                   else
09779                      ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09780                }
09781                if (defaultsockfd < 0) 
09782                   defaultsockfd = ast_netsock_sockfd(ns);
09783                ast_netsock_unref(ns);
09784             }
09785          }
09786       } else if (!strcasecmp(v->name, "authdebug"))
09787          authdebug = ast_true(v->value);
09788       else if (!strcasecmp(v->name, "encryption"))
09789          iax2_encryption = get_encrypt_methods(v->value);
09790       else if (!strcasecmp(v->name, "notransfer")) {
09791          ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09792          ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 
09793          ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);   
09794       } else if (!strcasecmp(v->name, "transfer")) {
09795          if (!strcasecmp(v->value, "mediaonly")) {
09796             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 
09797          } else if (ast_true(v->value)) {
09798             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09799          } else 
09800             ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09801       } else if (!strcasecmp(v->name, "codecpriority")) {
09802          if(!strcasecmp(v->value, "caller"))
09803             ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09804          else if(!strcasecmp(v->value, "disabled"))
09805             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09806          else if(!strcasecmp(v->value, "reqonly")) {
09807             ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
09808             ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09809          }
09810       } else if (!strcasecmp(v->name, "jitterbuffer"))
09811          ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 
09812       else if (!strcasecmp(v->name, "forcejitterbuffer"))
09813          ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);  
09814       else if (!strcasecmp(v->name, "delayreject"))
09815          delayreject = ast_true(v->value);
09816       else if (!strcasecmp(v->name, "rtcachefriends"))
09817          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);  
09818       else if (!strcasecmp(v->name, "rtignoreregexpire"))
09819          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);  
09820       else if (!strcasecmp(v->name, "rtupdate"))
09821          ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
09822       else if (!strcasecmp(v->name, "trunktimestamps"))
09823          ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
09824       else if (!strcasecmp(v->name, "rtautoclear")) {
09825          int i = atoi(v->value);
09826          if(i > 0)
09827             global_rtautoclear = i;
09828          else
09829             i = 0;
09830          ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);   
09831       } else if (!strcasecmp(v->name, "trunkfreq")) {
09832          trunkfreq = atoi(v->value);
09833          if (trunkfreq < 10)
09834             trunkfreq = 10;
09835       } else if (!strcasecmp(v->name, "autokill")) {
09836          if (sscanf(v->value, "%d", &x) == 1) {
09837             if (x >= 0)
09838                autokill = x;
09839             else
09840                ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
09841          } else if (ast_true(v->value)) {
09842             autokill = DEFAULT_MAXMS;
09843          } else {
09844             autokill = 0;
09845          }
09846       } else if (!strcasecmp(v->name, "bandwidth")) {
09847          if (!strcasecmp(v->value, "low")) {
09848             capability = IAX_CAPABILITY_LOWBANDWIDTH;
09849          } else if (!strcasecmp(v->value, "medium")) {
09850             capability = IAX_CAPABILITY_MEDBANDWIDTH;
09851          } else if (!strcasecmp(v->value, "high")) {
09852             capability = IAX_CAPABILITY_FULLBANDWIDTH;
09853          } else
09854             ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
09855       } else if (!strcasecmp(v->name, "allow")) {
09856          ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
09857       } else if (!strcasecmp(v->name, "disallow")) {
09858          ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
09859       } else if (!strcasecmp(v->name, "register")) {
09860          iax2_register(v->value, v->lineno);
09861       } else if (!strcasecmp(v->name, "iaxcompat")) {
09862          iaxcompat = ast_true(v->value);
09863       } else if (!strcasecmp(v->name, "regcontext")) {
09864          ast_copy_string(regcontext, v->value, sizeof(regcontext));
09865          /* Create context if it doesn't exist already */
09866          if (!ast_context_find(regcontext))
09867             ast_context_create(NULL, regcontext, "IAX2");
09868       } else if (!strcasecmp(v->name, "tos")) {
09869          if (ast_str2tos(v->value, &tos))
09870             ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
09871       } else if (!strcasecmp(v->name, "accountcode")) {
09872          ast_copy_string(accountcode, v->value, sizeof(accountcode));
09873       } else if (!strcasecmp(v->name, "mohinterpret")) {
09874          ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
09875       } else if (!strcasecmp(v->name, "mohsuggest")) {
09876          ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
09877       } else if (!strcasecmp(v->name, "amaflags")) {
09878          format = ast_cdr_amaflags2int(v->value);
09879          if (format < 0) {
09880             ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09881          } else {
09882             amaflags = format;
09883          }
09884       } else if (!strcasecmp(v->name, "language")) {
09885          ast_copy_string(language, v->value, sizeof(language));
09886       } else if (!strcasecmp(v->name, "maxauthreq")) {
09887          maxauthreq = atoi(v->value);
09888          if (maxauthreq < 0)
09889             maxauthreq = 0;
09890       } else if (!strcasecmp(v->name, "adsi")) {
09891          adsi = ast_true(v->value);
09892       } /*else if (strcasecmp(v->name,"type")) */
09893       /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */
09894       v = v->next;
09895    }
09896    
09897    if (defaultsockfd < 0) {
09898       if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
09899          ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09900       } else {
09901          if (option_verbose > 1)
09902             ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
09903          defaultsockfd = ast_netsock_sockfd(ns);
09904          ast_netsock_unref(ns);
09905       }
09906    }
09907    if (reload) {
09908       ast_netsock_release(outsock);
09909       outsock = ast_netsock_list_alloc();
09910       if (!outsock) {
09911          ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
09912          return -1;
09913       }
09914       ast_netsock_init(outsock);
09915    }
09916 
09917    if (min_reg_expire > max_reg_expire) {
09918       ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
09919          min_reg_expire, max_reg_expire, max_reg_expire);
09920       min_reg_expire = max_reg_expire;
09921    }
09922    iax2_capability = capability;
09923    
09924    ucfg = ast_config_load("users.conf");
09925    if (ucfg) {
09926       struct ast_variable *gen;
09927       int genhasiax;
09928       int genregisteriax;
09929       const char *hasiax, *registeriax;
09930       
09931       genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
09932       genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
09933       gen = ast_variable_browse(ucfg, "general");
09934       cat = ast_category_browse(ucfg, NULL);
09935       while (cat) {
09936          if (strcasecmp(cat, "general")) {
09937             hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
09938             registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
09939             if (ast_true(hasiax) || (!hasiax && genhasiax)) {
09940                /* Start with general parameters, then specific parameters, user and peer */
09941                user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
09942                if (user) {
09943                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09944                   user = user_unref(user);
09945                }
09946                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
09947                if (peer) {
09948                   if (ast_test_flag(peer, IAX_DYNAMIC))
09949                      reg_source_db(peer);
09950                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09951                   peer = peer_unref(peer);
09952                }
09953             }
09954             if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
09955                char tmp[256];
09956                const char *host = ast_variable_retrieve(ucfg, cat, "host");
09957                const char *username = ast_variable_retrieve(ucfg, cat, "username");
09958                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
09959                if (!host)
09960                   host = ast_variable_retrieve(ucfg, "general", "host");
09961                if (!username)
09962                   username = ast_variable_retrieve(ucfg, "general", "username");
09963                if (!secret)
09964                   secret = ast_variable_retrieve(ucfg, "general", "secret");
09965                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
09966                   if (!ast_strlen_zero(secret))
09967                      snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
09968                   else
09969                      snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
09970                   iax2_register(tmp, 0);
09971                }
09972             }
09973          }
09974          cat = ast_category_browse(ucfg, cat);
09975       }
09976       ast_config_destroy(ucfg);
09977    }
09978    
09979    cat = ast_category_browse(cfg, NULL);
09980    while(cat) {
09981       if (strcasecmp(cat, "general")) {
09982          utype = ast_variable_retrieve(cfg, cat, "type");
09983          if (utype) {
09984             if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
09985                user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
09986                if (user) {
09987                   __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09988                   user = user_unref(user);
09989                }
09990             }
09991             if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
09992                peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
09993                if (peer) {
09994                   if (ast_test_flag(peer, IAX_DYNAMIC))
09995                      reg_source_db(peer);
09996                   __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
09997                   peer = peer_unref(peer);
09998                }
09999             } else if (strcasecmp(utype, "user")) {
10000                ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10001             }
10002          } else
10003             ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10004       }
10005       cat = ast_category_browse(cfg, cat);
10006    }
10007    ast_config_destroy(cfg);
10008    set_timing();
10009    return 1;
10010 }
10011 
10012 static void poke_all_peers(void)
10013 {
10014    struct ao2_iterator i;
10015    struct iax2_peer *peer;
10016 
10017    i = ao2_iterator_init(peers, 0);
10018    while ((peer = ao2_iterator_next(&i))) {
10019       iax2_poke_peer(peer, 0);
10020       peer_unref(peer);
10021    }
10022 }
10023 static int reload_config(void)
10024 {
10025    char *config = "iax.conf";
10026    struct iax2_registry *reg;
10027 
10028    if (set_config(config, 1) > 0) {
10029       prune_peers();
10030       prune_users();
10031       AST_LIST_LOCK(&registrations);
10032       AST_LIST_TRAVERSE(&registrations, reg, entry)
10033          iax2_do_register(reg);
10034       AST_LIST_UNLOCK(&registrations);
10035       /* Qualify hosts, too */
10036       poke_all_peers();
10037    }
10038    reload_firmware(0);
10039    iax_provision_reload();
10040 
10041    return 0;
10042 }
10043 
10044 static int iax2_reload(int fd, int argc, char *argv[])
10045 {
10046    return reload_config();
10047 }
10048 
10049 static int reload(void)
10050 {
10051    return reload_config();
10052 }
10053 
10054 static int cache_get_callno_locked(const char *data)
10055 {
10056    struct sockaddr_in sin;
10057    int x;
10058    int callno;
10059    struct iax_ie_data ied;
10060    struct create_addr_info cai;
10061    struct parsed_dial_string pds;
10062    char *tmpstr;
10063 
10064    for (x=0; x<IAX_MAX_CALLS; x++) {
10065       /* Look for an *exact match* call.  Once a call is negotiated, it can only
10066          look up entries for a single context */
10067       if (!ast_mutex_trylock(&iaxsl[x])) {
10068          if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10069             return x;
10070          ast_mutex_unlock(&iaxsl[x]);
10071       }
10072    }
10073 
10074    /* No match found, we need to create a new one */
10075 
10076    memset(&cai, 0, sizeof(cai));
10077    memset(&ied, 0, sizeof(ied));
10078    memset(&pds, 0, sizeof(pds));
10079 
10080    tmpstr = ast_strdupa(data);
10081    parse_dial_string(tmpstr, &pds);
10082 
10083    if (ast_strlen_zero(pds.peer)) {
10084       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10085       return -1;
10086    }
10087 
10088    /* Populate our address from the given */
10089    if (create_addr(pds.peer, NULL, &sin, &cai))
10090       return -1;
10091 
10092    if (option_debug)
10093       ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10094          pds.peer, pds.username, pds.password, pds.context);
10095 
10096    callno = find_callno(0, 0, &sin, NEW_FORCE, cai.sockfd);
10097    if (callno < 1) {
10098       ast_log(LOG_WARNING, "Unable to create call\n");
10099       return -1;
10100    }
10101 
10102    ast_mutex_lock(&iaxsl[callno]);
10103    ast_string_field_set(iaxs[callno], dproot, data);
10104    iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10105 
10106    iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10107    iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10108    /* the string format is slightly different from a standard dial string,
10109       because the context appears in the 'exten' position
10110    */
10111    if (pds.exten)
10112       iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10113    if (pds.username)
10114       iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10115    iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10116    iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10117    /* Keep password handy */
10118    if (pds.password)
10119       ast_string_field_set(iaxs[callno], secret, pds.password);
10120    if (pds.key)
10121       ast_string_field_set(iaxs[callno], outkey, pds.key);
10122    /* Start the call going */
10123    send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10124 
10125    return callno;
10126 }
10127 
10128 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10129 {
10130    struct iax2_dpcache *dp, *prev = NULL, *next;
10131    struct timeval tv;
10132    int x;
10133    int com[2];
10134    int timeout;
10135    int old=0;
10136    int outfd;
10137    int abort;
10138    int callno;
10139    struct ast_channel *c;
10140    struct ast_frame *f;
10141    gettimeofday(&tv, NULL);
10142    dp = dpcache;
10143    while(dp) {
10144       next = dp->next;
10145       /* Expire old caches */
10146       if (ast_tvcmp(tv, dp->expiry) > 0) {
10147             /* It's expired, let it disappear */
10148             if (prev)
10149                prev->next = dp->next;
10150             else
10151                dpcache = dp->next;
10152             if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10153                /* Free memory and go again */
10154                free(dp);
10155             } else {
10156                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);
10157             }
10158             dp = next;
10159             continue;
10160       }
10161       /* We found an entry that matches us! */
10162       if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 
10163          break;
10164       prev = dp;
10165       dp = next;
10166    }
10167    if (!dp) {
10168       /* No matching entry.  Create a new one. */
10169       /* First, can we make a callno? */
10170       callno = cache_get_callno_locked(data);
10171       if (callno < 0) {
10172          ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10173          return NULL;
10174       }
10175       if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10176          ast_mutex_unlock(&iaxsl[callno]);
10177          return NULL;
10178       }
10179       ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10180       ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10181       gettimeofday(&dp->expiry, NULL);
10182       dp->orig = dp->expiry;
10183       /* Expires in 30 mins by default */
10184       dp->expiry.tv_sec += iaxdefaultdpcache;
10185       dp->next = dpcache;
10186       dp->flags = CACHE_FLAG_PENDING;
10187       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10188          dp->waiters[x] = -1;
10189       dpcache = dp;
10190       dp->peer = iaxs[callno]->dpentries;
10191       iaxs[callno]->dpentries = dp;
10192       /* Send the request if we're already up */
10193       if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10194          iax2_dprequest(dp, callno);
10195       ast_mutex_unlock(&iaxsl[callno]);
10196    }
10197    /* By here we must have a dp */
10198    if (dp->flags & CACHE_FLAG_PENDING) {
10199       /* Okay, here it starts to get nasty.  We need a pipe now to wait
10200          for a reply to come back so long as it's pending */
10201       for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10202          /* Find an empty slot */
10203          if (dp->waiters[x] < 0)
10204             break;
10205       }
10206       if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10207          ast_log(LOG_WARNING, "No more waiter positions available\n");
10208          return NULL;
10209       }
10210       if (pipe(com)) {
10211          ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10212          return NULL;
10213       }
10214       dp->waiters[x] = com[1];
10215       /* Okay, now we wait */
10216       timeout = iaxdefaulttimeout * 1000;
10217       /* Temporarily unlock */
10218       ast_mutex_unlock(&dpcache_lock);
10219       /* Defer any dtmf */
10220       if (chan)
10221          old = ast_channel_defer_dtmf(chan);
10222       abort = 0;
10223       while(timeout) {
10224          c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10225          if (outfd > -1) {
10226             break;
10227          }
10228          if (c) {
10229             f = ast_read(c);
10230             if (f)
10231                ast_frfree(f);
10232             else {
10233                /* Got hung up on, abort! */
10234                break;
10235                abort = 1;
10236             }
10237          }
10238       }
10239       if (!timeout) {
10240          ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10241       }
10242       ast_mutex_lock(&dpcache_lock);
10243       dp->waiters[x] = -1;
10244       close(com[1]);
10245       close(com[0]);
10246       if (abort) {
10247          /* Don't interpret anything, just abort.  Not sure what th epoint
10248            of undeferring dtmf on a hung up channel is but hey whatever */
10249          if (!old && chan)
10250             ast_channel_undefer_dtmf(chan);
10251          return NULL;
10252       }
10253       if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10254          /* Now to do non-independent analysis the results of our wait */
10255          if (dp->flags & CACHE_FLAG_PENDING) {
10256             /* Still pending... It's a timeout.  Wake everybody up.  Consider it no longer
10257                pending.  Don't let it take as long to timeout. */
10258             dp->flags &= ~CACHE_FLAG_PENDING;
10259             dp->flags |= CACHE_FLAG_TIMEOUT;
10260             /* Expire after only 60 seconds now.  This is designed to help reduce backlog in heavily loaded
10261                systems without leaving it unavailable once the server comes back online */
10262             dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10263             for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10264                if (dp->waiters[x] > -1)
10265                   write(dp->waiters[x], "asdf", 4);
10266          }
10267       }
10268       /* Our caller will obtain the rest */
10269       if (!old && chan)
10270          ast_channel_undefer_dtmf(chan);
10271    }
10272    return dp;  
10273 }
10274 
10275 /*! \brief Part of the IAX2 switch interface */
10276 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10277 {
10278    struct iax2_dpcache *dp;
10279    int res = 0;
10280 #if 0
10281    ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10282 #endif
10283    if ((priority != 1) && (priority != 2))
10284       return 0;
10285    ast_mutex_lock(&dpcache_lock);
10286    dp = find_cache(chan, data, context, exten, priority);
10287    if (dp) {
10288       if (dp->flags & CACHE_FLAG_EXISTS)
10289          res= 1;
10290    }
10291    ast_mutex_unlock(&dpcache_lock);
10292    if (!dp) {
10293       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10294    }
10295    return res;
10296 }
10297 
10298 /*! \brief part of the IAX2 dial plan switch interface */
10299 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10300 {
10301    int res = 0;
10302    struct iax2_dpcache *dp;
10303 #if 0
10304    ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10305 #endif
10306    if ((priority != 1) && (priority != 2))
10307       return 0;
10308    ast_mutex_lock(&dpcache_lock);
10309    dp = find_cache(chan, data, context, exten, priority);
10310    if (dp) {
10311       if (dp->flags & CACHE_FLAG_CANEXIST)
10312          res= 1;
10313    }
10314    ast_mutex_unlock(&dpcache_lock);
10315    if (!dp) {
10316       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10317    }
10318    return res;
10319 }
10320 
10321 /*! \brief Part of the IAX2 Switch interface */
10322 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10323 {
10324    int res = 0;
10325    struct iax2_dpcache *dp;
10326 #if 0
10327    ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10328 #endif
10329    if ((priority != 1) && (priority != 2))
10330       return 0;
10331    ast_mutex_lock(&dpcache_lock);
10332    dp = find_cache(chan, data, context, exten, priority);
10333    if (dp) {
10334       if (dp->flags & CACHE_FLAG_MATCHMORE)
10335          res= 1;
10336    }
10337    ast_mutex_unlock(&dpcache_lock);
10338    if (!dp) {
10339       ast_log(LOG_WARNING, "Unable to make DP cache\n");
10340    }
10341    return res;
10342 }
10343 
10344 /*! \brief Execute IAX2 dialplan switch */
10345 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10346 {
10347    char odata[256];
10348    char req[256];
10349    char *ncontext;
10350    struct iax2_dpcache *dp;
10351    struct ast_app *dial;
10352 #if 0
10353    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);
10354 #endif
10355    if (priority == 2) {
10356       /* Indicate status, can be overridden in dialplan */
10357       const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10358       if (dialstatus) {
10359          dial = pbx_findapp(dialstatus);
10360          if (dial) 
10361             pbx_exec(chan, dial, "");
10362       }
10363       return -1;
10364    } else if (priority != 1)
10365       return -1;
10366    ast_mutex_lock(&dpcache_lock);
10367    dp = find_cache(chan, data, context, exten, priority);
10368    if (dp) {
10369       if (dp->flags & CACHE_FLAG_EXISTS) {
10370          ast_copy_string(odata, data, sizeof(odata));
10371          ncontext = strchr(odata, '/');
10372          if (ncontext) {
10373             *ncontext = '\0';
10374             ncontext++;
10375             snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10376          } else {
10377             snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10378          }
10379          if (option_verbose > 2)
10380             ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10381       } else {
10382          ast_mutex_unlock(&dpcache_lock);
10383          ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10384          return -1;
10385       }
10386    }
10387    ast_mutex_unlock(&dpcache_lock);
10388    dial = pbx_findapp("Dial");
10389    if (dial) {
10390       return pbx_exec(chan, dial, req);
10391    } else {
10392       ast_log(LOG_WARNING, "No dial application registered\n");
10393    }
10394    return -1;
10395 }
10396 
10397 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10398 {
10399    struct iax2_peer *peer;
10400    char *peername, *colname;
10401 
10402    peername = ast_strdupa(data);
10403 
10404    /* if our channel, return the IP address of the endpoint of current channel */
10405    if (!strcmp(peername,"CURRENTCHANNEL")) {
10406            unsigned short callno;
10407       if (chan->tech != &iax2_tech)
10408          return -1;
10409       callno = PTR_TO_CALLNO(chan->tech_pvt);   
10410       ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10411       return 0;
10412    }
10413 
10414    if ((colname = strchr(peername, ':'))) /*! \todo : will be removed after the 1.4 relese */
10415       *colname++ = '\0';
10416    else if ((colname = strchr(peername, '|')))
10417       *colname++ = '\0';
10418    else
10419       colname = "ip";
10420 
10421    if (!(peer = find_peer(peername, 1)))
10422       return -1;
10423 
10424    if (!strcasecmp(colname, "ip")) {
10425       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10426    } else  if (!strcasecmp(colname, "status")) {
10427       peer_status(peer, buf, len); 
10428    } else  if (!strcasecmp(colname, "mailbox")) {
10429       ast_copy_string(buf, peer->mailbox, len);
10430    } else  if (!strcasecmp(colname, "context")) {
10431       ast_copy_string(buf, peer->context, len);
10432    } else  if (!strcasecmp(colname, "expire")) {
10433       snprintf(buf, len, "%d", peer->expire);
10434    } else  if (!strcasecmp(colname, "dynamic")) {
10435       ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10436    } else  if (!strcasecmp(colname, "callerid_name")) {
10437       ast_copy_string(buf, peer->cid_name, len);
10438    } else  if (!strcasecmp(colname, "callerid_num")) {
10439       ast_copy_string(buf, peer->cid_num, len);
10440    } else  if (!strcasecmp(colname, "codecs")) {
10441       ast_getformatname_multiple(buf, len -1, peer->capability);
10442    } else  if (!strncasecmp(colname, "codec[", 6)) {
10443       char *codecnum, *ptr;
10444       int index = 0, codec = 0;
10445       
10446       codecnum = strchr(colname, '[');
10447       *codecnum = '\0';
10448       codecnum++;
10449       if ((ptr = strchr(codecnum, ']'))) {
10450          *ptr = '\0';
10451       }
10452       index = atoi(codecnum);
10453       if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10454          ast_copy_string(buf, ast_getformatname(codec), len);
10455       }
10456    }
10457 
10458    peer_unref(peer);
10459 
10460    return 0;
10461 }
10462 
10463 struct ast_custom_function iaxpeer_function = {
10464    .name = "IAXPEER",
10465    .synopsis = "Gets IAX peer information",
10466    .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10467    .read = function_iaxpeer,
10468    .desc = "If peername specified, valid items are:\n"
10469    "- ip (default)          The IP address.\n"
10470    "- status                The peer's status (if qualify=yes)\n"
10471    "- mailbox               The configured mailbox.\n"
10472    "- context               The configured context.\n"
10473    "- expire                The epoch time of the next expire.\n"
10474    "- dynamic               Is it dynamic? (yes/no).\n"
10475    "- callerid_name         The configured Caller ID name.\n"
10476    "- callerid_num          The configured Caller ID number.\n"
10477    "- codecs                The configured codecs.\n"
10478    "- codec[x]              Preferred codec index number 'x' (beginning with zero).\n"
10479    "\n"
10480    "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10481    "\n"
10482 };
10483 
10484 
10485 /*! \brief Part of the device state notification system ---*/
10486 static int iax2_devicestate(void *data) 
10487 {
10488    struct parsed_dial_string pds;
10489    char *tmp = ast_strdupa(data);
10490    struct iax2_peer *p;
10491    int res = AST_DEVICE_INVALID;
10492 
10493    memset(&pds, 0, sizeof(pds));
10494    parse_dial_string(tmp, &pds);
10495 
10496    if (ast_strlen_zero(pds.peer)) {
10497       ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10498       return res;
10499    }
10500    
10501    if (option_debug > 2)
10502       ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10503 
10504    /* SLD: FIXME: second call to find_peer during registration */
10505    if (!(p = find_peer(pds.peer, 1)))
10506       return res;
10507 
10508    res = AST_DEVICE_UNAVAILABLE;
10509    if (option_debug > 2) 
10510       ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10511          pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10512    
10513    if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10514        (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10515       /* Peer is registered, or have default IP address
10516          and a valid registration */
10517       if (p->historicms == 0 || p->historicms <= p->maxms)
10518          /* let the core figure out whether it is in use or not */
10519          res = AST_DEVICE_UNKNOWN;  
10520    }
10521 
10522    peer_unref(p);
10523 
10524    return res;
10525 }
10526 
10527 static struct ast_switch iax2_switch = 
10528 {
10529    name:          "IAX2",
10530    description:      "IAX Remote Dialplan Switch",
10531    exists:        iax2_exists,
10532    canmatch:      iax2_canmatch,
10533    exec:       iax2_exec,
10534    matchmore:     iax2_matchmore,
10535 };
10536 
10537 static char show_stats_usage[] =
10538 "Usage: iax2 show stats\n"
10539 "       Display statistics on IAX channel driver.\n";
10540 
10541 static char show_cache_usage[] =
10542 "Usage: iax2 show cache\n"
10543 "       Display currently cached IAX Dialplan results.\n";
10544 
10545 static char show_peer_usage[] =
10546 "Usage: iax2 show peer <name>\n"
10547 "       Display details on specific IAX peer\n";
10548 
10549 static char prune_realtime_usage[] =
10550 "Usage: iax2 prune realtime [<peername>|all]\n"
10551 "       Prunes object(s) from the cache\n";
10552 
10553 static char iax2_reload_usage[] =
10554 "Usage: iax2 reload\n"
10555 "       Reloads IAX configuration from iax.conf\n";
10556 
10557 static char show_prov_usage[] =
10558 "Usage: iax2 provision <host> <template> [forced]\n"
10559 "       Provisions the given peer or IP address using a template\n"
10560 "       matching either 'template' or '*' if the template is not\n"
10561 "       found.  If 'forced' is specified, even empty provisioning\n"
10562 "       fields will be provisioned as empty fields.\n";
10563 
10564 static char show_users_usage[] = 
10565 "Usage: iax2 show users [like <pattern>]\n"
10566 "       Lists all known IAX2 users.\n"
10567 "       Optional regular expression pattern is used to filter the user list.\n";
10568 
10569 static char show_channels_usage[] = 
10570 "Usage: iax2 show channels\n"
10571 "       Lists all currently active IAX channels.\n";
10572 
10573 static char show_netstats_usage[] = 
10574 "Usage: iax2 show netstats\n"
10575 "       Lists network status for all currently active IAX channels.\n";
10576 
10577 static char show_threads_usage[] = 
10578 "Usage: iax2 show threads\n"
10579 "       Lists status of IAX helper threads\n";
10580 
10581 static char show_peers_usage[] = 
10582 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10583 "       Lists all known IAX2 peers.\n"
10584 "       Optional 'registered' argument lists only peers with known addresses.\n"
10585 "       Optional regular expression pattern is used to filter the peer list.\n";
10586 
10587 static char show_firmware_usage[] = 
10588 "Usage: iax2 show firmware\n"
10589 "       Lists all known IAX firmware images.\n";
10590 
10591 static char show_reg_usage[] =
10592 "Usage: iax2 show registry\n"
10593 "       Lists all registration requests and status.\n";
10594 
10595 static char debug_usage[] = 
10596 "Usage: iax2 set debug\n"
10597 "       Enables dumping of IAX packets for debugging purposes\n";
10598 
10599 static char no_debug_usage[] = 
10600 "Usage: iax2 set debug off\n"
10601 "       Disables dumping of IAX packets for debugging purposes\n";
10602 
10603 static char debug_trunk_usage[] =
10604 "Usage: iax2 set debug trunk\n"
10605 "       Requests current status of IAX trunking\n";
10606 
10607 static char no_debug_trunk_usage[] =
10608 "Usage: iax2 set debug trunk off\n"
10609 "       Requests current status of IAX trunking\n";
10610 
10611 static char debug_jb_usage[] =
10612 "Usage: iax2 set debug jb\n"
10613 "       Enables jitterbuffer debugging information\n";
10614 
10615 static char no_debug_jb_usage[] =
10616 "Usage: iax2 set debug jb off\n"
10617 "       Disables jitterbuffer debugging information\n";
10618 
10619 static char iax2_test_losspct_usage[] =
10620 "Usage: iax2 test losspct <percentage>\n"
10621 "       For testing, throws away <percentage> percent of incoming packets\n";
10622 
10623 #ifdef IAXTESTS
10624 static char iax2_test_late_usage[] =
10625 "Usage: iax2 test late <ms>\n"
10626 "       For testing, count the next frame as <ms> ms late\n";
10627 
10628 static char iax2_test_resync_usage[] =
10629 "Usage: iax2 test resync <ms>\n"
10630 "       For testing, adjust all future frames by <ms> ms\n";
10631 
10632 static char iax2_test_jitter_usage[] =
10633 "Usage: iax2 test jitter <ms> <pct>\n"
10634 "       For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10635 #endif /* IAXTESTS */
10636 
10637 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10638    { "iax2", "trunk", "debug", NULL },
10639    iax2_do_trunk_debug, NULL,
10640    NULL };
10641 
10642 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10643    { "iax2", "jb", "debug", NULL },
10644    iax2_do_jb_debug, NULL,
10645    NULL };
10646 
10647 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10648    { "iax2", "no", "debug", NULL },
10649    iax2_no_debug, NULL,
10650    NULL };
10651 
10652 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10653    { "iax2", "no", "trunk", "debug", NULL },
10654    iax2_no_trunk_debug, NULL,
10655    NULL };
10656 
10657 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10658    { "iax2", "no", "jb", "debug", NULL },
10659    iax2_no_jb_debug, NULL,
10660    NULL };
10661 
10662 static struct ast_cli_entry cli_iax2[] = {
10663    { { "iax2", "show", "cache", NULL },
10664    iax2_show_cache, "Display IAX cached dialplan",
10665    show_cache_usage, NULL, },
10666 
10667    { { "iax2", "show", "channels", NULL },
10668    iax2_show_channels, "List active IAX channels",
10669    show_channels_usage, NULL, },
10670 
10671    { { "iax2", "show", "firmware", NULL },
10672    iax2_show_firmware, "List available IAX firmwares",
10673    show_firmware_usage, NULL, },
10674 
10675    { { "iax2", "show", "netstats", NULL },
10676    iax2_show_netstats, "List active IAX channel netstats",
10677    show_netstats_usage, NULL, },
10678 
10679    { { "iax2", "show", "peers", NULL },
10680    iax2_show_peers, "List defined IAX peers",
10681    show_peers_usage, NULL, },
10682 
10683    { { "iax2", "show", "registry", NULL },
10684    iax2_show_registry, "Display IAX registration status",
10685    show_reg_usage, NULL, },
10686 
10687    { { "iax2", "show", "stats", NULL },
10688    iax2_show_stats, "Display IAX statistics",
10689    show_stats_usage, NULL, },
10690 
10691    { { "iax2", "show", "threads", NULL },
10692    iax2_show_threads, "Display IAX helper thread info",
10693    show_threads_usage, NULL, },
10694 
10695    { { "iax2", "show", "users", NULL },
10696    iax2_show_users, "List defined IAX users",
10697    show_users_usage, NULL, },
10698 
10699    { { "iax2", "prune", "realtime", NULL },
10700    iax2_prune_realtime, "Prune a cached realtime lookup",
10701    prune_realtime_usage, complete_iax2_show_peer },
10702 
10703    { { "iax2", "reload", NULL },
10704    iax2_reload, "Reload IAX configuration",
10705    iax2_reload_usage },
10706 
10707    { { "iax2", "show", "peer", NULL },
10708    iax2_show_peer, "Show details on specific IAX peer",
10709    show_peer_usage, complete_iax2_show_peer },
10710 
10711    { { "iax2", "set", "debug", NULL },
10712    iax2_do_debug, "Enable IAX debugging",
10713    debug_usage },
10714 
10715    { { "iax2", "set", "debug", "trunk", NULL },
10716    iax2_do_trunk_debug, "Enable IAX trunk debugging",
10717    debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10718 
10719    { { "iax2", "set", "debug", "jb", NULL },
10720    iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10721    debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10722 
10723    { { "iax2", "set", "debug", "off", NULL },
10724    iax2_no_debug, "Disable IAX debugging",
10725    no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10726 
10727    { { "iax2", "set", "debug", "trunk", "off", NULL },
10728    iax2_no_trunk_debug, "Disable IAX trunk debugging",
10729    no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10730 
10731    { { "iax2", "set", "debug", "jb", "off", NULL },
10732    iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10733    no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10734 
10735    { { "iax2", "test", "losspct", NULL },
10736    iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10737    iax2_test_losspct_usage },
10738 
10739    { { "iax2", "provision", NULL },
10740    iax2_prov_cmd, "Provision an IAX device",
10741    show_prov_usage, iax2_prov_complete_template_3rd },
10742 
10743 #ifdef IAXTESTS
10744    { { "iax2", "test", "late", NULL },
10745    iax2_test_late, "Test the receipt of a late frame",
10746    iax2_test_late_usage },
10747 
10748    { { "iax2", "test", "resync", NULL },
10749    iax2_test_resync, "Test a resync in received timestamps",
10750    iax2_test_resync_usage },
10751 
10752    { { "iax2", "test", "jitter", NULL },
10753    iax2_test_jitter, "Simulates jitter for testing",
10754    iax2_test_jitter_usage },
10755 #endif /* IAXTESTS */
10756 };
10757 
10758 static int __unload_module(void)
10759 {
10760    struct iax2_thread *thread = NULL;
10761    int x;
10762 
10763    /* Make sure threads do not hold shared resources when they are canceled */
10764    
10765    /* Grab the sched lock resource to keep it away from threads about to die */
10766    /* Cancel the network thread, close the net socket */
10767    if (netthreadid != AST_PTHREADT_NULL) {
10768       AST_LIST_LOCK(&iaxq.queue);
10769       ast_mutex_lock(&sched_lock);
10770       pthread_cancel(netthreadid);
10771       ast_cond_signal(&sched_cond);
10772       ast_mutex_unlock(&sched_lock);   /* Release the schedule lock resource */
10773       AST_LIST_UNLOCK(&iaxq.queue);
10774       pthread_join(netthreadid, NULL);
10775    }
10776    if (schedthreadid != AST_PTHREADT_NULL) {
10777       ast_mutex_lock(&sched_lock);  
10778       pthread_cancel(schedthreadid);
10779       ast_cond_signal(&sched_cond);
10780       ast_mutex_unlock(&sched_lock);   
10781       pthread_join(schedthreadid, NULL);
10782    }
10783    
10784    /* Call for all threads to halt */
10785    AST_LIST_LOCK(&idle_list);
10786    AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10787       AST_LIST_REMOVE_CURRENT(&idle_list, list);
10788       pthread_cancel(thread->threadid);
10789    }
10790    AST_LIST_TRAVERSE_SAFE_END
10791    AST_LIST_UNLOCK(&idle_list);
10792 
10793    AST_LIST_LOCK(&active_list);
10794    AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10795       AST_LIST_REMOVE_CURRENT(&active_list, list);
10796       pthread_cancel(thread->threadid);
10797    }
10798    AST_LIST_TRAVERSE_SAFE_END
10799    AST_LIST_UNLOCK(&active_list);
10800 
10801    AST_LIST_LOCK(&dynamic_list);
10802         AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10803       AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10804       pthread_cancel(thread->threadid);
10805         }
10806    AST_LIST_TRAVERSE_SAFE_END
10807         AST_LIST_UNLOCK(&dynamic_list);
10808 
10809    AST_LIST_HEAD_DESTROY(&iaxq.queue);
10810 
10811    /* Wait for threads to exit */
10812    while(0 < iaxactivethreadcount)
10813       usleep(10000);
10814    
10815    ast_netsock_release(netsock);
10816    ast_netsock_release(outsock);
10817    for (x=0;x<IAX_MAX_CALLS;x++)
10818       if (iaxs[x])
10819          iax2_destroy(x);
10820    ast_manager_unregister( "IAXpeers" );
10821    ast_manager_unregister( "IAXnetstats" );
10822    ast_unregister_application(papp);
10823    ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10824    ast_unregister_switch(&iax2_switch);
10825    ast_channel_unregister(&iax2_tech);
10826    delete_users();
10827    iax_provision_unload();
10828    sched_context_destroy(sched);
10829    reload_firmware(1);
10830 
10831    ast_mutex_destroy(&waresl.lock);
10832 
10833    for (x = 0; x < IAX_MAX_CALLS; x++)
10834       ast_mutex_destroy(&iaxsl[x]);
10835 
10836    ao2_ref(peers, -1);
10837    ao2_ref(users, -1);
10838 
10839    return 0;
10840 }
10841 
10842 static int unload_module(void)
10843 {
10844    ast_custom_function_unregister(&iaxpeer_function);
10845    return __unload_module();
10846 }
10847 
10848 static int peer_set_sock_cb(void *obj, void *arg, int flags)
10849 {
10850    struct iax2_peer *peer = obj;
10851 
10852    if (peer->sockfd < 0)
10853       peer->sockfd = defaultsockfd;
10854 
10855    return 0;
10856 }
10857 
10858 /*! \brief Load IAX2 module, load configuraiton ---*/
10859 static int load_module(void)
10860 {
10861    char *config = "iax.conf";
10862    int res = 0;
10863    int x;
10864    struct iax2_registry *reg = NULL;
10865 
10866    peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
10867    if (!peers)
10868       return AST_MODULE_LOAD_FAILURE;
10869    users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
10870    if (!users) {
10871       ao2_ref(peers, -1);
10872       return AST_MODULE_LOAD_FAILURE;
10873    }
10874 
10875    ast_custom_function_register(&iaxpeer_function);
10876 
10877    iax_set_output(iax_debug_output);
10878    iax_set_error(iax_error_output);
10879    jb_setoutput(jb_error_output, jb_warning_output, NULL);
10880    
10881 #ifdef HAVE_ZAPTEL
10882 #ifdef ZT_TIMERACK
10883    timingfd = open("/dev/zap/timer", O_RDWR);
10884    if (timingfd < 0)
10885 #endif
10886       timingfd = open("/dev/zap/pseudo", O_RDWR);
10887    if (timingfd < 0) 
10888       ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10889 #endif      
10890 
10891    memset(iaxs, 0, sizeof(iaxs));
10892 
10893    for (x=0;x<IAX_MAX_CALLS;x++)
10894       ast_mutex_init(&iaxsl[x]);
10895    
10896    ast_cond_init(&sched_cond, NULL);
10897 
10898    io = io_context_create();
10899    sched = sched_context_create();
10900    
10901    if (!io || !sched) {
10902       ast_log(LOG_ERROR, "Out of memory\n");
10903       return -1;
10904    }
10905 
10906    netsock = ast_netsock_list_alloc();
10907    if (!netsock) {
10908       ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10909       return -1;
10910    }
10911    ast_netsock_init(netsock);
10912 
10913    outsock = ast_netsock_list_alloc();
10914    if (!outsock) {
10915       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10916       return -1;
10917    }
10918    ast_netsock_init(outsock);
10919 
10920    ast_mutex_init(&waresl.lock);
10921 
10922    AST_LIST_HEAD_INIT(&iaxq.queue);
10923    
10924    ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10925 
10926    ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10927    
10928    ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10929    ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10930 
10931    if(set_config(config, 0) == -1)
10932       return AST_MODULE_LOAD_DECLINE;
10933 
10934    if (ast_channel_register(&iax2_tech)) {
10935       ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10936       __unload_module();
10937       return -1;
10938    }
10939 
10940    if (ast_register_switch(&iax2_switch)) 
10941       ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10942 
10943    res = start_network_thread();
10944    if (!res) {
10945       if (option_verbose > 1) 
10946          ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10947    } else {
10948       ast_log(LOG_ERROR, "Unable to start network thread\n");
10949       ast_netsock_release(netsock);
10950       ast_netsock_release(outsock);
10951    }
10952 
10953    AST_LIST_LOCK(&registrations);
10954    AST_LIST_TRAVERSE(&registrations, reg, entry)
10955       iax2_do_register(reg);
10956    AST_LIST_UNLOCK(&registrations); 
10957 
10958    ao2_callback(peers, 0, peer_set_sock_cb, NULL);
10959    ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
10960 
10961    reload_firmware(0);
10962    iax_provision_reload();
10963    return res;
10964 }
10965 
10966 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10967       .load = load_module,
10968       .unload = unload_module,
10969       .reload = reload,
10970           );

Generated on Mon Mar 31 07:37:58 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1